diff options
author | wolfbeast <mcwerewolf@gmail.com> | 2018-07-18 08:24:24 +0200 |
---|---|---|
committer | wolfbeast <mcwerewolf@gmail.com> | 2018-07-18 08:24:24 +0200 |
commit | fc61780b35af913801d72086456f493f63197da6 (patch) | |
tree | f85891288a7bd988da9f0f15ae64e5c63f00d493 /security/nss | |
parent | 69f7f9e5f1475891ce11cc4f431692f965b0cd30 (diff) | |
parent | 50d3e596bbe89c95615f96eb71f6bc5be737a1db (diff) | |
download | UXP-2018.07.18.tar UXP-2018.07.18.tar.gz UXP-2018.07.18.tar.lz UXP-2018.07.18.tar.xz UXP-2018.07.18.zip |
Merge commit '50d3e596bbe89c95615f96eb71f6bc5be737a1db' into Basilisk-releasev2018.07.18
# Conflicts:
# browser/app/profile/firefox.js
# browser/components/preferences/jar.mn
Diffstat (limited to 'security/nss')
439 files changed, 39459 insertions, 21410 deletions
diff --git a/security/nss/.taskcluster.yml b/security/nss/.taskcluster.yml index 9d56c9bcd..494d31a7b 100644 --- a/security/nss/.taskcluster.yml +++ b/security/nss/.taskcluster.yml @@ -57,7 +57,7 @@ tasks: - "tc-treeherder.v2.{{project}}.{{revision}}.{{pushlog_id}}" payload: - image: ttaubert/nss-decision:0.0.2 + image: nssdev/nss-decision:0.0.2 env: TC_OWNER: {{owner}} diff --git a/security/nss/TAG-INFO b/security/nss/TAG-INFO index 2ff04f990..1d96321b3 100644 --- a/security/nss/TAG-INFO +++ b/security/nss/TAG-INFO @@ -1 +1 @@ -NSS_3_32_1_RTM +NSS_3_36_4_RTM 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 e69de29bb..ad818d0aa 100644 --- a/security/nss/automation/abi-check/expected-report-libssl3.so.txt +++ b/security/nss/automation/abi-check/expected-report-libssl3.so.txt @@ -0,0 +1,28 @@ + +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 b8d28cde0..c213ca3f8 100644 --- a/security/nss/automation/abi-check/previous-nss-release +++ b/security/nss/automation/abi-check/previous-nss-release @@ -1 +1 @@ -NSS_3_31_BRANCH +NSS_3_35_BRANCH diff --git a/security/nss/automation/buildbot-slave/build.sh b/security/nss/automation/buildbot-slave/build.sh index 3fc914803..00e749672 100755 --- a/security/nss/automation/buildbot-slave/build.sh +++ b/security/nss/automation/buildbot-slave/build.sh @@ -212,7 +212,7 @@ test_nss() RET=$? print_log "######## details of detected failures (if any) ########" - grep -B50 FAILED ${OUTPUTFILE} + grep -B50 -w FAILED ${OUTPUTFILE} [ $? -eq 1 ] || RET=1 print_result "NSS - tests - ${BITS} bits - ${OPT}" ${RET} 0 @@ -236,11 +236,14 @@ check_abi() BASE_NSPR=NSPR_$(head -1 ${HGDIR}/baseline/nss/automation/release/nspr-version.txt | cut -d . -f 1-2 | tr . _)_BRANCH hg clone -u "${BASE_NSPR}" "${HGDIR}/nspr" "${HGDIR}/baseline/nspr" if [ $? -ne 0 ]; then - echo "invalid tag ${BASE_NSPR} derived from ${BASE_NSS} automation/release/nspr-version.txt" - return 1 + echo "nonexisting tag ${BASE_NSPR} derived from ${BASE_NSS} automation/release/nspr-version.txt" + # Assume that version hasn't been released yet, fall back to trunk + pushd "${HGDIR}/baseline/nspr" + hg update default + popd fi - print_log "######## building older NSPR/NSS ########" + print_log "######## building baseline NSPR/NSS ########" pushd ${HGDIR}/baseline/nss print_log "$ ${MAKE} ${NSS_BUILD_TARGET}" @@ -253,26 +256,83 @@ check_abi() fi popd + ABI_PROBLEM_FOUND=0 ABI_REPORT=${OUTPUTDIR}/abi-diff.txt rm -f ${ABI_REPORT} PREVDIST=${HGDIR}/baseline/dist NEWDIST=${HGDIR}/dist ALL_SOs="libfreebl3.so libfreeblpriv3.so libnspr4.so libnss3.so libnssckbi.so libnssdbm3.so libnsssysinit.so libnssutil3.so libplc4.so libplds4.so libsmime3.so libsoftokn3.so libssl3.so" for SO in ${ALL_SOs}; do - if [ ! -f nss/automation/abi-check/expected-report-$SO.txt ]; then - touch nss/automation/abi-check/expected-report-$SO.txt + if [ ! -f ${HGDIR}/nss/automation/abi-check/expected-report-$SO.txt ]; then + touch ${HGDIR}/nss/automation/abi-check/expected-report-$SO.txt fi abidiff --hd1 $PREVDIST/public/ --hd2 $NEWDIST/public \ $PREVDIST/*/lib/$SO $NEWDIST/*/lib/$SO \ - > nss/automation/abi-check/new-report-$SO.txt - diff -u nss/automation/abi-check/expected-report-$SO.txt \ - nss/automation/abi-check/new-report-$SO.txt >> ${ABI_REPORT} + > ${HGDIR}/nss/automation/abi-check/new-report-temp$SO.txt + RET=$? + cat ${HGDIR}/nss/automation/abi-check/new-report-temp$SO.txt \ + | grep -v "^Functions changes summary:" \ + | grep -v "^Variables changes summary:" \ + > ${HGDIR}/nss/automation/abi-check/new-report-$SO.txt + rm -f ${HGDIR}/nss/automation/abi-check/new-report-temp$SO.txt + ABIDIFF_ERROR=$((($RET & 0x01) != 0)) + ABIDIFF_USAGE_ERROR=$((($RET & 0x02) != 0)) + ABIDIFF_ABI_CHANGE=$((($RET & 0x04) != 0)) + ABIDIFF_ABI_INCOMPATIBLE_CHANGE=$((($RET & 0x08) != 0)) + ABIDIFF_UNKNOWN_BIT_SET=$((($RET & 0xf0) != 0)) + + # If abidiff reports an error, or a usage error, or if it sets a result + # bit value this script doesn't know yet about, we'll report failure. + # For ABI changes, we don't yet report an error. We'll compare the + # result report with our whitelist. This allows us to silence changes + # that we're already aware of and have been declared acceptable. + + REPORT_RET_AS_FAILURE=0 + if [ $ABIDIFF_ERROR -ne 0 ]; then + print_log "abidiff reported ABIDIFF_ERROR." + REPORT_RET_AS_FAILURE=1 + fi + if [ $ABIDIFF_USAGE_ERROR -ne 0 ]; then + print_log "abidiff reported ABIDIFF_USAGE_ERROR." + REPORT_RET_AS_FAILURE=1 + fi + if [ $ABIDIFF_UNKNOWN_BIT_SET -ne 0 ]; then + print_log "abidiff reported ABIDIFF_UNKNOWN_BIT_SET." + REPORT_RET_AS_FAILURE=1 + fi + + if [ $ABIDIFF_ABI_CHANGE -ne 0 ]; then + print_log "Ignoring abidiff result ABI_CHANGE, instead we'll check for non-whitelisted differences." + fi + if [ $ABIDIFF_ABI_INCOMPATIBLE_CHANGE -ne 0 ]; then + print_log "Ignoring abidiff result ABIDIFF_ABI_INCOMPATIBLE_CHANGE, instead we'll check for non-whitelisted differences." + fi + + if [ $REPORT_RET_AS_FAILURE -ne 0 ]; then + ABI_PROBLEM_FOUND=1 + print_log "abidiff {$PREVDIST , $NEWDIST} for $SO FAILED with result $RET, or failed writing to ${HGDIR}/nss/automation/abi-check/new-report-$SO.txt" + fi + if [ ! -f ${HGDIR}/nss/automation/abi-check/expected-report-$SO.txt ]; then + ABI_PROBLEM_FOUND=1 + print_log "FAILED to access report file: ${HGDIR}/nss/automation/abi-check/expected-report-$SO.txt" + fi + + diff -wB -u ${HGDIR}/nss/automation/abi-check/expected-report-$SO.txt \ + ${HGDIR}/nss/automation/abi-check/new-report-$SO.txt >> ${ABI_REPORT} + if [ ! -f ${ABI_REPORT} ]; then + ABI_PROBLEM_FOUND=1 + print_log "FAILED to compare exepcted and new report: ${HGDIR}/nss/automation/abi-check/new-report-$SO.txt" + fi done if [ -s ${ABI_REPORT} ]; then print_log "FAILED: there are new unexpected ABI changes" cat ${ABI_REPORT} return 1 + elif [ $ABI_PROBLEM_FOUND -ne 0 ]; then + print_log "FAILED: failure executing the ABI checks" + cat ${ABI_REPORT} + return 1 fi return 0 diff --git a/security/nss/automation/clang-format/run_clang_format.sh b/security/nss/automation/clang-format/run_clang_format.sh index 2ba5ebeb1..378b00ff0 100644 --- a/security/nss/automation/clang-format/run_clang_format.sh +++ b/security/nss/automation/clang-format/run_clang_format.sh @@ -6,6 +6,8 @@ if [[ $(id -u) -eq 0 ]]; then exec su worker -c "$0 $*" fi +set -e + # Apply clang-format on the provided folder and verify that this doesn't change any file. # If any file differs after formatting, the script eventually exits with 1. # Any differences between formatted and unformatted files is printed to stdout to give a hint what's wrong. @@ -21,17 +23,16 @@ blacklist=( "./lib/zlib" \ "./lib/sqlite" \ "./gtests/google_test" \ - "./.hg" \ "./out" \ ) -top="$(dirname $0)/../.." -cd "$top" +top=$(cd "$(dirname $0)/../.."; pwd -P) if [ $# -gt 0 ]; then dirs=("$@") else - dirs=($(find . -maxdepth 2 -mindepth 1 -type d ! -path . \( ! -regex '.*/' \))) + cd "$top" + dirs=($(find . -maxdepth 2 -mindepth 1 -type d ! -path '*/.*' -print)) fi format_folder() @@ -46,20 +47,20 @@ format_folder() } for dir in "${dirs[@]}"; do - if format_folder "$dir" ; then + if format_folder "$dir"; then c="${dir//[^\/]}" echo "formatting $dir ..." - depth="" + depth=() if [ "${#c}" == "1" ]; then - depth="-maxdepth 1" + depth+=(-maxdepth 1) fi - find "$dir" $depth -type f \( -name '*.[ch]' -o -name '*.cc' \) -exec clang-format -i {} \+ + find "$dir" "${depth[@]}" -type f \( -name '*.[ch]' -o -name '*.cc' \) -exec clang-format -i {} \+ fi done TMPFILE=$(mktemp /tmp/$(basename $0).XXXXXX) -trap 'rm $TMPFILE' exit -if (cd $(dirname $0); hg root >/dev/null 2>&1); then +trap 'rm -f $TMPFILE' exit +if [[ -d "$top/.hg" ]]; then hg diff --git "$top" | tee $TMPFILE else git -C "$top" diff | tee $TMPFILE diff --git a/security/nss/automation/clang-format/setup.sh b/security/nss/automation/clang-format/setup.sh index 9b2480e90..beac9e905 100644 --- a/security/nss/automation/clang-format/setup.sh +++ b/security/nss/automation/clang-format/setup.sh @@ -17,8 +17,8 @@ apt_packages+=('locales') apt-get install -y --no-install-recommends ${apt_packages[@]} # Download clang. -curl -L http://releases.llvm.org/3.9.1/clang+llvm-3.9.1-x86_64-linux-gnu-ubuntu-16.04.tar.xz -o clang.tar.xz -curl -L http://releases.llvm.org/3.9.1/clang+llvm-3.9.1-x86_64-linux-gnu-ubuntu-16.04.tar.xz.sig -o clang.tar.xz.sig +curl -L https://releases.llvm.org/3.9.1/clang+llvm-3.9.1-x86_64-linux-gnu-ubuntu-16.04.tar.xz -o clang.tar.xz +curl -L https://releases.llvm.org/3.9.1/clang+llvm-3.9.1-x86_64-linux-gnu-ubuntu-16.04.tar.xz.sig -o clang.tar.xz.sig # Verify the signature. gpg --keyserver pool.sks-keyservers.net --recv-keys B6C8F98282B944E3B0D5C2530FC3042E345AD05D gpg --verify clang.tar.xz.sig diff --git a/security/nss/automation/release/nspr-version.txt b/security/nss/automation/release/nspr-version.txt index 98783a615..701680d2c 100644 --- a/security/nss/automation/release/nspr-version.txt +++ b/security/nss/automation/release/nspr-version.txt @@ -1,4 +1,4 @@ -4.16 +4.19 # The first line of this file must contain the human readable NSPR # version number, which is the minimum required version of NSPR diff --git a/security/nss/automation/saw/bmul.cry b/security/nss/automation/saw/bmul.cry new file mode 100644 index 000000000..87303dad6 --- /dev/null +++ b/security/nss/automation/saw/bmul.cry @@ -0,0 +1,8 @@ +/* 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/. */ + +bmul : {n,m} (fin n, n >= 1, m == n*2 - 1) => [n] -> [n] -> ([n], [n]) +bmul a b = (take`{n} prod, drop`{n} prod) + where prod = pad (pmult a b : [m]) + pad x = zero # x diff --git a/security/nss/automation/saw/bmul.saw b/security/nss/automation/saw/bmul.saw new file mode 100644 index 000000000..22cd2757b --- /dev/null +++ b/security/nss/automation/saw/bmul.saw @@ -0,0 +1,26 @@ +// 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/. + +import "bmul.cry"; + +print "Loading LLVM bitcode..."; +m <- llvm_load_module "../../../dist/Debug/lib/libfreeblpriv3.so.bc"; + +let SpecBinaryMul n = do { + x <- llvm_var "x" (llvm_int n); + y <- llvm_var "y" (llvm_int n); + llvm_ptr "r_high" (llvm_int n); + r_high <- llvm_var "*r_high" (llvm_int n); + llvm_ptr "r_low" (llvm_int n); + r_low <- llvm_var "*r_low" (llvm_int n); + + let res = {{ bmul x y }}; + llvm_ensure_eq "*r_high" {{ res.0 }}; + llvm_ensure_eq "*r_low" {{ res.1 }}; + + llvm_verify_tactic abc; +}; + +print "Proving equality for 32-bit bmul()..."; +time (llvm_verify m "bmul32" [] (SpecBinaryMul 32)); diff --git a/security/nss/automation/saw/chacha20.cry b/security/nss/automation/saw/chacha20.cry new file mode 100644 index 000000000..0b52d51ad --- /dev/null +++ b/security/nss/automation/saw/chacha20.cry @@ -0,0 +1,357 @@ +/* +** ChaCha20 specification +** Author: Austin Seipp <aseipp@pobox.com>. Released in the Public Domain. +** +** Based on RFC 7539 - "ChaCha20 and Poly1305 for IETF Protocols" +** https://tools.ietf.org/html/rfc7539 +*/ +module chacha20 where + +/* -------------------------------------------------------------------------- */ +/* -- Implementation -------------------------------------------------------- */ + +type Round = [16][32] // An input to the ChaCha20 core function +type Block = [64][8] // An output block from the ChaCha20 core function. +type Key = [32][8] // A 32-byte input key +type Nonce = [12][8] // A 12-byte nonce +type Counter = [32] // Starting block counter. Usually 1 or 0. + +/* ---------------------------------- */ +/* -- Quarter Round ----------------- */ + +// The quarter round. This takes 4 32-bit integers and diffuses them +// appropriately, and is the core of the column and diagonal round. +qround : [4][32] -> [4][32] +qround [ a0, b0, c0, d0 ] = [ a2, b4, c2, d4 ] + where + a1 = a0 + b0 /* a += b; d ^= a; d <<<= 16 */ + d1 = d0 ^ a1 + d2 = d1 <<< 16 + + c1 = c0 + d2 /* c += d; b ^= c; b <<<= 12 */ + b1 = b0 ^ c1 + b2 = b1 <<< 12 + + a2 = a1 + b2 /* a += b; d ^= a; d <<<= 8 */ + d3 = d2 ^ a2 + d4 = d3 <<< 8 + + c2 = c1 + d4 /* c += d; b ^= c; b <<<= 7 */ + b3 = b2 ^ c2 + b4 = b3 <<< 7 + + +/* ---------------------------------- */ +/* -- Column and diagonal rounds ---- */ + +// Perform the column round, followed by the diagonal round on the +// input state, which are both defined in terms of the quarter +// round. ChaCha20 requires 20 total rounds of interleaving +// column/diagonal passes on the state, and therefore `cdround` actually +// does two passes at once (mostly for simplicity). +cdround : Round -> Round +cdround [ x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15 ] + = [ z0, z1, z2, z3, z4, z5, z6, z7, z8, z9, z10, z11, z12, z13, z14, z15 ] + where + // Column round + [ y0, y4, y8, y12 ] = qround [ x0, x4, x8, x12 ] + [ y1, y5, y9, y13 ] = qround [ x1, x5, x9, x13 ] + [ y2, y6, y10, y14 ] = qround [ x2, x6, x10, x14 ] + [ y3, y7, y11, y15 ] = qround [ x3, x7, x11, x15 ] + + // Diagonal round + [ z0, z5, z10, z15 ] = qround [ y0, y5, y10, y15 ] + [ z1, z6, z11, z12 ] = qround [ y1, y6, y11, y12 ] + [ z2, z7, z8, z13 ] = qround [ y2, y7, y8, y13 ] + [ z3, z4, z9, z14 ] = qround [ y3, y4, y9, y14 ] + + +/* ---------------------------------- */ +/* -- Block encryption -------------- */ + +// Given an input round, calculate the core ChaCha20 algorithm over +// the round and return an output block. These output blocks form the +// stream which you XOR your plaintext with, and successive iterations of +// the core algorithm result in an infinite stream you can use as a +// cipher. +core : Round -> Block +core x = block + where + rounds = iterate cdround x // Do a bunch of column/diagonal passes... + result = rounds @ 10 // And grab the 10th result (20 total passes) + block = blocked (x + result) // Add to input, convert to output block + + +/* ---------------------------------- */ +/* -- Key Expansion ----------------- */ + +// Key expansion. Given a nonce and a key, compute a round (which is +// fed to the core algorithm above) by taking the initial round state and +// mixing in the key and nonce appropriately. +kexp : Key -> Counter -> Nonce -> Round +kexp k c n = [ c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15 ] + where + // The following describes the layout of the output round, which + // is fed into the core algorithm successively. + + // Bytes 0-3: Constants + [ c0, c1, c2, c3 ] = [ 0x61707865, 0x3320646e, 0x79622d32, 0x6b206574 ] + + // Bytes 4-11: Key + [ c4, c5, c6, c7 ] = map rjoin (groupBy`{4} kslice1 : [4][4][8]) : [4][32] + [ c8, c9, c10, c11 ] = map rjoin (groupBy`{4} kslice2 : [4][4][8]) : [4][32] + kslice1 = k @@ ([ 0 .. 15 ] : [16][32]) // Top half + kslice2 = k @@ ([ 16 .. 31 ] : [16][32]) // Bottom half + + // Bytes 12: Counter, starts off with whatever the user specified + // (usually 0 or 1) + [ c12 ] = [ c ] + + // Bytes 14-15: Nonce + [ c13, c14, c15 ] = map rjoin (groupBy`{4} n) + + +/* ---------------------------------- */ +/* -- Round increments -------------- */ + +// Take a given number of iterations and the input round (after key +// expansion!), and calculate the input round for the core algorithm +// function. This allows you to index into a particular Round which +// can be passed to the 'core' function. +iround : [64] -> Round -> Round +iround n r = (iterate once r) @ n where + // Given a round, increment the counter inside (index no 12) + once [ x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15 ] + = [ x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12+1, x13, x14, x15 ] + +/* ---------------------------------- */ +/* -- ChaCha20 encryption ----------- */ + +// Produce a psuedo-random stream given a nonce and a key, which can +// be XOR'd with your data to encrypt it. +stream : {n} (fin n) => Key -> Counter -> Nonce -> [n][8] +stream k c n = take`{n} (join rounds) // Take n bytes from the final result + where + // Expand key + key = kexp k c n + + // Produce the stream by successively incrementing the input round + // by `i`, and running the core algorithm to get the resulting + // stream for the `i`th input. Once these are concatenated, you have + // an infinite list representing the ChaCha20 stream. + rounds = [ core (iround i key) | i <- [ 0, 1 ... ] ] + + +// Given an message, a nonce, and a key, produce an encrypted +// message. This is simply defined as the XOR of the message and the +// corresponding encryption stream. +encrypt : {n} (fin n) => Key -> Counter -> Nonce -> [n][8] -> [n][8] +encrypt k c n m = m ^ (stream k c n) + +/* -------------------------------------------------------------------------- */ +/* -- Theorems, tests ------------------------------------------------------- */ + +// Tests are private +private + qround01 = qround in == out + where + in = [ 0x11111111, 0x01020304, 0x9b8d6f43, 0x01234567 ] + out = [ 0xea2a92f4, 0xcb1cf8ce, 0x4581472e, 0x5881c4bb ] + + core01 = kexp k 1 n == out + where + n = [ 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x4a, + 0x00, 0x00, 0x00, 0x00 ] + k = [ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f ] + out = [ 0x61707865, 0x3320646e, 0x79622d32, 0x6b206574, + 0x03020100, 0x07060504, 0x0b0a0908, 0x0f0e0d0c, + 0x13121110, 0x17161514, 0x1b1a1918, 0x1f1e1d1c, + 0x00000001, 0x09000000, 0x4a000000, 0x00000000 ] + + core02 = core (kexp k 1 n) == out + where + n = [ 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x4a, + 0x00, 0x00, 0x00, 0x00 ] + k = [ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f ] + out = [ 0x10, 0xf1, 0xe7, 0xe4, 0xd1, 0x3b, 0x59, 0x15, + 0x50, 0x0f, 0xdd, 0x1f, 0xa3, 0x20, 0x71, 0xc4, + 0xc7, 0xd1, 0xf4, 0xc7, 0x33, 0xc0, 0x68, 0x03, + 0x04, 0x22, 0xaa, 0x9a, 0xc3, 0xd4, 0x6c, 0x4e, + 0xd2, 0x82, 0x64, 0x46, 0x07, 0x9f, 0xaa, 0x09, + 0x14, 0xc2, 0xd7, 0x05, 0xd9, 0x8b, 0x02, 0xa2, + 0xb5, 0x12, 0x9c, 0xd1, 0xde, 0x16, 0x4e, 0xb9, + 0xcb, 0xd0, 0x83, 0xe8, 0xa2, 0x50, 0x3c, 0x4e ] + + rfctest01 = encrypt zero zero zero zero + == [ 0x76, 0xb8, 0xe0, 0xad, 0xa0, 0xf1, 0x3d, 0x90, 0x40, 0x5d, + 0x6a, 0xe5, 0x53, 0x86, 0xbd, 0x28, 0xbd, 0xd2, 0x19, 0xb8, + 0xa0, 0x8d, 0xed, 0x1a, 0xa8, 0x36, 0xef, 0xcc, 0x8b, 0x77, + 0x0d, 0xc7, 0xda, 0x41, 0x59, 0x7c, 0x51, 0x57, 0x48, 0x8d, + 0x77, 0x24, 0xe0, 0x3f, 0xb8, 0xd8, 0x4a, 0x37, 0x6a, 0x43, + 0xb8, 0xf4, 0x15, 0x18, 0xa1, 0x1c, 0xc3, 0x87, 0xb6, 0x69, + 0xb2, 0xee, 0x65, 0x86 ] + + rfctest02 = encrypt (zero # [1]) 1 (zero # [2]) msg == out + where + out = [ 0xa3, 0xfb, 0xf0, 0x7d, 0xf3, 0xfa, 0x2f, 0xde, 0x4f, 0x37, + 0x6c, 0xa2, 0x3e, 0x82, 0x73, 0x70, 0x41, 0x60, 0x5d, 0x9f, + 0x4f, 0x4f, 0x57, 0xbd, 0x8c, 0xff, 0x2c, 0x1d, 0x4b, 0x79, + 0x55, 0xec, 0x2a, 0x97, 0x94, 0x8b, 0xd3, 0x72, 0x29, 0x15, + 0xc8, 0xf3, 0xd3, 0x37, 0xf7, 0xd3, 0x70, 0x05, 0x0e, 0x9e, + 0x96, 0xd6, 0x47, 0xb7, 0xc3, 0x9f, 0x56, 0xe0, 0x31, 0xca, + 0x5e, 0xb6, 0x25, 0x0d, 0x40, 0x42, 0xe0, 0x27, 0x85, 0xec, + 0xec, 0xfa, 0x4b, 0x4b, 0xb5, 0xe8, 0xea, 0xd0, 0x44, 0x0e, + 0x20, 0xb6, 0xe8, 0xdb, 0x09, 0xd8, 0x81, 0xa7, 0xc6, 0x13, + 0x2f, 0x42, 0x0e, 0x52, 0x79, 0x50, 0x42, 0xbd, 0xfa, 0x77, + 0x73, 0xd8, 0xa9, 0x05, 0x14, 0x47, 0xb3, 0x29, 0x1c, 0xe1, + 0x41, 0x1c, 0x68, 0x04, 0x65, 0x55, 0x2a, 0xa6, 0xc4, 0x05, + 0xb7, 0x76, 0x4d, 0x5e, 0x87, 0xbe, 0xa8, 0x5a, 0xd0, 0x0f, + 0x84, 0x49, 0xed, 0x8f, 0x72, 0xd0, 0xd6, 0x62, 0xab, 0x05, + 0x26, 0x91, 0xca, 0x66, 0x42, 0x4b, 0xc8, 0x6d, 0x2d, 0xf8, + 0x0e, 0xa4, 0x1f, 0x43, 0xab, 0xf9, 0x37, 0xd3, 0x25, 0x9d, + 0xc4, 0xb2, 0xd0, 0xdf, 0xb4, 0x8a, 0x6c, 0x91, 0x39, 0xdd, + 0xd7, 0xf7, 0x69, 0x66, 0xe9, 0x28, 0xe6, 0x35, 0x55, 0x3b, + 0xa7, 0x6c, 0x5c, 0x87, 0x9d, 0x7b, 0x35, 0xd4, 0x9e, 0xb2, + 0xe6, 0x2b, 0x08, 0x71, 0xcd, 0xac, 0x63, 0x89, 0x39, 0xe2, + 0x5e, 0x8a, 0x1e, 0x0e, 0xf9, 0xd5, 0x28, 0x0f, 0xa8, 0xca, + 0x32, 0x8b, 0x35, 0x1c, 0x3c, 0x76, 0x59, 0x89, 0xcb, 0xcf, + 0x3d, 0xaa, 0x8b, 0x6c, 0xcc, 0x3a, 0xaf, 0x9f, 0x39, 0x79, + 0xc9, 0x2b, 0x37, 0x20, 0xfc, 0x88, 0xdc, 0x95, 0xed, 0x84, + 0xa1, 0xbe, 0x05, 0x9c, 0x64, 0x99, 0xb9, 0xfd, 0xa2, 0x36, + 0xe7, 0xe8, 0x18, 0xb0, 0x4b, 0x0b, 0xc3, 0x9c, 0x1e, 0x87, + 0x6b, 0x19, 0x3b, 0xfe, 0x55, 0x69, 0x75, 0x3f, 0x88, 0x12, + 0x8c, 0xc0, 0x8a, 0xaa, 0x9b, 0x63, 0xd1, 0xa1, 0x6f, 0x80, + 0xef, 0x25, 0x54, 0xd7, 0x18, 0x9c, 0x41, 0x1f, 0x58, 0x69, + 0xca, 0x52, 0xc5, 0xb8, 0x3f, 0xa3, 0x6f, 0xf2, 0x16, 0xb9, + 0xc1, 0xd3, 0x00, 0x62, 0xbe, 0xbc, 0xfd, 0x2d, 0xc5, 0xbc, + 0xe0, 0x91, 0x19, 0x34, 0xfd, 0xa7, 0x9a, 0x86, 0xf6, 0xe6, + 0x98, 0xce, 0xd7, 0x59, 0xc3, 0xff, 0x9b, 0x64, 0x77, 0x33, + 0x8f, 0x3d, 0xa4, 0xf9, 0xcd, 0x85, 0x14, 0xea, 0x99, 0x82, + 0xcc, 0xaf, 0xb3, 0x41, 0xb2, 0x38, 0x4d, 0xd9, 0x02, 0xf3, + 0xd1, 0xab, 0x7a, 0xc6, 0x1d, 0xd2, 0x9c, 0x6f, 0x21, 0xba, + 0x5b, 0x86, 0x2f, 0x37, 0x30, 0xe3, 0x7c, 0xfd, 0xc4, 0xfd, + 0x80, 0x6c, 0x22, 0xf2, 0x21 ] + + msg = [ 0x41, 0x6e, 0x79, 0x20, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x49, 0x45, 0x54, 0x46, 0x20, 0x69, 0x6e, 0x74, + 0x65, 0x6e, 0x64, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x6f, 0x72, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x70, + 0x75, 0x62, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x61, 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x72, + 0x20, 0x70, 0x61, 0x72, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x61, + 0x6e, 0x20, 0x49, 0x45, 0x54, 0x46, 0x20, 0x49, 0x6e, 0x74, + 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2d, 0x44, 0x72, 0x61, 0x66, + 0x74, 0x20, 0x6f, 0x72, 0x20, 0x52, 0x46, 0x43, 0x20, 0x61, + 0x6e, 0x64, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x6d, 0x61, 0x64, + 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, 0x69, 0x6e, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, + 0x20, 0x6f, 0x66, 0x20, 0x61, 0x6e, 0x20, 0x49, 0x45, 0x54, + 0x46, 0x20, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, + 0x20, 0x69, 0x73, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, + 0x65, 0x72, 0x65, 0x64, 0x20, 0x61, 0x6e, 0x20, 0x22, 0x49, + 0x45, 0x54, 0x46, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x2e, 0x20, 0x53, + 0x75, 0x63, 0x68, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, + 0x64, 0x65, 0x20, 0x6f, 0x72, 0x61, 0x6c, 0x20, 0x73, 0x74, + 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x69, + 0x6e, 0x20, 0x49, 0x45, 0x54, 0x46, 0x20, 0x73, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2c, 0x20, 0x61, 0x73, 0x20, + 0x77, 0x65, 0x6c, 0x6c, 0x20, 0x61, 0x73, 0x20, 0x77, 0x72, + 0x69, 0x74, 0x74, 0x65, 0x6e, 0x20, 0x61, 0x6e, 0x64, 0x20, + 0x65, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x6f, 0x6e, 0x69, 0x63, + 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6d, 0x61, 0x64, 0x65, + 0x20, 0x61, 0x74, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x74, 0x69, + 0x6d, 0x65, 0x20, 0x6f, 0x72, 0x20, 0x70, 0x6c, 0x61, 0x63, + 0x65, 0x2c, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x61, + 0x72, 0x65, 0x20, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x65, 0x64, 0x20, 0x74, 0x6f ] + + rfctest03 = encrypt key 42 (zero # [2]) msg == out + where + key = [ 0x1c, 0x92, 0x40, 0xa5, 0xeb, 0x55, 0xd3, 0x8a, 0xf3, 0x33, + 0x88, 0x86, 0x04, 0xf6, 0xb5, 0xf0, 0x47, 0x39, 0x17, 0xc1, + 0x40, 0x2b, 0x80, 0x09, 0x9d, 0xca, 0x5c, 0xbc, 0x20, 0x70, + 0x75, 0xc0 ] + out = [ 0x27, 0x54, 0x77, 0x61, 0x73, 0x20, 0x62, 0x72, 0x69, 0x6c, + 0x6c, 0x69, 0x67, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x73, 0x6c, 0x69, 0x74, 0x68, 0x79, 0x20, + 0x74, 0x6f, 0x76, 0x65, 0x73, 0x0a, 0x44, 0x69, 0x64, 0x20, + 0x67, 0x79, 0x72, 0x65, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x67, + 0x69, 0x6d, 0x62, 0x6c, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x77, 0x61, 0x62, 0x65, 0x3a, 0x0a, 0x41, + 0x6c, 0x6c, 0x20, 0x6d, 0x69, 0x6d, 0x73, 0x79, 0x20, 0x77, + 0x65, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x6f, + 0x72, 0x6f, 0x67, 0x6f, 0x76, 0x65, 0x73, 0x2c, 0x0a, 0x41, + 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6d, 0x6f, 0x6d, + 0x65, 0x20, 0x72, 0x61, 0x74, 0x68, 0x73, 0x20, 0x6f, 0x75, + 0x74, 0x67, 0x72, 0x61, 0x62, 0x65, 0x2e ] + + msg = [ 0x62, 0xe6, 0x34, 0x7f, 0x95, 0xed, 0x87, 0xa4, 0x5f, 0xfa, + 0xe7, 0x42, 0x6f, 0x27, 0xa1, 0xdf, 0x5f, 0xb6, 0x91, 0x10, + 0x04, 0x4c, 0x0d, 0x73, 0x11, 0x8e, 0xff, 0xa9, 0x5b, 0x01, + 0xe5, 0xcf, 0x16, 0x6d, 0x3d, 0xf2, 0xd7, 0x21, 0xca, 0xf9, + 0xb2, 0x1e, 0x5f, 0xb1, 0x4c, 0x61, 0x68, 0x71, 0xfd, 0x84, + 0xc5, 0x4f, 0x9d, 0x65, 0xb2, 0x83, 0x19, 0x6c, 0x7f, 0xe4, + 0xf6, 0x05, 0x53, 0xeb, 0xf3, 0x9c, 0x64, 0x02, 0xc4, 0x22, + 0x34, 0xe3, 0x2a, 0x35, 0x6b, 0x3e, 0x76, 0x43, 0x12, 0xa6, + 0x1a, 0x55, 0x32, 0x05, 0x57, 0x16, 0xea, 0xd6, 0x96, 0x25, + 0x68, 0xf8, 0x7d, 0x3f, 0x3f, 0x77, 0x04, 0xc6, 0xa8, 0xd1, + 0xbc, 0xd1, 0xbf, 0x4d, 0x50, 0xd6, 0x15, 0x4b, 0x6d, 0xa7, + 0x31, 0xb1, 0x87, 0xb5, 0x8d, 0xfd, 0x72, 0x8a, 0xfa, 0x36, + 0x75, 0x7a, 0x79, 0x7a, 0xc1, 0x88, 0xd1 ] + +property allTestsPass = + ([ // Basic tests + qround01, core01, core02 + // Full RFC test vectors + , rfctest01, rfctest02, rfctest03 + ] : [_]Bit) == ~zero // All test bits should equal one + +/* -------------------------------------------------------------------------- */ +/* -- Private utilities ----------------------------------------------------- */ + +private + // Convert a round into a block, by splitting every 32-bit round entry + // into 4 bytes, and then serialize those values into a full block. + blocked : Round -> Block + blocked x = join (map toBytes x) + where + // This essentially splits a 32-bit number into 4-byte + // little-endian form, where 'rjoin' is the inverse and would merge + // 4 bytes as a 32-bit little endian number. + toBytes : [32] -> [4][8] + toBytes v = reverse (groupBy`{8} v) + + // Map a function over a finite list. + map : { a, b, c } + (a -> b) -> [c]a -> [c]b + map f xs = [ f x | x <- xs ] + + // Map a function iteratively over a seed value, producing an infinite + // list of successive function applications: + // + // iterate f 0 == [ 0, f 0, f (f 0), f (f (f 0)), ... ] + iterate : { a } (a -> a) -> a -> [inf]a + iterate f x = [x] # [ f v | v <- iterate f x ] + where + // NB: Needs a binded name in order to tie the recursive knot. + xs = [x] # [ f v | v <- xs ] + + // rjoin = join . reverse + // This encodes a sequence of values as a little endian number + // e.g. [ 0xaa, 0xbb, 0xcc, 0xdd ] is serialized as \xdd\xcc\xbb\xaa + rjoin : {a, b, c} + ( fin a, fin c + ) => [c][a]b -> [a * c]b + rjoin x = join (reverse x) diff --git a/security/nss/automation/saw/chacha20.saw b/security/nss/automation/saw/chacha20.saw new file mode 100644 index 000000000..92145ab74 --- /dev/null +++ b/security/nss/automation/saw/chacha20.saw @@ -0,0 +1,40 @@ +// 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/. + +import "chacha20.cry" as chacha20; + +print "Proving ChaCha20 spec..."; +prove_print abc {{ chacha20::allTestsPass }}; + +print "Loading LLVM bitcode..."; +m <- llvm_load_module "../../../dist/Debug/lib/libfreeblpriv3.so.bc"; + +let SpecChaCha20 n = do { + llvm_ptr "output" (llvm_array n (llvm_int 8)); + output <- llvm_var "*output" (llvm_array n (llvm_int 8)); + + llvm_ptr "plain" (llvm_array n (llvm_int 8)); + plain <- llvm_var "*plain" (llvm_array n (llvm_int 8)); + + len <- llvm_var "len" (llvm_int 32); + llvm_assert_eq "len" {{ `n : [32] }}; + + llvm_ptr "k" (llvm_array 32 (llvm_int 8)); + k <- llvm_var "*k" (llvm_array 32 (llvm_int 8)); + + llvm_ptr "n1" (llvm_array 12 (llvm_int 8)); + n1 <- llvm_var "*n1" (llvm_array 12 (llvm_int 8)); + + ctr <- llvm_var "ctr" (llvm_int 32); + + llvm_ensure_eq "*output" {{ chacha20::encrypt k ctr n1 plain }}; + + llvm_verify_tactic abc; +}; + +print "Proving equality for a single block..."; +time (llvm_verify m "Hacl_Chacha20_chacha20" [] (SpecChaCha20 64)); + +print "Proving equality for multiple blocks..."; +time (llvm_verify m "Hacl_Chacha20_chacha20" [] (SpecChaCha20 256)); diff --git a/security/nss/automation/saw/poly1305-hacl.saw b/security/nss/automation/saw/poly1305-hacl.saw new file mode 100644 index 000000000..a4dfff6d9 --- /dev/null +++ b/security/nss/automation/saw/poly1305-hacl.saw @@ -0,0 +1,38 @@ +// 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/. + +import "poly1305.cry" as poly1305; + +print "Proving Poly1305 spec..."; +prove_print abc {{ poly1305::allTestsPass }}; + +print "Loading LLVM bitcode..."; +m <- llvm_load_module "../../../dist/Debug/lib/libfreeblpriv3.so.bc"; + +let SpecPoly1305 n = do { + llvm_ptr "output" (llvm_array 16 (llvm_int 8)); + output <- llvm_var "*output" (llvm_array 16 (llvm_int 8)); + + llvm_ptr "input" (llvm_array n (llvm_int 8)); + input <- llvm_var "*input" (llvm_array n (llvm_int 8)); + + llvm_var "len1" (llvm_int 64); + llvm_ptr "k1" (llvm_array 32 (llvm_int 8)); + k1 <- llvm_var "*k1" (llvm_array 32 (llvm_int 8)); + + llvm_assert_eq "*input" {{ zero : [n][8] }}; + llvm_assert_eq "len1" {{ `n : [64] }}; + + llvm_assert_eq "*k1" {{ zero : [32][8] }}; + + let res = {{ poly1305::Poly1305 input (take`{16} k1) (drop`{16} k1) }}; + llvm_ensure_eq "*output" {{ res }}; + + llvm_verify_tactic abc; +}; + +print "Proving equality for a single block..."; +// This is currently disabled as it takes way too long. We need to help Z3 +// prove this before we can enable it on Taskcluster. +//time (llvm_verify m "Hacl_Poly1305_64_crypto_onetimeauth" [] (SpecPoly1305 16)); diff --git a/security/nss/automation/saw/poly1305.cry b/security/nss/automation/saw/poly1305.cry new file mode 100644 index 000000000..6321a4f19 --- /dev/null +++ b/security/nss/automation/saw/poly1305.cry @@ -0,0 +1,336 @@ +/* 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 file provides a spec of the Poly1305 one-time authenticator. + * See <https://tools.ietf.org/html/rfc7539> for details. */ + +module poly1305 where + +P : [136] +P = 2^^130 - 5 + +Poly1305 : {n} (fin n) => [n][8] -> [16][8] -> [16][8] -> [16][8] +Poly1305 msg r s = reverse (groupBy (drop ((rounds ! 0) + s'))) + where + rounds = [zero] # [ Poly1305_block acc r' b | b <- blocks | acc <- rounds ] + r' = zero # (Poly1305_clamp (join (reverse r))) + s' = zero # (join (reverse s)) + blocks = Poly1305_split msg + +private + // 0x0f - for r[3], r[7], r[11], r[15] + // 0xfc - for r[4], r[8], r[12] + Poly1305_clamp r = r && 0x0ffffffc0ffffffc0ffffffc0fffffff + + // Poly1305_block : ((acc + msg) * r) % P + Poly1305_block : [136] -> [136] -> [136] -> [136] + Poly1305_block acc r msg = drop (prod % (zero # P)) + where + acc' : [137] + // Add the current block to the accumulator. + acc' = (zero # acc) + (zero # msg) + prod : [273] + // Multiply the new accumulator value by r. + prod = ((zero : [137]) # r) * ((zero : [136]) # acc') + + Poly1305_split : {n, nb, nf} (fin n, nf == n / 16, nb == (n + 15) / 16) => [n][8] -> [nb][136] + Poly1305_split msg = take ((h1 : [nf][136]) # h2) + where + // Split all full 16-byte blocks and append 0x01, then convert to LE. + h1 = [ join (reverse (b # [0x01])) | b <- groupBy`{16} (take msg)] + // Pad the remaining bytes (if any) and convert to LE. + h2 = [join (reverse ((drop`{nf * 16} msg) # [0x01] # zero))] + +/* -------------------------------------------------------------------------- */ +/* -- Tests ----------------------------------------------------------------- */ + +private + // https://tools.ietf.org/html/rfc7539#section-2.5.2 + rval1 = [0x85, 0xd6, 0xbe, 0x78, 0x57, 0x55, 0x6d, 0x33, + 0x7f, 0x44, 0x52, 0xfe, 0x42, 0xd5, 0x06, 0xa8] + sval1 = [0x01, 0x03, 0x80, 0x8a, 0xfb, 0x0d, 0xb2, 0xfd, + 0x4a, 0xbf, 0xf6, 0xaf, 0x41, 0x49, 0xf5, 0x1b] + text1 = [0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x46, 0x6f, + 0x72, 0x75, 0x6d, 0x20, 0x52, 0x65, 0x73, 0x65, + 0x61, 0x72, 0x63, 0x68, 0x20, 0x47, 0x72, 0x6f, + 0x75, 0x70] + + rfctest01 = Poly1305 text1 rval1 sval1 + == [0xa8, 0x06, 0x1d, 0xc1, 0x30, 0x51, 0x36, 0xc6, + 0xc2, 0x2b, 0x8b, 0xaf, 0x0c, 0x01, 0x27, 0xa9] + + // https://tools.ietf.org/html/rfc7539#appendix-A.3 + // Test Vector #1 + rval2 = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] + sval2 = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] + text2 = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] + + rfctest02 = Poly1305 text2 rval2 sval2 + == [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] + + // https://tools.ietf.org/html/rfc7539#appendix-A.3 + // Test Vector #2 + rval3 = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] + sval3 = [0x36, 0xe5, 0xf6, 0xb5, 0xc5, 0xe0, 0x60, 0x70, + 0xf0, 0xef, 0xca, 0x96, 0x22, 0x7a, 0x86, 0x3e] + text3 = [0x41, 0x6e, 0x79, 0x20, 0x73, 0x75, 0x62, 0x6d, + 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x74, + 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x49, 0x45, + 0x54, 0x46, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x6e, + 0x64, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x6f, 0x72, 0x20, 0x66, + 0x6f, 0x72, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, + 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x72, + 0x20, 0x70, 0x61, 0x72, 0x74, 0x20, 0x6f, 0x66, + 0x20, 0x61, 0x6e, 0x20, 0x49, 0x45, 0x54, 0x46, + 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, + 0x74, 0x2d, 0x44, 0x72, 0x61, 0x66, 0x74, 0x20, + 0x6f, 0x72, 0x20, 0x52, 0x46, 0x43, 0x20, 0x61, + 0x6e, 0x64, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x20, 0x6d, 0x61, 0x64, 0x65, 0x20, 0x77, 0x69, + 0x74, 0x68, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, + 0x20, 0x6f, 0x66, 0x20, 0x61, 0x6e, 0x20, 0x49, + 0x45, 0x54, 0x46, 0x20, 0x61, 0x63, 0x74, 0x69, + 0x76, 0x69, 0x74, 0x79, 0x20, 0x69, 0x73, 0x20, + 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72, + 0x65, 0x64, 0x20, 0x61, 0x6e, 0x20, 0x22, 0x49, + 0x45, 0x54, 0x46, 0x20, 0x43, 0x6f, 0x6e, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, + 0x22, 0x2e, 0x20, 0x53, 0x75, 0x63, 0x68, 0x20, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, + 0x64, 0x65, 0x20, 0x6f, 0x72, 0x61, 0x6c, 0x20, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x49, 0x45, + 0x54, 0x46, 0x20, 0x73, 0x65, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x73, 0x2c, 0x20, 0x61, 0x73, 0x20, + 0x77, 0x65, 0x6c, 0x6c, 0x20, 0x61, 0x73, 0x20, + 0x77, 0x72, 0x69, 0x74, 0x74, 0x65, 0x6e, 0x20, + 0x61, 0x6e, 0x64, 0x20, 0x65, 0x6c, 0x65, 0x63, + 0x74, 0x72, 0x6f, 0x6e, 0x69, 0x63, 0x20, 0x63, + 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6d, 0x61, + 0x64, 0x65, 0x20, 0x61, 0x74, 0x20, 0x61, 0x6e, + 0x79, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x6f, + 0x72, 0x20, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x2c, + 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x61, + 0x72, 0x65, 0x20, 0x61, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f] + + rfctest03 = Poly1305 text3 rval3 sval3 + == [0x36, 0xe5, 0xf6, 0xb5, 0xc5, 0xe0, 0x60, 0x70, + 0xf0, 0xef, 0xca, 0x96, 0x22, 0x7a, 0x86, 0x3e] + + // https://tools.ietf.org/html/rfc7539#appendix-A.3 + // Test Vector #3 + rval4 = [0x36, 0xe5, 0xf6, 0xb5, 0xc5, 0xe0, 0x60, 0x70, + 0xf0, 0xef, 0xca, 0x96, 0x22, 0x7a, 0x86, 0x3e] + sval4 = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] + text4 = [0x41, 0x6e, 0x79, 0x20, 0x73, 0x75, 0x62, 0x6d, + 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x74, + 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x49, 0x45, + 0x54, 0x46, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x6e, + 0x64, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x6f, 0x72, 0x20, 0x66, + 0x6f, 0x72, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, + 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x72, + 0x20, 0x70, 0x61, 0x72, 0x74, 0x20, 0x6f, 0x66, + 0x20, 0x61, 0x6e, 0x20, 0x49, 0x45, 0x54, 0x46, + 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, + 0x74, 0x2d, 0x44, 0x72, 0x61, 0x66, 0x74, 0x20, + 0x6f, 0x72, 0x20, 0x52, 0x46, 0x43, 0x20, 0x61, + 0x6e, 0x64, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x20, 0x6d, 0x61, 0x64, 0x65, 0x20, 0x77, 0x69, + 0x74, 0x68, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, + 0x20, 0x6f, 0x66, 0x20, 0x61, 0x6e, 0x20, 0x49, + 0x45, 0x54, 0x46, 0x20, 0x61, 0x63, 0x74, 0x69, + 0x76, 0x69, 0x74, 0x79, 0x20, 0x69, 0x73, 0x20, + 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72, + 0x65, 0x64, 0x20, 0x61, 0x6e, 0x20, 0x22, 0x49, + 0x45, 0x54, 0x46, 0x20, 0x43, 0x6f, 0x6e, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, + 0x22, 0x2e, 0x20, 0x53, 0x75, 0x63, 0x68, 0x20, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, + 0x64, 0x65, 0x20, 0x6f, 0x72, 0x61, 0x6c, 0x20, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x49, 0x45, + 0x54, 0x46, 0x20, 0x73, 0x65, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x73, 0x2c, 0x20, 0x61, 0x73, 0x20, + 0x77, 0x65, 0x6c, 0x6c, 0x20, 0x61, 0x73, 0x20, + 0x77, 0x72, 0x69, 0x74, 0x74, 0x65, 0x6e, 0x20, + 0x61, 0x6e, 0x64, 0x20, 0x65, 0x6c, 0x65, 0x63, + 0x74, 0x72, 0x6f, 0x6e, 0x69, 0x63, 0x20, 0x63, + 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6d, 0x61, + 0x64, 0x65, 0x20, 0x61, 0x74, 0x20, 0x61, 0x6e, + 0x79, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x6f, + 0x72, 0x20, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x2c, + 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x61, + 0x72, 0x65, 0x20, 0x61, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f] + + rfctest04 = Poly1305 text4 rval4 sval4 + == [0xf3, 0x47, 0x7e, 0x7c, 0xd9, 0x54, 0x17, 0xaf, + 0x89, 0xa6, 0xb8, 0x79, 0x4c, 0x31, 0x0c, 0xf0] + + // https://tools.ietf.org/html/rfc7539#appendix-A.3 + // Test Vector #4 + rval5 = [0x1c, 0x92, 0x40, 0xa5, 0xeb, 0x55, 0xd3, 0x8a, + 0xf3, 0x33, 0x88, 0x86, 0x04, 0xf6, 0xb5, 0xf0] + sval5 = [0x47, 0x39, 0x17, 0xc1, 0x40, 0x2b, 0x80, 0x09, + 0x9d, 0xca, 0x5c, 0xbc, 0x20, 0x70, 0x75, 0xc0] + text5 = [0x27, 0x54, 0x77, 0x61, 0x73, 0x20, 0x62, 0x72, + 0x69, 0x6c, 0x6c, 0x69, 0x67, 0x2c, 0x20, 0x61, + 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, + 0x6c, 0x69, 0x74, 0x68, 0x79, 0x20, 0x74, 0x6f, + 0x76, 0x65, 0x73, 0x0a, 0x44, 0x69, 0x64, 0x20, + 0x67, 0x79, 0x72, 0x65, 0x20, 0x61, 0x6e, 0x64, + 0x20, 0x67, 0x69, 0x6d, 0x62, 0x6c, 0x65, 0x20, + 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77, + 0x61, 0x62, 0x65, 0x3a, 0x0a, 0x41, 0x6c, 0x6c, + 0x20, 0x6d, 0x69, 0x6d, 0x73, 0x79, 0x20, 0x77, + 0x65, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x62, 0x6f, 0x72, 0x6f, 0x67, 0x6f, 0x76, 0x65, + 0x73, 0x2c, 0x0a, 0x41, 0x6e, 0x64, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x6d, 0x6f, 0x6d, 0x65, 0x20, + 0x72, 0x61, 0x74, 0x68, 0x73, 0x20, 0x6f, 0x75, + 0x74, 0x67, 0x72, 0x61, 0x62, 0x65, 0x2e] + + rfctest05 = Poly1305 text5 rval5 sval5 + == [0x45, 0x41, 0x66, 0x9a, 0x7e, 0xaa, 0xee, 0x61, + 0xe7, 0x08, 0xdc, 0x7c, 0xbc, 0xc5, 0xeb, 0x62] + + // https://tools.ietf.org/html/rfc7539#appendix-A.3 + // Test Vector #5 + rval6 = [0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] + sval6 = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] + text6 = [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] + + rfctest06 = Poly1305 text6 rval6 sval6 + == [0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] + + // https://tools.ietf.org/html/rfc7539#appendix-A.3 + // Test Vector #6 + rval7 = [0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] + sval7 = [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] + text7 = [0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] + + rfctest07 = Poly1305 text7 rval7 sval7 + == [0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] + + // https://tools.ietf.org/html/rfc7539#appendix-A.3 + // Test Vector #7 + rval8 = [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] + sval8 = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] + text8 = [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] + + rfctest08 = Poly1305 text8 rval8 sval8 + == [0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] + + // https://tools.ietf.org/html/rfc7539#appendix-A.3 + // Test Vector #8 + rval9 = [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] + sval9 = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] + text9 = [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xfb, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, + 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01] + + rfctest09 = Poly1305 text9 rval9 sval9 + == [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] + + // https://tools.ietf.org/html/rfc7539#appendix-A.3 + // Test Vector #9 + rval10 = [0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] + sval10 = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] + text10 = [0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] + + rfctest10 = Poly1305 text10 rval10 sval10 + == [0xfa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] + + // https://tools.ietf.org/html/rfc7539#appendix-A.3 + // Test Vector #10 + rval11 = [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] + sval11 = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] + text11 = [0xe3, 0x35, 0x94, 0xd7, 0x50, 0x5e, 0x43, 0xb9, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x94, 0xd7, 0x50, 0x5e, 0x43, 0x79, 0xcd, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] + + rfctest11 = Poly1305 text11 rval11 sval11 + == [0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] + + // https://tools.ietf.org/html/rfc7539#appendix-A.3 + // Test Vector #11 + rval12 = [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] + sval12 = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] + text12 = [0xe3, 0x35, 0x94, 0xd7, 0x50, 0x5e, 0x43, 0xb9, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x94, 0xd7, 0x50, 0x5e, 0x43, 0x79, 0xcd, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] + + rfctest12 = Poly1305 text12 rval12 sval12 + == [0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] + +property allTestsPass = + ([ // Full RFC test vectors + rfctest01, rfctest02, rfctest03, rfctest04, + rfctest05, rfctest06, rfctest07, rfctest08, + rfctest09, rfctest10, rfctest11, rfctest12 + ] : [_]Bit) == ~zero // All test bits should equal one diff --git a/security/nss/automation/saw/poly1305.saw b/security/nss/automation/saw/poly1305.saw new file mode 100644 index 000000000..44be1e3e0 --- /dev/null +++ b/security/nss/automation/saw/poly1305.saw @@ -0,0 +1,47 @@ +// 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/. + +import "poly1305.cry" as poly1305; + +print "Proving Poly1305 spec..."; +prove_print abc {{ poly1305::allTestsPass }}; + +print "Loading LLVM bitcode..."; +m <- llvm_load_module "../../../dist/Debug/lib/libfreeblpriv3.so.bc"; + +let SpecPoly1305 n = do { + llvm_ptr "out" (llvm_array 16 (llvm_int 8)); + out <- llvm_var "*out" (llvm_array 16 (llvm_int 8)); + + llvm_ptr "ad" (llvm_array 16 (llvm_int 8)); + ad <- llvm_var "*ad" (llvm_array 16 (llvm_int 8)); + + adLen <- llvm_var "adLen" (llvm_int 32); + + llvm_ptr "ciphertext" (llvm_array n (llvm_int 8)); + ciphertext <- llvm_var "*ciphertext" (llvm_array n (llvm_int 8)); + + ciphertextLen <- llvm_var "ciphertextLen" (llvm_int 32); + + llvm_ptr "key" (llvm_array 32 (llvm_int 8)); + key <- llvm_var "*key" (llvm_array 32 (llvm_int 8)); + + llvm_assert_eq "*ad" {{ zero : [16][8] }}; + llvm_assert_eq "adLen" {{ 16 : [32] }}; + + llvm_assert_eq "*ciphertext" {{ zero : [n][8] }}; + llvm_assert_eq "ciphertextLen" {{ `n : [32] }}; + + llvm_assert_eq "*key" {{ zero : [32][8] }}; + + let res = {{ poly1305::Poly1305 (ad # ciphertext # [16, 0, 0, 0, 0, 0, 0, 0] # [`n, 0, 0, 0, 0, 0, 0, 0]) (take`{16} key) (drop`{16} key) }}; + llvm_ensure_eq "*out" {{ res }}; + + llvm_verify_tactic abc; +}; + +print "Proving equality for a single block..."; +// This is currently disabled as it takes way too long. We need to help Z3 +// prove this before we can enable it on Taskcluster. +//time (llvm_verify m "Poly1305Do" [] (SpecPoly1305 16)); diff --git a/security/nss/automation/taskcluster/docker-clang-3.9/setup.sh b/security/nss/automation/taskcluster/docker-clang-3.9/setup.sh index 7b7d534e6..3076667a6 100644 --- a/security/nss/automation/taskcluster/docker-clang-3.9/setup.sh +++ b/security/nss/automation/taskcluster/docker-clang-3.9/setup.sh @@ -25,8 +25,8 @@ apt-get -y update apt-get install -y --no-install-recommends ${apt_packages[@]} # Download clang. -curl -LO http://releases.llvm.org/3.9.1/clang+llvm-3.9.1-x86_64-linux-gnu-ubuntu-16.04.tar.xz -curl -LO http://releases.llvm.org/3.9.1/clang+llvm-3.9.1-x86_64-linux-gnu-ubuntu-16.04.tar.xz.sig +curl -LO https://releases.llvm.org/3.9.1/clang+llvm-3.9.1-x86_64-linux-gnu-ubuntu-16.04.tar.xz +curl -LO https://releases.llvm.org/3.9.1/clang+llvm-3.9.1-x86_64-linux-gnu-ubuntu-16.04.tar.xz.sig # Verify the signature. gpg --keyserver pool.sks-keyservers.net --recv-keys B6C8F98282B944E3B0D5C2530FC3042E345AD05D gpg --verify *.tar.xz.sig diff --git a/security/nss/automation/taskcluster/docker-decision/Dockerfile b/security/nss/automation/taskcluster/docker-decision/Dockerfile index 35777c0b7..473ce64ba 100644 --- a/security/nss/automation/taskcluster/docker-decision/Dockerfile +++ b/security/nss/automation/taskcluster/docker-decision/Dockerfile @@ -12,6 +12,9 @@ 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/docker-decision/bin/checkout.sh b/security/nss/automation/taskcluster/docker-decision/bin/checkout.sh index 9167f6bda..0cdd2ac40 100644 --- a/security/nss/automation/taskcluster/docker-decision/bin/checkout.sh +++ b/security/nss/automation/taskcluster/docker-decision/bin/checkout.sh @@ -2,11 +2,6 @@ set -v -e -x -if [ $(id -u) = 0 ]; then - # Drop privileges by re-running this script. - exec su worker $0 -fi - # Default values for testing. REVISION=${NSS_HEAD_REVISION:-default} REPOSITORY=${NSS_HEAD_REPOSITORY:-https://hg.mozilla.org/projects/nss} diff --git a/security/nss/automation/taskcluster/docker-gcc-4.4/Dockerfile b/security/nss/automation/taskcluster/docker-gcc-4.4/Dockerfile new file mode 100644 index 000000000..3330c007f --- /dev/null +++ b/security/nss/automation/taskcluster/docker-gcc-4.4/Dockerfile @@ -0,0 +1,30 @@ +FROM ubuntu:14.04 +MAINTAINER Tim Taubert <ttaubert@mozilla.com> + +RUN useradd -d /home/worker -s /bin/bash -m worker +WORKDIR /home/worker + +# Add build and test scripts. +ADD bin /home/worker/bin +RUN chmod +x /home/worker/bin/* + +# Install dependencies. +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 +ENV USER worker +ENV LOGNAME worker +ENV HOSTNAME taskcluster-worker +ENV LANG en_US.UTF-8 +ENV LC_ALL en_US.UTF-8 +ENV HOST localhost +ENV DOMSUF localdomain + +# Set a default command for debugging. +CMD ["/bin/bash", "--login"] diff --git a/security/nss/automation/taskcluster/docker-gcc-4.4/bin/checkout.sh b/security/nss/automation/taskcluster/docker-gcc-4.4/bin/checkout.sh new file mode 100644 index 000000000..9167f6bda --- /dev/null +++ b/security/nss/automation/taskcluster/docker-gcc-4.4/bin/checkout.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +set -v -e -x + +if [ $(id -u) = 0 ]; then + # Drop privileges by re-running this script. + exec su worker $0 +fi + +# Default values for testing. +REVISION=${NSS_HEAD_REVISION:-default} +REPOSITORY=${NSS_HEAD_REPOSITORY:-https://hg.mozilla.org/projects/nss} + +# Clone NSS. +for i in 0 2 5; do + sleep $i + hg clone -r $REVISION $REPOSITORY nss && exit 0 + rm -rf nss +done +exit 1 diff --git a/security/nss/automation/taskcluster/docker-gcc-4.4/setup.sh b/security/nss/automation/taskcluster/docker-gcc-4.4/setup.sh new file mode 100644 index 000000000..f6325d966 --- /dev/null +++ b/security/nss/automation/taskcluster/docker-gcc-4.4/setup.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash + +set -v -e -x + +# Update packages. +export DEBIAN_FRONTEND=noninteractive +apt-get -y update && apt-get -y upgrade + +apt_packages=() +apt_packages+=('ca-certificates') +apt_packages+=('g++-4.4') +apt_packages+=('gcc-4.4') +apt_packages+=('locales') +apt_packages+=('make') +apt_packages+=('mercurial') +apt_packages+=('zlib1g-dev') + +# Install packages. +apt-get -y update +apt-get install -y --no-install-recommends ${apt_packages[@]} + +locale-gen en_US.UTF-8 +dpkg-reconfigure locales + +# Cleanup. +rm -rf ~/.ccache ~/.cache +apt-get autoremove -y +apt-get clean +apt-get autoclean +rm $0 diff --git a/security/nss/automation/taskcluster/docker-hacl/Dockerfile b/security/nss/automation/taskcluster/docker-hacl/Dockerfile new file mode 100644 index 000000000..63f9a24e2 --- /dev/null +++ b/security/nss/automation/taskcluster/docker-hacl/Dockerfile @@ -0,0 +1,30 @@ +FROM ubuntu:xenial + +MAINTAINER Franziskus Kiefer <franziskuskiefer@gmail.com> +# Based on the HACL* image from Benjamin Beurdouche and +# 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 + +# Define versions of dependencies +ENV opamv 4.04.2 +ENV haclversion 668d6cf274c33bbe2e951e3a84b73f2b6442a51f + +# Install required packages and set versions +ADD setup.sh /tmp/setup.sh +RUN bash /tmp/setup.sh + +# Create user, add scripts. +RUN useradd -ms /bin/bash worker +WORKDIR /home/worker +ADD bin /home/worker/bin +RUN chmod +x /home/worker/bin/* +USER worker + +# Build F*, HACL*, verify. Install a few more dependencies. +ENV OPAMYES true +ENV PATH "/home/worker/hacl-star/dependencies/z3/bin:$PATH" +ADD setup-user.sh /tmp/setup-user.sh +ADD license.txt /tmp/license.txt +RUN bash /tmp/setup-user.sh diff --git a/security/nss/automation/taskcluster/docker-hacl/bin/checkout.sh b/security/nss/automation/taskcluster/docker-hacl/bin/checkout.sh new file mode 100644 index 000000000..9167f6bda --- /dev/null +++ b/security/nss/automation/taskcluster/docker-hacl/bin/checkout.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +set -v -e -x + +if [ $(id -u) = 0 ]; then + # Drop privileges by re-running this script. + exec su worker $0 +fi + +# Default values for testing. +REVISION=${NSS_HEAD_REVISION:-default} +REPOSITORY=${NSS_HEAD_REPOSITORY:-https://hg.mozilla.org/projects/nss} + +# Clone NSS. +for i in 0 2 5; do + sleep $i + hg clone -r $REVISION $REPOSITORY nss && exit 0 + rm -rf nss +done +exit 1 diff --git a/security/nss/automation/taskcluster/docker-hacl/license.txt b/security/nss/automation/taskcluster/docker-hacl/license.txt new file mode 100644 index 000000000..03d25c4d3 --- /dev/null +++ b/security/nss/automation/taskcluster/docker-hacl/license.txt @@ -0,0 +1,15 @@ +/* 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. + */ + diff --git a/security/nss/automation/taskcluster/docker-hacl/setup-user.sh b/security/nss/automation/taskcluster/docker-hacl/setup-user.sh new file mode 100644 index 000000000..b8accaf58 --- /dev/null +++ b/security/nss/automation/taskcluster/docker-hacl/setup-user.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash + +set -v -e -x + +# Prepare build (OCaml packages) +opam init +echo ". /home/worker/.opam/opam-init/init.sh > /dev/null 2> /dev/null || true" >> .bashrc +opam switch -v ${opamv} +opam install ocamlfind batteries sqlite3 fileutils yojson ppx_deriving_yojson zarith pprint menhir ulex process fix wasm stdint + +# Get the HACL* code +git clone ${haclrepo} hacl-star +git -C hacl-star checkout ${haclversion} + +# Prepare submodules, and build, verify, test, and extract c code +# 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) +make -C hacl-star/code/poly1305 test -j$(nproc) + +# Cleanup. +rm -rf ~/.ccache ~/.cache diff --git a/security/nss/automation/taskcluster/docker-hacl/setup.sh b/security/nss/automation/taskcluster/docker-hacl/setup.sh new file mode 100644 index 000000000..f5f8bd7d5 --- /dev/null +++ b/security/nss/automation/taskcluster/docker-hacl/setup.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash + +set -v -e -x + +# Update packages. +export DEBIAN_FRONTEND=noninteractive +apt-get -qq update +apt-get install --yes libssl-dev libsqlite3-dev g++-5 gcc-5 m4 make opam pkg-config python libgmp3-dev cmake curl libtool-bin autoconf wget locales +update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-5 200 +update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-5 200 + +# Get clang-format-3.9 +curl -LO https://releases.llvm.org/3.9.1/clang+llvm-3.9.1-x86_64-linux-gnu-ubuntu-16.04.tar.xz +curl -LO https://releases.llvm.org/3.9.1/clang+llvm-3.9.1-x86_64-linux-gnu-ubuntu-16.04.tar.xz.sig +# Verify the signature. +gpg --keyserver pool.sks-keyservers.net --recv-keys B6C8F98282B944E3B0D5C2530FC3042E345AD05D +gpg --verify *.tar.xz.sig +# Install into /usr/local/. +tar xJvf *.tar.xz -C /usr/local --strip-components=1 +# Cleanup. +rm *.tar.xz* + +locale-gen en_US.UTF-8 +dpkg-reconfigure locales + +# Cleanup. +rm -rf ~/.ccache ~/.cache +apt-get autoremove -y +apt-get clean +apt-get autoclean diff --git a/security/nss/automation/taskcluster/docker-saw/Dockerfile b/security/nss/automation/taskcluster/docker-saw/Dockerfile new file mode 100644 index 000000000..a481ba048 --- /dev/null +++ b/security/nss/automation/taskcluster/docker-saw/Dockerfile @@ -0,0 +1,46 @@ +FROM ubuntu:latest +MAINTAINER Tim Taubert <ttaubert@mozilla.com> + +RUN useradd -d /home/worker -s /bin/bash -m worker +WORKDIR /home/worker + +ENV DEBIAN_FRONTEND noninteractive + +RUN apt-get update && apt-get install -y \ + binutils \ + build-essential \ + bzip2 \ + clang-3.8 \ + curl \ + gcc-multilib \ + g++-multilib \ + gyp \ + lib32z1-dev \ + mercurial \ + ninja-build \ + unzip \ + zlib1g-dev + +# Add missing LLVM plugin for gold linker. +ADD LLVMgold.so.zip /usr/lib/llvm-3.8/lib/LLVMgold.so.zip +RUN unzip /usr/lib/llvm-3.8/lib/LLVMgold.so.zip -d /usr/lib/llvm-3.8/lib/ + +# Install SAW/Cryptol. +RUN curl -LO https://saw.galois.com/builds/nightly/saw-0.2-2018-01-14-Ubuntu14.04-64.tar.gz && \ + tar xzvf saw-*.tar.gz -C /usr/local --strip-components=1 && \ + rm saw-*.tar.gz + +# Install Z3. +RUN curl -LO https://github.com/Z3Prover/z3/releases/download/z3-4.6.0/z3-4.6.0-x64-ubuntu-16.04.zip && \ + unzip z3*.zip && \ + cp -r z3*/* /usr/local/ && \ + rm -fr z3* + +ADD bin /home/worker/bin +RUN chmod +x /home/worker/bin/* + +# Change user. +USER worker + +# Set a default command useful for debugging +CMD ["/bin/bash", "--login"] diff --git a/security/nss/automation/taskcluster/docker-saw/LLVMgold.so.zip b/security/nss/automation/taskcluster/docker-saw/LLVMgold.so.zip Binary files differnew file mode 100644 index 000000000..b5e5a593d --- /dev/null +++ b/security/nss/automation/taskcluster/docker-saw/LLVMgold.so.zip diff --git a/security/nss/automation/taskcluster/docker-saw/bin/checkout.sh b/security/nss/automation/taskcluster/docker-saw/bin/checkout.sh new file mode 100644 index 000000000..0cdd2ac40 --- /dev/null +++ b/security/nss/automation/taskcluster/docker-saw/bin/checkout.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +set -v -e -x + +# Default values for testing. +REVISION=${NSS_HEAD_REVISION:-default} +REPOSITORY=${NSS_HEAD_REPOSITORY:-https://hg.mozilla.org/projects/nss} + +# Clone NSS. +for i in 0 2 5; do + sleep $i + hg clone -r $REVISION $REPOSITORY nss && exit 0 + rm -rf nss +done +exit 1 diff --git a/security/nss/automation/taskcluster/docker/setup.sh b/security/nss/automation/taskcluster/docker/setup.sh index 3ba4e854e..7b90b2e69 100644 --- a/security/nss/automation/taskcluster/docker/setup.sh +++ b/security/nss/automation/taskcluster/docker/setup.sh @@ -12,6 +12,7 @@ apt-get install -y --no-install-recommends apt-utils apt_packages=() apt_packages+=('build-essential') apt_packages+=('ca-certificates') +apt_packages+=('clang-5.0') apt_packages+=('curl') apt_packages+=('npm') apt_packages+=('git') @@ -47,16 +48,17 @@ echo "deb http://ppa.launchpad.net/ubuntu-toolchain-r/test/ubuntu xenial main" > apt-get -y update apt-get install -y --no-install-recommends ${apt_packages[@]} -# Download clang. -curl -LO http://releases.llvm.org/4.0.0/clang+llvm-4.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz -curl -LO http://releases.llvm.org/4.0.0/clang+llvm-4.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz.sig -# Verify the signature. -gpg --keyserver pool.sks-keyservers.net --recv-keys B6C8F98282B944E3B0D5C2530FC3042E345AD05D -gpg --verify *.tar.xz.sig -# Install into /usr/local/. -tar xJvf *.tar.xz -C /usr/local --strip-components=1 -# Cleanup. -rm *.tar.xz* +# Latest version of abigail-tools +apt-get install -y libxml2-dev autoconf libelf-dev libdw-dev libtool +git clone git://sourceware.org/git/libabigail.git +cd ./libabigail +autoreconf -fi +./configure --prefix=/usr --disable-static --disable-apidoc --disable-manual +make +make install +cd .. +apt-get remove -y libxml2-dev autoconf libtool +rm -rf libabigail # Install latest Rust (stable). su worker -c "curl https://sh.rustup.rs -sSf | sh -s -- -y" diff --git a/security/nss/automation/taskcluster/graph/src/context_hash.js b/security/nss/automation/taskcluster/graph/src/context_hash.js index f0a2e9a88..0699a0590 100644 --- a/security/nss/automation/taskcluster/graph/src/context_hash.js +++ b/security/nss/automation/taskcluster/graph/src/context_hash.js @@ -27,14 +27,24 @@ function collectFilesInDirectory(dir) { }); } -// Compute a context hash for the given context path. -export default function (context_path) { +// A list of hashes for each file in the given path. +function collectFileHashes(context_path) { let root = path.join(__dirname, "../../../.."); let dir = path.join(root, context_path); let files = collectFilesInDirectory(dir).sort(); - let hashes = files.map(file => { + + return files.map(file => { return sha256(file + "|" + fs.readFileSync(file, "utf-8")); }); +} + +// Compute a context hash for the given context path. +export default function (context_path) { + // Regenerate all images when the image_builder changes. + let hashes = collectFileHashes("automation/taskcluster/image_builder"); + + // Regenerate images when the image itself changes. + hashes = hashes.concat(collectFileHashes(context_path)); // Generate a new prefix every month to ensure the image stays buildable. let now = new Date(); diff --git a/security/nss/automation/taskcluster/graph/src/extend.js b/security/nss/automation/taskcluster/graph/src/extend.js index d541a1a3b..ee9ac9b74 100644 --- a/security/nss/automation/taskcluster/graph/src/extend.js +++ b/security/nss/automation/taskcluster/graph/src/extend.js @@ -15,15 +15,34 @@ const LINUX_CLANG39_IMAGE = { path: "automation/taskcluster/docker-clang-3.9" }; +const LINUX_GCC44_IMAGE = { + name: "linux-gcc-4.4", + path: "automation/taskcluster/docker-gcc-4.4" +}; + const FUZZ_IMAGE = { name: "fuzz", path: "automation/taskcluster/docker-fuzz" }; +const HACL_GEN_IMAGE = { + name: "hacl", + path: "automation/taskcluster/docker-hacl" +}; + +const SAW_IMAGE = { + name: "saw", + path: "automation/taskcluster/docker-saw" +}; + const WINDOWS_CHECKOUT_CMD = "bash -c \"hg clone -r $NSS_HEAD_REVISION $NSS_HEAD_REPOSITORY nss || " + "(sleep 2; hg clone -r $NSS_HEAD_REVISION $NSS_HEAD_REPOSITORY nss) || " + "(sleep 5; hg clone -r $NSS_HEAD_REVISION $NSS_HEAD_REPOSITORY nss)\""; +const MAC_CHECKOUT_CMD = ["bash", "-c", + "hg clone -r $NSS_HEAD_REVISION $NSS_HEAD_REPOSITORY nss || " + + "(sleep 2; hg clone -r $NSS_HEAD_REVISION $NSS_HEAD_REPOSITORY nss) || " + + "(sleep 5; hg clone -r $NSS_HEAD_REVISION $NSS_HEAD_REPOSITORY nss)"]; /*****************************************************************************/ @@ -51,6 +70,16 @@ queue.filter(task => { if (task.platform == "aarch64") { return false; } + + // No mac + if (task.platform == "mac") { + return false; + } + } + + if (task.tests == "fips" && + (task.platform == "mac" || task.platform == "aarch64")) { + return false; } // Only old make builds have -Ddisable_libpkix=0 and can run chain tests. @@ -59,13 +88,13 @@ queue.filter(task => { } if (task.group == "Test") { - // Don't run test builds on old make platforms - if (task.collection == "make") { + // Don't run test builds on old make platforms, and not for fips gyp. + if (task.collection == "make" || task.collection == "fips") { return false; } } - // Don't run additional hardware tests on ARM (we don't have anything there). + // Don't run all additional hardware tests on ARM. if (task.group == "Cipher" && task.platform == "aarch64" && task.env && (task.env.NSS_DISABLE_PCLMUL == "1" || task.env.NSS_DISABLE_HW_AES == "1" || task.env.NSS_DISABLE_AVX == "1")) { @@ -78,11 +107,19 @@ queue.filter(task => { queue.map(task => { if (task.collection == "asan") { // CRMF and FIPS tests still leak, unfortunately. - if (task.tests == "crmf" || task.tests == "fips") { + if (task.tests == "crmf") { task.env.ASAN_OPTIONS = "detect_leaks=0"; } } + // We don't run FIPS SSL tests + if (task.tests == "ssl") { + if (!task.env) { + task.env = {}; + } + task.env.NSS_SSL_TESTS = "crl iopr policy"; + } + // Windows is slow. if (task.platform == "windows2012-64" && task.tests == "chains") { task.maxRunTime = 7200; @@ -128,6 +165,18 @@ export default async function main() { ], }); + await scheduleLinux("Linux 64 (opt, make)", { + env: {USE_64: "1", BUILD_OPT: "1"}, + platform: "linux64", + image: LINUX_IMAGE, + collection: "make", + command: [ + "/bin/bash", + "-c", + "bin/checkout.sh && nss/automation/taskcluster/scripts/build.sh" + ], + }); + await scheduleLinux("Linux 32 (debug, make)", { platform: "linux32", image: LINUX_IMAGE, @@ -144,8 +193,8 @@ export default async function main() { UBSAN_OPTIONS: "print_stacktrace=1", NSS_DISABLE_ARENA_FREE_LIST: "1", NSS_DISABLE_UNLOAD: "1", - CC: "clang", - CCC: "clang++", + CC: "clang-5.0", + CCC: "clang++-5.0", }, platform: "linux64", collection: "asan", @@ -153,6 +202,12 @@ export default async function main() { features: ["allowPtrace"], }, "--ubsan --asan"); + await scheduleLinux("Linux 64 (FIPS opt)", { + platform: "linux64", + collection: "fips", + image: LINUX_IMAGE, + }, "--enable-fips --opt"); + await scheduleWindows("Windows 2012 64 (debug, make)", { platform: "windows2012-64", collection: "make", @@ -216,6 +271,82 @@ export default async function main() { collection: "opt", }, aarch64_base) ); + + await scheduleLinux("Linux AArch64 (debug, make)", + merge({ + env: {USE_64: "1"}, + command: [ + "/bin/bash", + "-c", + "bin/checkout.sh && nss/automation/taskcluster/scripts/build.sh" + ], + collection: "make", + }, aarch64_base) + ); + + await scheduleMac("Mac (opt)", {collection: "opt"}, "--opt"); + await scheduleMac("Mac (debug)", {collection: "debug"}); +} + + +async function scheduleMac(name, base, args = "") { + let mac_base = merge(base, { + env: { + PATH: "/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin", + NSS_TASKCLUSTER_MAC: "1", + DOMSUF: "localdomain", + HOST: "localhost", + }, + provisioner: "localprovisioner", + workerType: "nss-macos-10-12", + platform: "mac" + }); + + // Build base definition. + let build_base = merge({ + command: [ + MAC_CHECKOUT_CMD, + ["bash", "-c", + "nss/automation/taskcluster/scripts/build_gyp.sh", args] + ], + provisioner: "localprovisioner", + workerType: "nss-macos-10-12", + platform: "mac", + maxRunTime: 7200, + artifacts: [{ + expires: 24 * 7, + type: "directory", + path: "public" + }], + kind: "build", + symbol: "B" + }, mac_base); + + // The task that builds NSPR+NSS. + let task_build = queue.scheduleTask(merge(build_base, {name})); + + // The task that generates certificates. + let task_cert = queue.scheduleTask(merge(build_base, { + name: "Certificates", + command: [ + MAC_CHECKOUT_CMD, + ["bash", "-c", + "nss/automation/taskcluster/scripts/gen_certs.sh"] + ], + parent: task_build, + symbol: "Certs" + })); + + // Schedule tests. + scheduleTests(task_build, task_cert, merge(mac_base, { + command: [ + MAC_CHECKOUT_CMD, + ["bash", "-c", + "nss/automation/taskcluster/scripts/run_tests.sh"] + ] + })); + + return queue.submit(); } /*****************************************************************************/ @@ -242,6 +373,45 @@ async function scheduleLinux(name, base, args = "") { // The task that builds NSPR+NSS. let task_build = queue.scheduleTask(merge(build_base, {name})); + // Make builds run FIPS tests, which need an extra FIPS build. + if (base.collection == "make") { + let extra_build = queue.scheduleTask(merge(build_base, { + env: { NSS_FORCE_FIPS: "1" }, + group: "FIPS", + name: `${name} w/ NSS_FORCE_FIPS` + })); + + // The task that generates certificates. + let task_cert = queue.scheduleTask(merge(build_base, { + name: "Certificates", + command: [ + "/bin/bash", + "-c", + "bin/checkout.sh && nss/automation/taskcluster/scripts/gen_certs.sh" + ], + parent: extra_build, + symbol: "Certs-F", + group: "FIPS", + })); + + // Schedule FIPS tests. + queue.scheduleTask(merge(base, { + parent: task_cert, + name: "FIPS", + command: [ + "/bin/bash", + "-c", + "bin/checkout.sh && nss/automation/taskcluster/scripts/run_tests.sh" + ], + cycle: "standard", + kind: "test", + name: "FIPS tests", + symbol: "Tests-F", + tests: "fips", + group: "FIPS" + })); + } + // The task that generates certificates. let task_cert = queue.scheduleTask(merge(build_base, { name: "Certificates", @@ -266,12 +436,32 @@ async function scheduleLinux(name, base, args = "") { // Extra builds. let extra_base = merge({group: "Builds"}, build_base); queue.scheduleTask(merge(extra_base, { - name: `${name} w/ clang-4.0`, + name: `${name} w/ clang-5.0`, env: { - CC: "clang", - CCC: "clang++", + CC: "clang-5.0", + CCC: "clang++-5.0", }, - symbol: "clang-4.0" + symbol: "clang-5.0" + })); + + queue.scheduleTask(merge(extra_base, { + name: `${name} w/ gcc-4.4`, + image: LINUX_GCC44_IMAGE, + env: { + USE_64: "1", + CC: "gcc-4.4", + CCC: "g++-4.4", + // gcc-4.6 introduced nullptr. + NSS_DISABLE_GTESTS: "1", + }, + // Use the old Makefile-based build system, GYP doesn't have a proper GCC + // version check for __int128 support. It's mainly meant to cover RHEL6. + command: [ + "/bin/bash", + "-c", + "bin/checkout.sh && nss/automation/taskcluster/scripts/build.sh", + ], + symbol: "gcc-4.4" })); queue.scheduleTask(merge(extra_base, { @@ -403,12 +593,13 @@ async function scheduleFuzzing() { // Schedule MPI fuzzing runs. let mpi_base = merge(run_base, {group: "MPI"}); - let mpi_names = ["add", "addmod", "div", "expmod", "mod", "mulmod", "sqr", + let mpi_names = ["add", "addmod", "div", "mod", "mulmod", "sqr", "sqrmod", "sub", "submod"]; for (let name of mpi_names) { scheduleFuzzingRun(mpi_base, `MPI (${name})`, `mpi-${name}`, 4096, name); } scheduleFuzzingRun(mpi_base, `MPI (invmod)`, `mpi-invmod`, 256, "invmod"); + scheduleFuzzingRun(mpi_base, `MPI (expmod)`, `mpi-expmod`, 2048, "expmod"); // Schedule TLS fuzzing runs (non-fuzzing mode). let tls_base = merge(run_base, {group: "TLS"}); @@ -625,6 +816,43 @@ async function scheduleWindows(name, base, build_script) { symbol: "B" }); + // Make builds run FIPS tests, which need an extra FIPS build. + if (base.collection == "make") { + let extra_build = queue.scheduleTask(merge(build_base, { + env: { NSS_FORCE_FIPS: "1" }, + group: "FIPS", + name: `${name} w/ NSS_FORCE_FIPS` + })); + + // The task that generates certificates. + let task_cert = queue.scheduleTask(merge(build_base, { + name: "Certificates", + command: [ + WINDOWS_CHECKOUT_CMD, + "bash -c nss/automation/taskcluster/windows/gen_certs.sh" + ], + parent: extra_build, + symbol: "Certs-F", + group: "FIPS", + })); + + // Schedule FIPS tests. + queue.scheduleTask(merge(base, { + parent: task_cert, + name: "FIPS", + command: [ + WINDOWS_CHECKOUT_CMD, + "bash -c nss/automation/taskcluster/windows/run_tests.sh" + ], + cycle: "standard", + kind: "test", + name: "FIPS tests", + symbol: "Tests-F", + tests: "fips", + group: "FIPS" + })); + } + // The task that builds NSPR+NSS. let task_build = queue.scheduleTask(merge(build_base, {name})); @@ -685,6 +913,13 @@ function scheduleTests(task_build, task_cert, test_base) { env: {NSS_DISABLE_AVX: "1"}, group: "Cipher" })); queue.scheduleTask(merge(no_cert_base, { + name: "Cipher tests", symbol: "NoSSSE3|NEON", tests: "cipher", + env: { + NSS_DISABLE_ARM_NEON: "1", + NSS_DISABLE_SSSE3: "1" + }, group: "Cipher" + })); + queue.scheduleTask(merge(no_cert_base, { name: "EC tests", symbol: "EC", tests: "ec" })); queue.scheduleTask(merge(no_cert_base, { @@ -703,9 +938,6 @@ function scheduleTests(task_build, task_cert, test_base) { name: "DB tests", symbol: "DB", tests: "dbtests" })); queue.scheduleTask(merge(cert_base, { - name: "FIPS tests", symbol: "FIPS", tests: "fips" - })); - queue.scheduleTask(merge(cert_base, { name: "Merge tests", symbol: "Merge", tests: "merge" })); queue.scheduleTask(merge(cert_base, { @@ -739,6 +971,18 @@ async function scheduleTools() { kind: "test" }; + //ABI check task + queue.scheduleTask(merge(base, { + symbol: "abi", + name: "abi", + image: LINUX_IMAGE, + command: [ + "/bin/bash", + "-c", + "bin/checkout.sh && nss/automation/taskcluster/scripts/check_abi.sh" + ], + })); + queue.scheduleTask(merge(base, { symbol: "clang-format-3.9", name: "clang-format-3.9", @@ -751,13 +995,13 @@ async function scheduleTools() { })); queue.scheduleTask(merge(base, { - symbol: "scan-build-4.0", - name: "scan-build-4.0", + symbol: "scan-build-5.0", + name: "scan-build-5.0", image: LINUX_IMAGE, env: { USE_64: "1", - CC: "clang", - CCC: "clang++", + CC: "clang-5.0", + CCC: "clang++-5.0", }, artifacts: { public: { @@ -773,5 +1017,80 @@ async function scheduleTools() { ] })); + queue.scheduleTask(merge(base, { + symbol: "hacl", + name: "hacl", + image: HACL_GEN_IMAGE, + command: [ + "/bin/bash", + "-c", + "bin/checkout.sh && nss/automation/taskcluster/scripts/run_hacl.sh" + ] + })); + + let task_saw = queue.scheduleTask(merge(base, { + symbol: "B", + group: "SAW", + name: "LLVM bitcode build (32 bit)", + image: SAW_IMAGE, + kind: "build", + env: { + AR: "llvm-ar-3.8", + CC: "clang-3.8", + CCC: "clang++-3.8" + }, + artifacts: { + public: { + expires: 24 * 7, + type: "directory", + path: "/home/worker/artifacts" + } + }, + command: [ + "/bin/bash", + "-c", + "bin/checkout.sh && nss/automation/taskcluster/scripts/build_gyp.sh --disable-tests --emit-llvm -m32" + ] + })); + + queue.scheduleTask(merge(base, { + parent: task_saw, + symbol: "bmul", + group: "SAW", + name: "bmul.saw", + image: SAW_IMAGE, + command: [ + "/bin/bash", + "-c", + "bin/checkout.sh && nss/automation/taskcluster/scripts/run_saw.sh bmul" + ] + })); + + queue.scheduleTask(merge(base, { + parent: task_saw, + symbol: "ChaCha20", + group: "SAW", + name: "chacha20.saw", + image: SAW_IMAGE, + command: [ + "/bin/bash", + "-c", + "bin/checkout.sh && nss/automation/taskcluster/scripts/run_saw.sh chacha20" + ] + })); + + queue.scheduleTask(merge(base, { + parent: task_saw, + symbol: "Poly1305", + group: "SAW", + name: "poly1305.saw", + image: SAW_IMAGE, + command: [ + "/bin/bash", + "-c", + "bin/checkout.sh && nss/automation/taskcluster/scripts/run_saw.sh poly1305" + ] + })); + return queue.submit(); } diff --git a/security/nss/automation/taskcluster/graph/src/image_builder.js b/security/nss/automation/taskcluster/graph/src/image_builder.js index bc90e0242..d9d7755dc 100644 --- a/security/nss/automation/taskcluster/graph/src/image_builder.js +++ b/security/nss/automation/taskcluster/graph/src/image_builder.js @@ -30,14 +30,12 @@ export async function buildTask({name, path}) { let ns = `docker.images.v1.${process.env.TC_PROJECT}.${name}.hash.${hash}`; return { - name: "Image Builder", - image: "taskcluster/image_builder:0.1.5", + name: `Image Builder (${name})`, + image: "nssdev/image_builder:0.1.5", routes: ["index." + ns], env: { - HEAD_REPOSITORY: process.env.NSS_HEAD_REPOSITORY, - BASE_REPOSITORY: process.env.NSS_HEAD_REPOSITORY, - HEAD_REV: process.env.NSS_HEAD_REVISION, - HEAD_REF: process.env.NSS_HEAD_REVISION, + NSS_HEAD_REPOSITORY: process.env.NSS_HEAD_REPOSITORY, + NSS_HEAD_REVISION: process.env.NSS_HEAD_REVISION, PROJECT: process.env.TC_PROJECT, CONTEXT_PATH: path, HASH: hash @@ -52,10 +50,11 @@ export async function buildTask({name, path}) { command: [ "/bin/bash", "-c", - "/home/worker/bin/build_image.sh" + "bin/checkout.sh && nss/automation/taskcluster/scripts/build_image.sh" ], platform: "nss-decision", features: ["dind"], + maxRunTime: 7200, kind: "build", symbol: "I" }; diff --git a/security/nss/automation/taskcluster/graph/src/queue.js b/security/nss/automation/taskcluster/graph/src/queue.js index 29b570729..809a17bf1 100644 --- a/security/nss/automation/taskcluster/graph/src/queue.js +++ b/security/nss/automation/taskcluster/graph/src/queue.js @@ -31,10 +31,11 @@ function parseRoutes(routes) { ]; // Notify about failures (except on try). - if (process.env.TC_PROJECT != "nss-try") { + // Turned off, too noisy. + /*if (process.env.TC_PROJECT != "nss-try") { rv.push(`notify.email.${process.env.TC_OWNER}.on-failed`, `notify.email.${process.env.TC_OWNER}.on-exception`); - } + }*/ return rv; } diff --git a/security/nss/automation/taskcluster/graph/src/try_syntax.js b/security/nss/automation/taskcluster/graph/src/try_syntax.js index 7748e068a..1c06dde13 100644 --- a/security/nss/automation/taskcluster/graph/src/try_syntax.js +++ b/security/nss/automation/taskcluster/graph/src/try_syntax.js @@ -22,10 +22,10 @@ function parseOptions(opts) { } // Parse platforms. - let allPlatforms = ["linux", "linux64", "linux64-asan", + let allPlatforms = ["linux", "linux64", "linux64-asan", "linux64-fips", "win", "win64", "win-make", "win64-make", "linux64-make", "linux-make", "linux-fuzz", - "linux64-fuzz", "aarch64"]; + "linux64-fuzz", "aarch64", "mac"]; let platforms = intersect(opts.platform.split(/\s*,\s*/), allPlatforms); // If the given value is nonsense or "none" default to all platforms. @@ -51,7 +51,7 @@ function parseOptions(opts) { } // Parse tools. - let allTools = ["clang-format", "scan-build"]; + let allTools = ["clang-format", "scan-build", "hacl", "saw", "abi"]; let tools = intersect(opts.tools.split(/\s*,\s*/), allTools); // If the given value is "all" run all tools. @@ -77,7 +77,8 @@ function filter(opts) { // are not affected by platform or build type selectors. if (task.platform == "nss-tools") { return opts.tools.some(tool => { - return task.symbol.toLowerCase().startsWith(tool); + return task.symbol.toLowerCase().startsWith(tool) || + (task.group && task.group.toLowerCase().startsWith(tool)); }); } @@ -111,6 +112,7 @@ function filter(opts) { "linux": "linux32", "linux-fuzz": "linux32", "linux64-asan": "linux64", + "linux64-fips": "linux64", "linux64-fuzz": "linux64", "linux64-make": "linux64", "linux-make": "linux32", @@ -126,6 +128,8 @@ function filter(opts) { // Additional checks. if (platform == "linux64-asan") { keep &= coll("asan"); + } else if (platform == "linux64-fips") { + keep &= coll("fips"); } else if (platform == "linux64-make" || platform == "linux-make" || platform == "win64-make" || platform == "win-make") { keep &= coll("make"); diff --git a/security/nss/automation/taskcluster/image_builder/Dockerfile b/security/nss/automation/taskcluster/image_builder/Dockerfile new file mode 100644 index 000000000..f8b4edcc5 --- /dev/null +++ b/security/nss/automation/taskcluster/image_builder/Dockerfile @@ -0,0 +1,23 @@ +FROM ubuntu:16.04 +MAINTAINER Tim Taubert <ttaubert@mozilla.com> + +WORKDIR /home/worker + +ENV DEBIAN_FRONTEND noninteractive + +RUN apt-get update && apt-get install -y apt-transport-https apt-utils +RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 36A1D7869245C8950F966E92D8576A8BA88D21E9 && \ + sh -c "echo deb https://get.docker.io/ubuntu docker main \ + > /etc/apt/sources.list.d/docker.list" +RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 41BD8711B1F0EC2B0D85B91CF59CE3A8323293EE && \ + sh -c "echo deb http://ppa.launchpad.net/mercurial-ppa/releases/ubuntu xenial main \ + > /etc/apt/sources.list.d/mercurial.list" +RUN apt-get update && apt-get install -y \ + lxc-docker-1.6.1 \ + mercurial + +ADD bin /home/worker/bin +RUN chmod +x /home/worker/bin/* + +# Set a default command useful for debugging +CMD ["/bin/bash", "--login"] diff --git a/security/nss/automation/taskcluster/image_builder/VERSION b/security/nss/automation/taskcluster/image_builder/VERSION new file mode 100644 index 000000000..9faa1b7a7 --- /dev/null +++ b/security/nss/automation/taskcluster/image_builder/VERSION @@ -0,0 +1 @@ +0.1.5 diff --git a/security/nss/automation/taskcluster/image_builder/bin/checkout.sh b/security/nss/automation/taskcluster/image_builder/bin/checkout.sh new file mode 100644 index 000000000..0cdd2ac40 --- /dev/null +++ b/security/nss/automation/taskcluster/image_builder/bin/checkout.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +set -v -e -x + +# Default values for testing. +REVISION=${NSS_HEAD_REVISION:-default} +REPOSITORY=${NSS_HEAD_REPOSITORY:-https://hg.mozilla.org/projects/nss} + +# Clone NSS. +for i in 0 2 5; do + sleep $i + hg clone -r $REVISION $REPOSITORY nss && exit 0 + rm -rf nss +done +exit 1 diff --git a/security/nss/automation/taskcluster/scripts/build_gyp.sh b/security/nss/automation/taskcluster/scripts/build_gyp.sh index 7190bd5c4..fb3a33a52 100755 --- a/security/nss/automation/taskcluster/scripts/build_gyp.sh +++ b/security/nss/automation/taskcluster/scripts/build_gyp.sh @@ -9,5 +9,10 @@ hg_clone https://hg.mozilla.org/projects/nspr ./nspr default nss/build.sh -g -v "$@" # Package. -mkdir artifacts -tar cvfjh artifacts/dist.tar.bz2 dist +if [[ $(uname) = "Darwin" ]]; then + mkdir -p public + tar cvfjh public/dist.tar.bz2 dist +else + mkdir artifacts + tar cvfjh artifacts/dist.tar.bz2 dist +fi diff --git a/security/nss/automation/taskcluster/scripts/build_image.sh b/security/nss/automation/taskcluster/scripts/build_image.sh new file mode 100644 index 000000000..b422214e7 --- /dev/null +++ b/security/nss/automation/taskcluster/scripts/build_image.sh @@ -0,0 +1,24 @@ +#!/bin/bash -vex + +set -x -e -v + +# Prefix errors with taskcluster error prefix so that they are parsed by Treeherder +raise_error() { + echo + echo "[taskcluster-image-build:error] $1" + exit 1 +} + +# Ensure that the PROJECT is specified so the image can be indexed +test -n "$PROJECT" || raise_error "Project must be provided." +test -n "$HASH" || raise_error "Context Hash must be provided." + +CONTEXT_PATH=/home/worker/nss/$CONTEXT_PATH + +test -d $CONTEXT_PATH || raise_error "Context Path $CONTEXT_PATH does not exist." +test -f "$CONTEXT_PATH/Dockerfile" || raise_error "Dockerfile must be present in $CONTEXT_PATH." + +docker build -t $PROJECT:$HASH $CONTEXT_PATH + +mkdir /artifacts +docker save $PROJECT:$HASH > /artifacts/image.tar diff --git a/security/nss/automation/taskcluster/scripts/check_abi.sh b/security/nss/automation/taskcluster/scripts/check_abi.sh new file mode 100644 index 000000000..dbc1a476f --- /dev/null +++ b/security/nss/automation/taskcluster/scripts/check_abi.sh @@ -0,0 +1,172 @@ +#! /bin/bash + +set_env() +{ + cd /home/worker + HGDIR=/home/worker + OUTPUTDIR=$(pwd)$(echo "/output") + DATE=$(date "+TB [%Y-%m-%d %H:%M:%S]") + + if [ ! -d "${OUTPUTDIR}" ]; then + echo "Creating output dir" + mkdir "${OUTPUTDIR}" + fi + + if [ ! -d "nspr" ]; then + for i in 0 2 5; do + sleep $i + hg clone -r "default" "https://hg.mozilla.org/projects/nspr" "${HGDIR}/nspr" && break + rm -rf nspr + done + fi + + cd nss + ./build.sh -v -c + cd .. +} + +check_abi() +{ + set_env + set +e #reverses set -e from build.sh to allow possible hg clone failures + if [[ "$1" != --nobuild ]]; then # Start nobuild block + + echo "######## NSS ABI CHECK ########" + echo "######## creating temporary HG clones ########" + + rm -rf ${HGDIR}/baseline + mkdir ${HGDIR}/baseline + BASE_NSS=`cat ${HGDIR}/nss/automation/abi-check/previous-nss-release` #Reads the version number of the last release from the respective file + NSS_CLONE_RESULT=0 + for i in 0 2 5; do + sleep $i + hg clone -u "${BASE_NSS}" "https://hg.mozilla.org/projects/nss" "${HGDIR}/baseline/nss" + if [ $? -eq 0 ]; then + NSS_CLONE_RESULT=0 + break + fi + rm -rf "${HGDIR}/baseline/nss" + NSS_CLONE_RESULT=1 + done + if [ ${NSS_CLONE_RESULT} -ne 0 ]; then + echo "invalid tag in automation/abi-check/previous-nss-release" + return 1 + fi + + BASE_NSPR=NSPR_$(head -1 ${HGDIR}/baseline/nss/automation/release/nspr-version.txt | cut -d . -f 1-2 | tr . _)_BRANCH + hg clone -u "${BASE_NSPR}" "https://hg.mozilla.org/projects/nspr" "${HGDIR}/baseline/nspr" + NSPR_CLONE_RESULT=$? + + if [ ${NSPR_CLONE_RESULT} -ne 0 ]; then + rm -rf "${HGDIR}/baseline/nspr" + for i in 0 2 5; do + sleep $i + hg clone -u "default" "https://hg.mozilla.org/projects/nspr" "${HGDIR}/baseline/nspr" && break + rm -rf "${HGDIR}/baseline/nspr" + done + echo "Nonexisting tag ${BASE_NSPR} derived from ${BASE_NSS} automation/release/nspr-version.txt" + echo "Using default branch instead." + fi + + echo "######## building baseline NSPR/NSS ########" + echo "${HGDIR}/baseline/nss/build.sh" + cd ${HGDIR}/baseline/nss + ./build.sh -v -c + cd ${HGDIR} + else # Else nobuild block + echo "######## using existing baseline NSPR/NSS build ########" + fi # End nobuild block + + set +e #reverses set -e from build.sh to allow abidiff failures + + echo "######## Starting abidiff procedure ########" + abi_diff +} + +#Slightly modified from builbot-slave/build.sh +abi_diff() +{ + ABI_PROBLEM_FOUND=0 + ABI_REPORT=${OUTPUTDIR}/abi-diff.txt + rm -f ${ABI_REPORT} + PREVDIST=${HGDIR}/baseline/dist + NEWDIST=${HGDIR}/dist + ALL_SOs="libfreebl3.so libfreeblpriv3.so libnspr4.so libnss3.so libnssckbi.so libnssdbm3.so libnsssysinit.so libnssutil3.so libplc4.so libplds4.so libsmime3.so libsoftokn3.so libssl3.so" + for SO in ${ALL_SOs}; do + if [ ! -f ${HGDIR}/nss/automation/abi-check/expected-report-$SO.txt ]; then + touch ${HGDIR}/nss/automation/abi-check/expected-report-$SO.txt + fi + abidiff --hd1 $PREVDIST/public/ --hd2 $NEWDIST/public \ + $PREVDIST/*/lib/$SO $NEWDIST/*/lib/$SO \ + > ${HGDIR}/nss/automation/abi-check/new-report-temp$SO.txt + RET=$? + cat ${HGDIR}/nss/automation/abi-check/new-report-temp$SO.txt \ + | grep -v "^Functions changes summary:" \ + | grep -v "^Variables changes summary:" \ + > ${HGDIR}/nss/automation/abi-check/new-report-$SO.txt + rm -f ${HGDIR}/nss/automation/abi-check/new-report-temp$SO.txt + + ABIDIFF_ERROR=$((($RET & 0x01) != 0)) + ABIDIFF_USAGE_ERROR=$((($RET & 0x02) != 0)) + ABIDIFF_ABI_CHANGE=$((($RET & 0x04) != 0)) + ABIDIFF_ABI_INCOMPATIBLE_CHANGE=$((($RET & 0x08) != 0)) + ABIDIFF_UNKNOWN_BIT_SET=$((($RET & 0xf0) != 0)) + + # If abidiff reports an error, or a usage error, or if it sets a result + # bit value this script doesn't know yet about, we'll report failure. + # For ABI changes, we don't yet report an error. We'll compare the + # result report with our whitelist. This allows us to silence changes + # that we're already aware of and have been declared acceptable. + + REPORT_RET_AS_FAILURE=0 + if [ $ABIDIFF_ERROR -ne 0 ]; then + echo "abidiff reported ABIDIFF_ERROR." + REPORT_RET_AS_FAILURE=1 + fi + if [ $ABIDIFF_USAGE_ERROR -ne 0 ]; then + echo "abidiff reported ABIDIFF_USAGE_ERROR." + REPORT_RET_AS_FAILURE=1 + fi + if [ $ABIDIFF_UNKNOWN_BIT_SET -ne 0 ]; then + echo "abidiff reported ABIDIFF_UNKNOWN_BIT_SET." + REPORT_RET_AS_FAILURE=1 + fi + + if [ $ABIDIFF_ABI_CHANGE -ne 0 ]; then + echo "Ignoring abidiff result ABI_CHANGE, instead we'll check for non-whitelisted differences." + fi + if [ $ABIDIFF_ABI_INCOMPATIBLE_CHANGE -ne 0 ]; then + echo "Ignoring abidiff result ABIDIFF_ABI_INCOMPATIBLE_CHANGE, instead we'll check for non-whitelisted differences." + fi + + if [ $REPORT_RET_AS_FAILURE -ne 0 ]; then + ABI_PROBLEM_FOUND=1 + echo "abidiff {$PREVDIST , $NEWDIST} for $SO FAILED with result $RET, or failed writing to ${HGDIR}/nss/automation/abi-check/new-report-$SO.txt" + fi + if [ ! -f ${HGDIR}/nss/automation/abi-check/expected-report-$SO.txt ]; then + ABI_PROBLEM_FOUND=1 + echo "FAILED to access report file: ${HGDIR}/nss/automation/abi-check/expected-report-$SO.txt" + fi + + diff -wB -u ${HGDIR}/nss/automation/abi-check/expected-report-$SO.txt \ + ${HGDIR}/nss/automation/abi-check/new-report-$SO.txt >> ${ABI_REPORT} + if [ ! -f ${ABI_REPORT} ]; then + ABI_PROBLEM_FOUND=1 + echo "FAILED to compare exepcted and new report: ${HGDIR}/nss/automation/abi-check/new-report-$SO.txt" + fi + done + + if [ -s ${ABI_REPORT} ]; then + echo "FAILED: there are new unexpected ABI changes" + cat ${ABI_REPORT} + return 1 + elif [ $ABI_PROBLEM_FOUND -ne 0 ]; then + echo "FAILED: failure executing the ABI checks" + cat ${ABI_REPORT} + return 1 + fi + + return 0 +} + +check_abi $1 diff --git a/security/nss/automation/taskcluster/scripts/gen_certs.sh b/security/nss/automation/taskcluster/scripts/gen_certs.sh index b8d4f60ba..c03db7e9c 100755 --- a/security/nss/automation/taskcluster/scripts/gen_certs.sh +++ b/security/nss/automation/taskcluster/scripts/gen_certs.sh @@ -12,5 +12,10 @@ NSS_TESTS=cert NSS_CYCLES="standard pkix sharedb" $(dirname $0)/run_tests.sh echo 1 > tests_results/security/localhost # Package. -mkdir artifacts -tar cvfjh artifacts/dist.tar.bz2 dist tests_results +if [[ $(uname) = "Darwin" ]]; then + mkdir -p public + tar cvfjh public/dist.tar.bz2 dist tests_results +else + mkdir artifacts + tar cvfjh artifacts/dist.tar.bz2 dist tests_results +fi diff --git a/security/nss/automation/taskcluster/scripts/run_hacl.sh b/security/nss/automation/taskcluster/scripts/run_hacl.sh new file mode 100644 index 000000000..281075eef --- /dev/null +++ b/security/nss/automation/taskcluster/scripts/run_hacl.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash + +if [[ $(id -u) -eq 0 ]]; then + # Drop privileges by re-running this script. + # Note: this mangles arguments, better to avoid running scripts as root. + exec su worker -c "$0 $*" +fi + +set -e -x -v + +# The docker image this is running in has the HACL* and NSS sources. +# 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) + +# Add license header to specs +spec_files=($(find ~/hacl-star/specs -type f -name '*.fst')) +for f in "${spec_files[@]}"; do + cat /tmp/license.txt "$f" > /tmp/tmpfile && mv /tmp/tmpfile "$f" +done + +# Format the extracted C code. +cd ~/hacl-star/snapshots/nss +cp ~/nss/.clang-format . +find . -type f -name '*.[ch]' -exec clang-format -i {} \+ + +# These diff commands will return 1 if there are differences and stop the script. +files=($(find ~/nss/lib/freebl/verified/ -type f -name '*.[ch]')) +for f in "${files[@]}"; do + diff $f $(basename "$f") +done + +# Check that the specs didn't change either. +cd ~/hacl-star/specs +files=($(find ~/nss/lib/freebl/verified/specs -type f)) +for f in "${files[@]}"; do + diff $f $(basename "$f") +done diff --git a/security/nss/automation/taskcluster/scripts/run_saw.sh b/security/nss/automation/taskcluster/scripts/run_saw.sh new file mode 100644 index 000000000..0e9a8224a --- /dev/null +++ b/security/nss/automation/taskcluster/scripts/run_saw.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +source $(dirname "$0")/tools.sh + +# Fetch artifact if needed. +fetch_dist + +# Run SAW. +saw "nss/automation/saw/$1.saw" diff --git a/security/nss/automation/taskcluster/scripts/run_scan_build.sh b/security/nss/automation/taskcluster/scripts/run_scan_build.sh index 4024c226e..014530b42 100755 --- a/security/nss/automation/taskcluster/scripts/run_scan_build.sh +++ b/security/nss/automation/taskcluster/scripts/run_scan_build.sh @@ -34,7 +34,7 @@ for i in "${!scan[@]}"; do done # run scan-build (only building affected directories) -scan-build -o /home/worker/artifacts --use-cc=$CC --use-c++=$CCC make nss_build_all && cd .. +scan-build-5.0 -o /home/worker/artifacts --use-cc=$CC --use-c++=$CCC make nss_build_all && cd .. # print errors we found set +v +x diff --git a/security/nss/automation/taskcluster/scripts/split.sh b/security/nss/automation/taskcluster/scripts/split.sh index 4d18385ec..fded64e1b 100644 --- a/security/nss/automation/taskcluster/scripts/split.sh +++ b/security/nss/automation/taskcluster/scripts/split.sh @@ -23,16 +23,10 @@ split_util() { # Copy everything. cp -R $nssdir $dstdir - # Skip gtests when building. - sed '/^DIRS = /s/ cpputil gtests$//' $nssdir/manifest.mn > $dstdir/manifest.mn-t && mv $dstdir/manifest.mn-t $dstdir/manifest.mn - # Remove subdirectories that we don't want. rm -rf $dstdir/cmd - rm -rf $dstdir/tests rm -rf $dstdir/lib rm -rf $dstdir/automation - rm -rf $dstdir/gtests - rm -rf $dstdir/cpputil rm -rf $dstdir/doc # Start with an empty cmd lib directories to be filled selectively. diff --git a/security/nss/automation/taskcluster/windows/releng.manifest b/security/nss/automation/taskcluster/windows/releng.manifest index 68d2c1d9e..d571c544d 100644 --- a/security/nss/automation/taskcluster/windows/releng.manifest +++ b/security/nss/automation/taskcluster/windows/releng.manifest @@ -1,10 +1,10 @@ [ { - "version": "Visual Studio 2015 Update 3 14.0.25425.01 / SDK 10.0.14393.0", - "size": 326656969, - "digest": "babc414ffc0457d27f5a1ed24a8e4873afbe2f1c1a4075469a27c005e1babc3b2a788f643f825efedff95b79686664c67ec4340ed535487168a3482e68559bc7", + "version": "Visual Studio 2017 15.4.2 / SDK 10.0.15063.0", + "size": 303146863, + "digest": "18700889e6b5e81613b9cf57ce4e0d46a6ee45bb4c5c33bae2604a5275326128775b8a032a1eb178c5db973746d565340c4e36d98375789e1d5bd836ab16ba58", "algorithm": "sha512", - "filename": "vs2015u3.zip", + "filename": "vs2017_15.4.2.zip", "unpack": true }, { diff --git a/security/nss/automation/taskcluster/windows/setup.sh b/security/nss/automation/taskcluster/windows/setup.sh index 7def50db4..36a040ba1 100644 --- a/security/nss/automation/taskcluster/windows/setup.sh +++ b/security/nss/automation/taskcluster/windows/setup.sh @@ -2,12 +2,12 @@ set -v -e -x -export VSPATH="$(pwd)/vs2015u3" +export VSPATH="$(pwd)/vs2017_15.4.2" export NINJA_PATH="$(pwd)/ninja/bin" export WINDOWSSDKDIR="${VSPATH}/SDK" export VS90COMNTOOLS="${VSPATH}/VC" -export INCLUDE="${VSPATH}/VC/include:${VSPATH}/SDK/Include/10.0.14393.0/ucrt:${VSPATH}/SDK/Include/10.0.14393.0/shared:${VSPATH}/SDK/Include/10.0.14393.0/um" +export INCLUDE="${VSPATH}/VC/include:${VSPATH}/SDK/Include/10.0.15063.0/ucrt:${VSPATH}/SDK/Include/10.0.15063.0/shared:${VSPATH}/SDK/Include/10.0.15063.0/um" # Usage: hg_clone repo dir [revision=@] hg_clone() { @@ -23,4 +23,4 @@ hg_clone() { } hg_clone https://hg.mozilla.org/build/tools tools default -tools/scripts/tooltool/tooltool_wrapper.sh $(dirname $0)/releng.manifest https://api.pub.build.mozilla.org/tooltool/ non-existant-file.sh /c/mozilla-build/python/python.exe /c/builds/tooltool.py --authentication-file /c/builds/relengapi.tok -c /c/builds/tooltool_cache +tools/scripts/tooltool/tooltool_wrapper.sh $(dirname $0)/releng.manifest https://tooltool.mozilla-releng.net/ non-existant-file.sh /c/mozilla-build/python/python.exe /c/builds/tooltool.py --authentication-file /c/builds/relengapi.tok -c /c/builds/tooltool_cache diff --git a/security/nss/automation/taskcluster/windows/setup32.sh b/security/nss/automation/taskcluster/windows/setup32.sh index bcddabfa3..19bed284d 100644 --- a/security/nss/automation/taskcluster/windows/setup32.sh +++ b/security/nss/automation/taskcluster/windows/setup32.sh @@ -4,7 +4,7 @@ set -v -e -x source $(dirname $0)/setup.sh -export WIN32_REDIST_DIR="${VSPATH}/VC/redist/x86/Microsoft.VC140.CRT" +export WIN32_REDIST_DIR="${VSPATH}/VC/redist/x86/Microsoft.VC141.CRT" export WIN_UCRT_REDIST_DIR="${VSPATH}/SDK/Redist/ucrt/DLLs/x86" -export PATH="${NINJA_PATH}:${VSPATH}/VC/bin/amd64_x86:${VSPATH}/VC/bin/amd64:${VSPATH}/VC/bin:${VSPATH}/SDK/bin/x86:${VSPATH}/SDK/bin/x64:${VSPATH}/VC/redist/x86/Microsoft.VC140.CRT:${VSPATH}/VC/redist/x64/Microsoft.VC140.CRT:${VSPATH}/SDK/Redist/ucrt/DLLs/x86:${VSPATH}/SDK/Redist/ucrt/DLLs/x64:${PATH}" -export LIB="${VSPATH}/VC/lib:${VSPATH}/SDK/lib/10.0.14393.0/ucrt/x86:${VSPATH}/SDK/lib/10.0.14393.0/um/x86" +export PATH="${NINJA_PATH}:${VSPATH}/VC/bin/Hostx64/x86:${VSPATH}/VC/bin/Hostx64/x64:${VSPATH}/VC/Hostx86/x86:${VSPATH}/SDK/bin/10.0.15063.0/x64:${VSPATH}/VC/redist/x86/Microsoft.VC141.CRT:${VSPATH}/SDK/Redist/ucrt/DLLs/x86:${PATH}" +export LIB="${VSPATH}/VC/lib/x86:${VSPATH}/SDK/lib/10.0.15063.0/ucrt/x86:${VSPATH}/SDK/lib/10.0.15063.0/um/x86" diff --git a/security/nss/automation/taskcluster/windows/setup64.sh b/security/nss/automation/taskcluster/windows/setup64.sh index f308298c1..d16cb0ec9 100644 --- a/security/nss/automation/taskcluster/windows/setup64.sh +++ b/security/nss/automation/taskcluster/windows/setup64.sh @@ -4,7 +4,7 @@ set -v -e -x source $(dirname $0)/setup.sh -export WIN32_REDIST_DIR="${VSPATH}/VC/redist/x64/Microsoft.VC140.CRT" +export WIN32_REDIST_DIR="${VSPATH}/VC/redist/x64/Microsoft.VC141.CRT" export WIN_UCRT_REDIST_DIR="${VSPATH}/SDK/Redist/ucrt/DLLs/x64" -export PATH="${NINJA_PATH}:${VSPATH}/VC/bin/amd64:${VSPATH}/VC/bin:${VSPATH}/SDK/bin/x64:${VSPATH}/VC/redist/x64/Microsoft.VC140.CRT:${VSPATH}/SDK/Redist/ucrt/DLLs/x64:${PATH}" -export LIB="${VSPATH}/VC/lib/amd64:${VSPATH}/SDK/lib/10.0.14393.0/ucrt/x64:${VSPATH}/SDK/lib/10.0.14393.0/um/x64" +export PATH="${NINJA_PATH}:${VSPATH}/VC/bin/Hostx64/x64:${VSPATH}/VC/bin/Hostx86/x86:${VSPATH}/SDK/bin/10.0.15063.0/x64:${VSPATH}/VC/redist/x64/Microsoft.VC141.CRT:${VSPATH}/SDK/Redist/ucrt/DLLs/x64:${PATH}" +export LIB="${VSPATH}/VC/lib/x64:${VSPATH}/SDK/lib/10.0.15063.0/ucrt/x64:${VSPATH}/SDK/lib/10.0.15063.0/um/x64" diff --git a/security/nss/build.sh b/security/nss/build.sh index 2b377dec5..338e14beb 100755 --- a/security/nss/build.sh +++ b/security/nss/build.sh @@ -68,11 +68,14 @@ fi while [ $# -gt 0 ]; do case $1 in -c) clean=1 ;; + -cc) clean_only=1 ;; --gyp|-g) rebuild_gyp=1 ;; --nspr) nspr_clean; rebuild_nspr=1 ;; -j) ninja_params+=(-j "$2"); shift ;; -v) ninja_params+=(-v); verbose=1 ;; --test) gyp_params+=(-Dtest_build=1) ;; + --clang) export CC=clang; export CCC=clang++; export CXX=clang++ ;; + --gcc) export CC=gcc; export CCC=g++; export CXX=g++ ;; --fuzz) fuzz=1 ;; --fuzz=oss) fuzz=1; fuzz_oss=1 ;; --fuzz=tls) fuzz=1; fuzz_tls=1 ;; @@ -88,12 +91,14 @@ while [ $# -gt 0 ]; do --sancov=?*) enable_sancov "${1#*=}" ;; --pprof) gyp_params+=(-Duse_pprof=1) ;; --ct-verif) gyp_params+=(-Dct_verif=1) ;; + --emit-llvm) gyp_params+=(-Demit_llvm=1 -Dsign_libs=0) ;; --disable-tests) gyp_params+=(-Ddisable_tests=1) ;; --no-zdefs) gyp_params+=(-Dno_zdefs=1) ;; --system-sqlite) gyp_params+=(-Duse_system_sqlite=1) ;; --with-nspr=?*) set_nspr_path "${1#*=}"; no_local_nspr=1 ;; --system-nspr) set_nspr_path "/usr/include/nspr/:"; no_local_nspr=1 ;; --enable-libpkix) gyp_params+=(-Ddisable_libpkix=0) ;; + --enable-fips) gyp_params+=(-Ddisable_fips=0) ;; *) show_help; exit 2 ;; esac shift @@ -121,10 +126,15 @@ dist_dir=$(mkdir -p "$dist_dir"; cd "$dist_dir"; pwd -P) gyp_params+=(-Dnss_dist_dir="$dist_dir") # -c = clean first -if [ "$clean" = 1 ]; then +if [ "$clean" = 1 -o "$clean_only" = 1 ]; then nspr_clean rm -rf "$cwd"/out rm -rf "$dist_dir" + # -cc = only clean, don't build + if [ "$clean_only" = 1 ]; then + echo "Cleaned" + exit 0 + fi fi # This saves a canonical representation of arguments that we are passing to gyp diff --git a/security/nss/cmd/bltest/blapitest.c b/security/nss/cmd/bltest/blapitest.c index a3a162da1..ca3d6f314 100644 --- a/security/nss/cmd/bltest/blapitest.c +++ b/security/nss/cmd/bltest/blapitest.c @@ -20,16 +20,14 @@ #include "secport.h" #include "secoid.h" #include "nssutil.h" +#include "ecl-curve.h" #include "pkcs1_vectors.h" -#ifndef NSS_DISABLE_ECC -#include "ecl-curve.h" SECStatus EC_DecodeParams(const SECItem *encodedParams, ECParams **ecparams); SECStatus EC_CopyParams(PLArenaPool *arena, ECParams *dstParams, const ECParams *srcParams); -#endif char *progName; char *testdir = NULL; @@ -135,18 +133,14 @@ Usage() PRINTUSAGE(progName, "-S -m mode", "Sign a buffer"); PRINTUSAGE("", "", "[-i plaintext] [-o signature] [-k key]"); PRINTUSAGE("", "", "[-b bufsize]"); -#ifndef NSS_DISABLE_ECC PRINTUSAGE("", "", "[-n curvename]"); -#endif PRINTUSAGE("", "", "[-p repetitions | -5 time_interval] [-4 th_num]"); PRINTUSAGE("", "-m", "cipher mode to use"); PRINTUSAGE("", "-i", "file which contains input buffer"); PRINTUSAGE("", "-o", "file for signature"); PRINTUSAGE("", "-k", "file which contains key"); -#ifndef NSS_DISABLE_ECC PRINTUSAGE("", "-n", "name of curve for EC key generation; one of:"); PRINTUSAGE("", "", " nistp256, nistp384, nistp521"); -#endif PRINTUSAGE("", "-p", "do performance test"); PRINTUSAGE("", "-4", "run test in multithread mode. th_num number of parallel threads"); PRINTUSAGE("", "-5", "run test for specified time interval(in seconds)"); @@ -369,7 +363,6 @@ dsakey_from_filedata(PLArenaPool *arena, SECItem *filedata) return key; } -#ifndef NSS_DISABLE_ECC static ECPrivateKey * eckey_from_filedata(PLArenaPool *arena, SECItem *filedata) { @@ -519,7 +512,6 @@ getECParams(const char *curve) return ecparams; } -#endif /* NSS_DISABLE_ECC */ static void dump_pqg(PQGParams *pqg) @@ -537,7 +529,6 @@ dump_dsakey(DSAPrivateKey *key) SECU_PrintInteger(stdout, &key->privateValue, "PRIVATE VALUE:", 0); } -#ifndef NSS_DISABLE_ECC static void dump_ecp(ECParams *ecp) { @@ -552,7 +543,6 @@ dump_eckey(ECPrivateKey *key) SECU_PrintInteger(stdout, &key->publicValue, "PUBLIC VALUE:", 0); SECU_PrintInteger(stdout, &key->privateValue, "PRIVATE VALUE:", 0); } -#endif static void dump_rsakey(RSAPrivateKey *key) @@ -638,17 +628,15 @@ typedef enum { bltestRSA, /* Public Key Ciphers */ bltestRSA_OAEP, /* . (Public Key Enc.) */ bltestRSA_PSS, /* . (Public Key Sig.) */ -#ifndef NSS_DISABLE_ECC - bltestECDSA, /* . (Public Key Sig.) */ -#endif - bltestDSA, /* . (Public Key Sig.) */ - bltestMD2, /* Hash algorithms */ - bltestMD5, /* . */ - bltestSHA1, /* . */ - bltestSHA224, /* . */ - bltestSHA256, /* . */ - bltestSHA384, /* . */ - bltestSHA512, /* . */ + bltestECDSA, /* . (Public Key Sig.) */ + bltestDSA, /* . (Public Key Sig.) */ + bltestMD2, /* Hash algorithms */ + bltestMD5, /* . */ + bltestSHA1, /* . */ + bltestSHA224, /* . */ + bltestSHA256, /* . */ + bltestSHA384, /* . */ + bltestSHA512, /* . */ NUMMODES } bltestCipherMode; @@ -678,9 +666,7 @@ static char *mode_strings[] = "rsa", "rsa_oaep", "rsa_pss", -#ifndef NSS_DISABLE_ECC "ecdsa", -#endif /*"pqg",*/ "dsa", "md2", @@ -732,13 +718,11 @@ typedef struct PQGParams *pqg; } bltestDSAParams; -#ifndef NSS_DISABLE_ECC typedef struct { char *curveName; bltestIO sigseed; } bltestECDSAParams; -#endif typedef struct { @@ -751,9 +735,7 @@ typedef struct union { bltestRSAParams rsa; bltestDSAParams dsa; -#ifndef NSS_DISABLE_ECC bltestECDSAParams ecdsa; -#endif } cipherParams; } bltestAsymKeyParams; @@ -1310,7 +1292,6 @@ dsa_verifyDigest(void *cx, SECItem *output, const SECItem *input) return DSA_VerifyDigest((DSAPublicKey *)params->pubKey, output, input); } -#ifndef NSS_DISABLE_ECC SECStatus ecdsa_signDigest(void *cx, SECItem *output, const SECItem *input) { @@ -1331,7 +1312,6 @@ ecdsa_verifyDigest(void *cx, SECItem *output, const SECItem *input) bltestAsymKeyParams *params = (bltestAsymKeyParams *)cx; return ECDSA_VerifyDigest((ECPublicKey *)params->pubKey, output, input); } -#endif SECStatus bltest_des_init(bltestCipherInfo *cipherInfo, PRBool encrypt) @@ -1811,7 +1791,6 @@ bltest_dsa_init(bltestCipherInfo *cipherInfo, PRBool encrypt) return SECSuccess; } -#ifndef NSS_DISABLE_ECC SECStatus bltest_ecdsa_init(bltestCipherInfo *cipherInfo, PRBool encrypt) { @@ -1877,7 +1856,6 @@ bltest_ecdsa_init(bltestCipherInfo *cipherInfo, PRBool encrypt) } return SECSuccess; } -#endif /* XXX unfortunately, this is not defined in blapi.h */ SECStatus @@ -2169,11 +2147,7 @@ finish: SECStatus pubkeyInitKey(bltestCipherInfo *cipherInfo, PRFileDesc *file, -#ifndef NSS_DISABLE_ECC int keysize, int exponent, char *curveName) -#else - int keysize, int exponent) -#endif { int i; SECStatus rv = SECSuccess; @@ -2182,12 +2156,10 @@ pubkeyInitKey(bltestCipherInfo *cipherInfo, PRFileDesc *file, RSAPrivateKey **rsaKey = NULL; bltestDSAParams *dsap; DSAPrivateKey **dsaKey = NULL; -#ifndef NSS_DISABLE_ECC SECItem *tmpECParamsDER; ECParams *tmpECParams = NULL; SECItem ecSerialize[3]; ECPrivateKey **ecKey = NULL; -#endif switch (cipherInfo->mode) { case bltestRSA: case bltestRSA_PSS: @@ -2224,7 +2196,6 @@ pubkeyInitKey(bltestCipherInfo *cipherInfo, PRFileDesc *file, dsap->keysize = (*dsaKey)->params.prime.len * 8; } break; -#ifndef NSS_DISABLE_ECC case bltestECDSA: ecKey = (ECPrivateKey **)&asymk->privKey; if (curveName != NULL) { @@ -2254,7 +2225,6 @@ pubkeyInitKey(bltestCipherInfo *cipherInfo, PRFileDesc *file, *ecKey = eckey_from_filedata(cipherInfo->arena, &asymk->key.buf); } break; -#endif default: return SECFailure; } @@ -2341,7 +2311,6 @@ cipherInit(bltestCipherInfo *cipherInfo, PRBool encrypt) } return bltest_dsa_init(cipherInfo, encrypt); break; -#ifndef NSS_DISABLE_ECC case bltestECDSA: if (encrypt) { SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf, @@ -2349,7 +2318,6 @@ cipherInit(bltestCipherInfo *cipherInfo, PRBool encrypt) } return bltest_ecdsa_init(cipherInfo, encrypt); break; -#endif case bltestMD2: restart = cipherInfo->params.hash.restart; SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf, @@ -2644,9 +2612,7 @@ cipherFinish(bltestCipherInfo *cipherInfo) case bltestRSA_PSS: /* will be freed with it. */ case bltestRSA_OAEP: case bltestDSA: -#ifndef NSS_DISABLE_ECC case bltestECDSA: -#endif case bltestMD2: /* hash contexts are ephemeral */ case bltestMD5: case bltestSHA1: @@ -2822,7 +2788,6 @@ print_td: fprintf(stdout, "%8d", info->params.asymk.cipherParams.dsa.keysize); } break; -#ifndef NSS_DISABLE_ECC case bltestECDSA: if (td) { fprintf(stdout, "%12s", "ec_curve"); @@ -2833,7 +2798,6 @@ print_td: ecCurve_map[curveName] ? ecCurve_map[curveName]->text : "Unsupported curve"); } break; -#endif case bltestMD2: case bltestMD5: case bltestSHA1: @@ -3063,7 +3027,6 @@ get_params(PLArenaPool *arena, bltestParams *params, sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "ciphertext", j); load_file_data(arena, ¶ms->asymk.sig, filename, bltestBase64Encoded); break; -#ifndef NSS_DISABLE_ECC case bltestECDSA: sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "key", j); load_file_data(arena, ¶ms->asymk.key, filename, bltestBase64Encoded); @@ -3075,7 +3038,6 @@ get_params(PLArenaPool *arena, bltestParams *params, sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "ciphertext", j); load_file_data(arena, ¶ms->asymk.sig, filename, bltestBase64Encoded); break; -#endif case bltestMD2: case bltestMD5: case bltestSHA1: @@ -3297,13 +3259,11 @@ dump_file(bltestCipherMode mode, char *filename) load_file_data(arena, &keydata, filename, bltestBase64Encoded); key = dsakey_from_filedata(arena, &keydata.buf); dump_dsakey(key); -#ifndef NSS_DISABLE_ECC } else if (mode == bltestECDSA) { ECPrivateKey *key; load_file_data(arena, &keydata, filename, bltestBase64Encoded); key = eckey_from_filedata(arena, &keydata.buf); dump_eckey(key); -#endif } PORT_FreeArena(arena, PR_FALSE); return SECFailure; @@ -3590,9 +3550,7 @@ enum { opt_Key, opt_HexWSpc, opt_Mode, -#ifndef NSS_DISABLE_ECC opt_CurveName, -#endif opt_Output, opt_Repetitions, opt_ZeroBuf, @@ -3644,9 +3602,7 @@ static secuCommandFlag bltest_options[] = { /* opt_Key */ 'k', PR_TRUE, 0, PR_FALSE }, { /* opt_HexWSpc */ 'l', PR_FALSE, 0, PR_FALSE }, { /* opt_Mode */ 'm', PR_TRUE, 0, PR_FALSE }, -#ifndef NSS_DISABLE_ECC { /* opt_CurveName */ 'n', PR_TRUE, 0, PR_FALSE }, -#endif { /* opt_Output */ 'o', PR_TRUE, 0, PR_FALSE }, { /* opt_Repetitions */ 'p', PR_TRUE, 0, PR_FALSE }, { /* opt_ZeroBuf */ 'q', PR_FALSE, 0, PR_FALSE }, @@ -3679,9 +3635,7 @@ main(int argc, char **argv) bltestCipherInfo *cipherInfoListHead, *cipherInfo = NULL; bltestIOMode ioMode; int bufsize, exponent, curThrdNum; -#ifndef NSS_DISABLE_ECC char *curveName = NULL; -#endif int i, commandsEntered; int inoff, outoff; int threads = 1; @@ -3917,12 +3871,10 @@ main(int argc, char **argv) else exponent = 65537; -#ifndef NSS_DISABLE_ECC if (bltest.options[opt_CurveName].activated) curveName = PORT_Strdup(bltest.options[opt_CurveName].arg); else curveName = NULL; -#endif if (bltest.commands[cmd_Verify].activated && !bltest.options[opt_SigFile].activated) { @@ -4008,11 +3960,7 @@ main(int argc, char **argv) file = PR_Open("tmp.key", PR_WRONLY | PR_CREATE_FILE, 00660); } params->key.mode = bltestBase64Encoded; -#ifndef NSS_DISABLE_ECC pubkeyInitKey(cipherInfo, file, keysize, exponent, curveName); -#else - pubkeyInitKey(cipherInfo, file, keysize, exponent); -#endif PR_Close(file); } diff --git a/security/nss/cmd/certcgi/HOWTO.txt b/security/nss/cmd/certcgi/HOWTO.txt deleted file mode 100644 index 54edf8e1a..000000000 --- a/security/nss/cmd/certcgi/HOWTO.txt +++ /dev/null @@ -1,137 +0,0 @@ - How to setup your very own Cert-O-Matic Root CA server - - 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/. - - How to setup your very own Cert-O-Matic Root CA server - -The program certcgi is part of a small test CA that is used inside -Netscape by the NSS development team. That CA is affectionately known -as "Cert-O-Matic" or "Cert-O-Matic II". It presently runs on a server -named interzone.mcom.com inside Netscape's firewall. - -If you wish to setup your own Cert-O-Matic, here are directions. - -Disclaimer: This program does not follow good practices for root CAs. -It should be used only for playing/testing and never for production use. -Remember, you've been warned! - -Cert-O-Matic consists of some html files, shell scripts, one executable -program that uses NSS and NSPR, the usual set of NSS .db files, and a file -in which to remember the serial number of the last cert issued. The -html files and the source to the executable program are in this directory. -Sample shell scripts are shown below. - -The shell scripts and executable program run as CGI "scripts". The -entire thing runs on an ordinary http web server. It would also run on -an https web server. The shell scripts and html files must be -customized for the server on which they run. - -The package assumes you have a "document root" directory $DOCROOT, and a -"cgi-bin" directory $CGIBIN. In this example, the document root is -assumed to be located in /var/www/htdocs, and the cgi-bin directory in -/var/www/cgi-bin. - -The server is assumed to run all cgi scripts as the user "nobody". -The names of the cgi scripts run directly by the server all end in .cgi -because some servers like it that way. - -Instructions: - -- Create directory $DOCROOT/certomatic -- Copy the following files from nss/cmd/certcgi to $DOCROOT/certomatic - ca.html index.html main.html nscp_ext_form.html stnd_ext_form.html -- Edit the html files, substituting the name of your own server for the - server named in those files. -- In some web page (e.g. your server's home page), provide an html link to - $DOCROOT/certomatic/index.html. This is where users start to get their - own certs from certomatic. -- give these files and directories appropriate permissions. - -- Create directories $CGIBIN/certomatic and $CGIBIN/certomatic/bin - make sure that $CGIBIN/certomatic is writable by "nobody" - -- Create a new set of NSS db files there with the following command: - - certutil -N -d $CGIBIN/certomatic - -- when certutil prompts you for the password, enter the word foo - because that is compiled into the certcgi program. - -- Create the new Root CA cert with this command - - certutil -S -x -d $CGIBIN/certomatic -n "Cert-O-Matic II" \ - -s "CN=Cert-O-Matic II, O=Cert-O-Matic II" -t TCu,cu,cu -k rsa \ - -g 1024 -m 10001 -v 60 - - (adjust the -g, -m and -v parameters to taste. -s and -x must be as -shown.) - -- dump out the new root CA cert in base64 encoding: - - certutil -d $CGIBIN/certomatic -L -n "Cert-O-Matic II" -a > \ - $CGIBIN/certomatic/root.cacert - -- In $CGIBIN/certomatic/bin add two shell scripts - one to download the - root CA cert on demand, and one to run the certcgi program. - -download.cgi, the script to install the root CA cert into a browser on -demand, is this: - -#!/bin/sh -echo "Content-type: application/x-x509-ca-cert" -echo -cat $CGIBIN/certomatic/root.cacert - -You'll have to put the real path into that cat command because CGIBIN -won't be defined when this script is run by the server. - -certcgi.cgi, the script to run the certcgi program is similar to this: - -#!/bin/sh -cd $CGIBIN/certomatic/bin -LD_LIBRARY_PATH=$PLATFORM/lib -export LD_LIBRARY_PATH -$PLATFORM/bin/certcgi $* 2>&1 - -Where $PLATFORM/lib is where the NSPR nad NSS DSOs are located, and -$PLATFORM/bin is where certcgi is located. PLATFORM is not defined when -the server runs this script, so you'll have to substitute the right value -in your script. certcgi requires that the working directory be one level -below the NSS DBs, that is, the DBs are accessed in the directory "..". - -You'll want to provide an html link somewhere to the script that downloads -the root.cacert file. You'll probably want to put that next to the link -that loads the index.html page. On interzone, this is done with the -following html: - -<a href="/certomatic/index.html">Cert-O-Matic II Root CA server</a> -<p> -<a href="/cgi-bin/certomatic/bin/download.cgi">Download and trust Root CA -certificate</a> - -The index.html file in this directory invokes the certcgi.cgi script with -the form post method, so if you change the name of the certcgi.cgi script, -you'll also have to change the index.html file in $DOCROOT/certomatic - -The 4 files used by the certcgi program (the 3 NSS DBs, and the serial -number file) are not required to live in $CGIBIN/certomatic, but they are -required to live in $CWD/.. when certcgi starts. - -Known bugs: - -1. Because multiple of these CAs exist simultaneously, it would be best if -they didn't all have to be called "Cert-O-Matic II", but that string is -presently hard coded into certcgi.c. - -2. the html files in this directory contain numerous extraneous <FORM> tags -which appear to use the post method and have action URLS that are never -actually used. burp.cgi and echoform.cgi are never actually used. This -should be cleaned up. - -3. The html files use <layer> tags which are supported only in Netscape -Navigator and Netscape Communication 4.x browsers. The html files do -not work as intended with Netscape 6.x, Mozilla or Microsoft IE browsers. -The html files should be fixed to work with all those named browsers. - diff --git a/security/nss/cmd/certcgi/ca.html b/security/nss/cmd/certcgi/ca.html deleted file mode 100644 index 3f3f08699..000000000 --- a/security/nss/cmd/certcgi/ca.html +++ /dev/null @@ -1,19 +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/. --> - -<form method="post" name="ca_form" action="mailto:jerdonek@netscape.com"> -<input type="radio" name="caChoiceradio" value="SignWithDefaultkey" - onClick="{parent.choice_change(this.form)}"> - Use the Cert-O-matic certificate to issue the cert</p> -<input type="radio" name="caChoiceradio" value="SignWithRandomChain" - onClick="{parent.choice_change(this.form)}"> Use a - <input type="text" size="2" maxsize="2" name="autoCAs"> CA long - automatically generated chain ending with the Cert-O-Matic Cert - (18 maximum)</p> -<input type="radio" name="caChoiceradio" value="SignWithSpecifiedChain" - onClick="{parent.choice_change(this.form)}"> Use a - <input type="text" size="1" maxlength="1" name="manCAs" - onChange="{parent.ca_num_change(this.value,this.form)}"> CA long - user input chain ending in the Cert-O-Matic Cert.</p> -</form> diff --git a/security/nss/cmd/certcgi/ca_form.html b/security/nss/cmd/certcgi/ca_form.html deleted file mode 100644 index 452996b58..000000000 --- a/security/nss/cmd/certcgi/ca_form.html +++ /dev/null @@ -1,357 +0,0 @@ -<html> -<!-- 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/. --> - <form method="post" name="primary_form" action="http://interzone.mcom.com/burp.cgi"> - <table border=0 cellspacing=10 cellpadding=0> - <tr> - <td> - Common Name:</td><td> <input type="text" name="name" onChange="{window.top.reset_subject('CN=', value, form)}"></p> - </td> - <td></td><td></td><td> - Mail: </td><td><input type="text" name="email" onChange="var temp;{if (email_type[0].checked) {temp = 'MAIL='} else {temp = 'E='}} ;{window.top.reset_subject(temp, value, form)}"></p> - RFC 1274<input type="radio" name="email_type" value="1" onClick="window.top.switch_mail(form)"> - e-mail<input type="radio" name="email_type" value="2" checked onClick="window.top.switch_mail(form)"></td> - <tr> - <td> - Organization: </td><td> <input type="text" name="org" onChange="{window.top.reset_subject('O=', value, form)}"></p></td> - <td></td><td></td><td> - Organizational Unit: </td><td><input type="text" name="org_unit" onChange="{window.top.reset_subject('OU=', value, form)}"></p></td> - <tr> - <td> - RFC 1274 UID: </td><td><input type="text" name="uid" onChange="{window.top.reset_subject('UID=', value, form)}"></p></td> - <td></td><td></td><td> - Locality: </td><td><input type="text" name="loc" onChange="{window.top.reset_subject('L=', value, form)}"></p></td> - <tr> - <td> - State or Province: </td><td><input type="text" name="state" onChange="{window.top.reset_subject('ST=', value, form)}"></p></td> - <td></td><td></td><td> - Country: </td><td><input type="text" size="2" maxsize="2" name="country" onChange="{window.top.reset_subject('C=', value, form)}"></p></td> - </table> - <table border=0 cellspacing=10 cellpadding=0> - <tr> - <td> - Serial Number:</p> - <DD> - <input type="radio" name="serial" value="auto" checked> Auto Generate</P> - <DD> - <input type="radio" name="serial" value="input"> - Use this value: <input type="text" name="serial_value" size="8" maxlength="8"></p> - </td> - <td></td><td></td><td></td><td></td> - <td> - X.509 version:</p> - <DD> - <input type="radio" name="ver" value="1" checked> Version 1</p> - <DD> - <input type="radio" name="ver" value="3"> Version 3</P></td> - <td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td> - <td> - Key Type:</p> - <DD> - <input type="radio" name="keyType" value="rsa" checked> RSA</p> - <DD> - <input type="radio" name="keyType" value="dsa"> DSA</P></td> - </table> - DN: <input type="text" name="subject" size="70" onChange="{window.top.reset_subjectFields(form)}"></P> - <Select name="keysize"> - <option>1024 (High Grade) - <option>768 (Medium Grade) - <option>512 (Low Grade) - </select> - </p> - <hr> - </p> - <table border=1 cellspacing=5 cellpadding=5> - <tr> - <td> - <b>Netscape Certificate Type: </b></p> - Activate extension: <input type="checkbox" name="netscape-cert-type"></P> - Critical: <input type="checkbox" name="netscape-cert-type-crit"> - <td> - <input type="checkbox" name="netscape-cert-type-ssl-client"> SSL Client</P> - <input type="checkbox" name="netscape-cert-type-ssl-server"> SSL Server</P> - <input type="checkbox" name="netscape-cert-type-smime"> S/MIME</P> - <input type="checkbox" name="netscape-cert-type-object-signing"> Object Signing</P> - <input type="checkbox" name="netscape-cert-type-reserved"> Reserved for future use (bit 4)</P> - <input type="checkbox" name="netscape-cert-type-ssl-ca"> SSL CA</P> - <input type="checkbox" name="netscape-cert-type-smime-ca"> S/MIME CA</P> - <input type="checkbox" name="netscape-cert-type-object-signing-ca"> Object Signing CA</P> - </tr> - <tr> - <td> - <b>Netscape Base URL:</b></p> - Activate extension: <input type="checkbox" name="netscape-base-url"></P> - Critical: <input type="checkbox" name="netscape-base-url-crit"> - <td> - <input type="text" name="netscape-base-url-text" size="50"> - </tr> - <tr> - <td> - <b>Netscape Revocation URL:</b></p> - Activate extension: <input type="checkbox" name="netscape-revocation-url"></P> - Critical: <input type="checkbox" name="netscape-revocation-url-crit"> - <td> - <input type="text" name="netscape-revocation-url-text" size="50"> - </tr> - <tr> - <td> - <b>Netscape CA Revocation URL:</b></p> - Activate extension: <input type="checkbox" name="netscape-ca-revocation-url"></P> - Critical: <input type="checkbox" name="netscape-ca-revocation-url-crit"> - <td> - <input type="text" name="netscape-ca-revocation-url-text" size="50"> - </tr> - <tr> - <td> - <b>Netscape Certificate Renewal URL:</b></p> - Activate extension: <input type="checkbox" name="netscape-cert-renewal-url"></P> - Critical: <input type="checkbox" name="netscape-cert-renewal-url-crit"> - <td> - <input type="text" name="netscape-cert-renewal-url-text" size="50"> - </tr> - <tr> - <td> - <b>Netscape CA Policy URL:</b></p> - Activate extension: <input type="checkbox" name="netscape-ca-policy-url"></P> - Critical: <input type="checkbox" name="netscape-ca-policy-url-crit"> - <td> - <input type="text" name="netscape-ca-policy-url-text" size="50"> - </tr> - <tr> - <td> - <b>Netscape SSL Server Name:</b></p> - Activate extension: <input type="checkbox" name="netscape-ssl-server-name"></P> - Critical: <input type="checkbox" name="netscape-ssl-server-name-crit"> - <td> - <input type="text" name="netscape-ssl-server-name-text" size="50"> - </tr> - <tr> - <td> - <b>Netscape Comment:</b></p> - Activate extension: <input type="checkbox" name="netscape-comment"></P> - Critical: <input type="checkbox" name="netscape-comment-crit"> - <td> - <textarea name="netscape-comment-text" rows="5" cols="50"></textarea> - </tr> - </table> - </p> - <hr> - </p> - <table border=1 cellspacing=5 cellpadding=5> - <form method="post" name="primary_form" action="http://interzone.mcom.com/burp.cgi"> - <tr> - <td> - <b>Key Usage: </b></p> - Activate extension: <input type="checkbox" name="keyUsage"></P> - Critical: <input type="checkbox" name="keyUsage-crit"> - <td> - <input type="checkbox" name="keyUsage-digitalSignature"> Digital Signature</P> - <input type="checkbox" name="keyUsage-nonRepudiation"> Non Repudiation</P> - <input type="checkbox" name="keyUsage-keyEncipherment"> Key Encipherment</P> - <input type="checkbox" name="keyUsage-dataEncipherment"> Data Encipherment</P> - <input type="checkbox" name="keyUsage-keyAgreement"> Key Agreement</P> - <input type="checkbox" name="keyUsage-keyCertSign"> Key Certificate Signing</P> - <input type="checkbox" name="keyUsage-cRLSign"> CRL Signing</P> - </tr> - <tr> - <td> - <b>Extended Key Usage: </b></p> - Activate extension: <input type="checkbox" name="extKeyUsage"></P> - Critical: <input type="checkbox" name="extKeyUsage-crit"> - <td> - <input type="checkbox" name="extKeyUsage-serverAuth"> Server Auth</P> - <input type="checkbox" name="extKeyUsage-clientAuth"> Client Auth</P> - <input type="checkbox" name="extKeyUsage-codeSign"> Code Signing</P> - <input type="checkbox" name="extKeyUsage-emailProtect"> Email Protection</P> - <input type="checkbox" name="extKeyUsage-timeStamp"> Timestamp</P> - <input type="checkbox" name="extKeyUsage-ocspResponder"> OCSP Responder</P> - <input type="checkbox" name="extKeyUsage-NS-govtApproved"> Step-up</P> - <input type="checkbox" name="extKeyUsage-msTrustListSign"> Microsoft Trust List Signing</P> - </tr> - <tr> - <td> - <b>Basic Constraints:</b></p> - Activate extension: <input type="checkbox" name="basicConstraints"></P> - Critical: <input type="checkbox" name="basicConstraints-crit"> - <td> - CA:</p> - <dd><input type=radio name="basicConstraints-cA-radio" value="CA"> True</p> - <dd><input type=radio name="basicConstraints-cA-radio" value="NotCA"> False</p> - <input type="checkbox" name="basicConstraints-pathLengthConstraint"> - Include Path length: <input type="text" name="basicConstraints-pathLengthConstraint-text" size="2"></p> - </tr> - <tr> - <td> - <b>Authority Key Identifier:</b></p> - Activate extension: <input type="checkbox" name="authorityKeyIdentifier"> - <td> - <input type="radio" name="authorityKeyIdentifier-radio" value="keyIdentifier"> Key Identider</p> - <input type="radio" name="authorityKeyIdentifier-radio" value="authorityCertIssuer"> Issuer Name and Serial number</p> - </tr> - <tr> - <td> - <b>Subject Key Identifier:</b></p> - Activate extension: <input type="checkbox" name="subjectKeyIdentifier"> - <td> - Key Identifier: - <input type="text" name="subjectKeyIdentifier-text"></p> - This is an:<p> - <dd><dd><input type="radio" name="subjectKeyIdentifier-radio" value="ascii"> ascii text value<p> - <dd><dd><input type="radio" name="subjectKeyIdentifier-radio" value="hex"> hex value<p> - </tr> - <tr> - <td> - <b>Private Key Usage Period:</b></p> - Activate extension: <input type="checkbox" name="privKeyUsagePeriod"></p> - Critical: <input type="checkbox" name="privKeyUsagePeriod-crit"> - <td> - Use:</p> - <dd><input type="radio" name="privKeyUsagePeriod-radio" value="notBefore"> Not Before</p> - <dd><input type="radio" name="privKeyUsagePeriod-radio" value="notAfter"> Not After</p> - <dd><input type="radio" name="privKeyUsagePeriod-radio" value="both" > Both</p> - <b>Not to be used to sign before:</b></p> - <dd><input type="radio" name="privKeyUsagePeriod-notBefore-radio" value="auto"> Set to time of certificate issue</p> - <dd><input type="radio" name="privKeyUsagePeriod-notBefore-radio" value="manual"> Use This value</p> - <dd><dd>(YYYY/MM/DD HH:MM:SS): - <input type="text" name="privKeyUsagePeriod-notBefore-year" size="4" maxlength="4">/ - <input type="text" name="privKeyUsagePeriod-notBefore-month" size="2" maxlength="2">/ - <input type="text" name="privKeyUsagePeriod-notBefore-day" size="2" maxlength="2"> - <input type="text" name="privKeyUsagePeriod-notBefore-hour" size="2" maxlength="2">: - <input type="text" name="privKeyUsagePeriod-notBefore-minute" size="2" maxlength="2">: - <input type="text" name="privKeyUsagePeriod-notBefore-second" size="2" maxlength="2"></p> - <b>Not to be used to sign after:</b></p> - <dd>(YYYY/MM/DD HH:MM:SS): - <input type="text" name="privKeyUsagePeriod-notAfter-year" size="4" maxlength="4">/ - <input type="text" name="privKeyUsagePeriod-notAfter-month" size="2" maxlength="2">/ - <input type="text" name="privKeyUsagePeriod-notAfter-day" size="2" maxlength="2"> - <input type="text" name="privKeyUsagePeriod-notAfter-hour" size="2" maxlength="2">: - <input type="text" name="privKeyUsagePeriod-notAfter-minute" size="2" maxlength="2">: - <input type="text" name="privKeyUsagePeriod-notAfter-second" size="2" maxlength="2"></p> - </tr> - <tr> - <td> - <b>Subject Alternative Name:</b></p> - Activate extension: <input type="checkbox" name="SubAltName"></P> - Critical: <input type="checkbox" name="SubAltName-crit"> - <td> - <table> - <tr> - <td> - General Names:</p> - <select name="SubAltNameSelect" multiple size="10"> - </select></p></p> - <input type="button" name="SubAltName-add" value="Add" onClick="{parent.addSubAltName(this.form)}"> - <input type="button" name="SubAltName-delete" value="Delete" onClick="parent.deleteSubAltName(this.form)"> - </td><td> - <table><tr><td> - Name Type: </td></tr><tr><td> - <input type="radio" name="SubAltNameRadio" value="otherName" onClick="parent.setSubAltNameType(form)"> Other Name, - OID: <input type="text" name="SubAltNameOtherNameOID" size="6"> </td><td> - <input type="radio" name="SubAltNameRadio" value="rfc822Name" onClick="parent.setSubAltNameType(form)"> RFC 822 Name</td></tr><td> - <input type="radio" name="SubAltNameRadio" value="dnsName" onClick="parent.setSubAltNameType(form)"> DNS Name </td><td> - <input type="radio" name="SubAltNameRadio" value="x400" onClick="parent.setSubAltNameType(form)"> X400 Address</td></tr><td> - <input type="radio" name="SubAltNameRadio" value="directoryName" onClick="parent.setSubAltNameType(form)"> Directory Name</td><td> - <input type="radio" name="SubAltNameRadio" value="ediPartyName" onClick="parent.setSubAltNameType(form)"> EDI Party Name</td></tr><td> - <input type="radio" name="SubAltNameRadio" value="URL" onClick="parent.setSubAltNameType(form)"> Uniform Resource Locator</td><td> - <input type="radio" name="SubAltNameRadio" value="ipAddress" onClick="parent.setSubAltNameType(form)"> IP Address</td></tr><td> - <input type="radio" name="SubAltNameRadio" value="regID"onClick="parent.setSubAltNameType(form)"> Registered ID</td><td> - <input type="radio" name="SubAltNameRadio" value="nscpNickname" onClick="parent.setSubAltNameType(form)"> Netscape Certificate Nickname</td><td></tr> - </table> - Name: <input type="text" name="SubAltNameText"> - Binary Encoded: <input type="checkbox" name="SubAltNameDataType" value="binary" onClick="parent.setSubAltNameType(form)"></p> - </tr> - </table> - </tr> - - - <tr> - <td> - <b>Issuer Alternative Name:</b></p> - Activate extension: <input type="checkbox" name="IssuerAltName"></P> - Critical: <input type="checkbox" name="IssuerAltName-crit"> - <td> - <input type="radio" name="IssuerAltNameSourceRadio" value="auto"> Use the Subject Alternative Name from the Issuers Certificate</p> - <input type="radio" name="IssuerAltNameSourceRadio" value="man"> Use this Name: - <table> - <tr> - <td> - General Names:</p> - <select name="IssuerAltNameSelect" multiple size="10"> - </select></p></p> - <input type="button" name="IssuerAltName-add" value="Add" onClick="{parent.addIssuerAltName(this.form)}"> - <input type="button" name="IssuerAltName-delete" value="Delete" onClick="parent.deleteIssuerAltName(this.form)"> - </td><td> - <table><tr><td> - Name Type: </td></tr><tr><td> - <input type="radio" name="IssuerAltNameRadio" value="otherName" onClick="parent.setIssuerAltNameType(form)"> Other Name, - OID: <input type="text" name="IssuerAltNameOtherNameOID" size="6"> </td><td> - <input type="radio" name="IssuerAltNameRadio" value="rfc822Name" onClick="parent.setIssuerAltNameType(form)"> RFC 822 Name</td></tr><td> - <input type="radio" name="IssuerAltNameRadio" value="dnsName" onClick="parent.setIssuerAltNameType(form)"> DNS Name </td><td> - <input type="radio" name="IssuerAltNameRadio" value="x400" onClick="parent.setIssuerAltNameType(form)"> X400 Address</td></tr><td> - <input type="radio" name="IssuerAltNameRadio" value="directoryName" onClick="parent.setIssuerAltNameType(form)"> Directory Name</td><td> - <input type="radio" name="IssuerAltNameRadio" value="ediPartyName" onClick="parent.setIssuerAltNameType(form)"> EDI Party Name</td></tr><td> - <input type="radio" name="IssuerAltNameRadio" value="URL" onClick="parent.setIssuerAltNameType(form)"> Uniform Resource Locator</td><td> - <input type="radio" name="IssuerAltNameRadio" value="ipAddress" onClick="parent.setIssuerAltNameType(form)"> IP Address</td></tr><td> - <input type="radio" name="IssuerAltNameRadio" value="regID" onClick="parent.setIssuerAltNameType(form)"> Registered ID</td><td></tr> - </table> - Name: <input type="text" name="IssuerAltNameText"> - Binary Encoded: <input type="checkbox" name="IssuerAltNameDataType" value="binary" onClick="parent.setIssuerAltNameType(form)"></p> - </tr> - </table> - </tr> - - <tr> - <td> - <b>Name Constraints:</b></p> - Activate extension: <input type="checkbox" name="NameConstraints"></P> - <td> - <table> - <tr> - <td> - Name Constraints:</p> - - - <select name="NameConstraintSelect" multiple size="10"> - </select></p></p> - <input type="button" name="NameConstraint-add" value="Add" onClick="{parent.addNameConstraint(this.form)}"> - <input type="button" name="NameConstraint-delete" value="Delete" onClick="parent.deleteNameConstraint(this.form)"> - </td><td> - <table><tr><td> - Name Type: </td></tr><tr><td> - <input type="radio" name="NameConstraintRadio" value="otherName" onClick="parent.setNameConstraintNameType(form)"> Other Name, - OID: <input type="text" name="NameConstraintOtherNameOID" size="6"> </td><td> - <input type="radio" name="NameConstraintRadio" value="rfc822Name" onClick="parent.setNameConstraintNameType(form)"> RFC 822 Name</td></tr><td> - <input type="radio" name="NameConstraintRadio" value="dnsName" onClick="parent.setNameConstraintNameType(form)"> DNS Name </td><td> - <input type="radio" name="NameConstraintRadio" value="x400" onClick="parent.setNameConstraintNameType(form)"> X400 Address</td></tr><td> - <input type="radio" name="NameConstraintRadio" value="directoryName" onClick="parent.setNameConstraintNameType(form)"> Directory Name</td><td> - <input type="radio" name="NameConstraintRadio" value="ediPartyName" onClick="parent.setNameConstraintNameType(form)"> EDI Party Name</td></tr><td> - <input type="radio" name="NameConstraintRadio" value="URL" onClick="parent.setNameConstraintNameType(form)"> Uniform Resource Locator</td><td> - <input type="radio" name="NameConstraintRadio" value="ipAddress" onClick="parent.setNameConstraintNameType(form)"> IP Address</td></tr><td> - <input type="radio" name="NameConstraintRadio" value="regID" onClick="parent.setNameConstraintNameType(form)"> Registered ID</td><td></tr> - </table> - Name: <input type="text" name="NameConstraintText"> - Binary Encoded: <input type="checkbox" name="NameConstraintNameDataType" value="binary" onClick="parent.setNameConstraintNameType(form)"></p> - Constraint type:<p> - <dd><input type="radio" name="NameConstraintTypeRadio" value="permited"> permited<p> - <dd><input type="radio" name="NameConstraintTypeRadio" value="excluded"> excluded<p> - Minimum: <input type="text" name="NameConstraintMin" size="8" maxlength="8"></p> - Maximum: <input type="text" name="NameConstraintMax" size="8" maxlength="8"></p> - - - - </tr> - </table> - </tr> - </table> - </form> - - - - - - - - - - diff --git a/security/nss/cmd/certcgi/certcgi.c b/security/nss/cmd/certcgi/certcgi.c deleted file mode 100644 index 35409e250..000000000 --- a/security/nss/cmd/certcgi/certcgi.c +++ /dev/null @@ -1,2246 +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/. */ - -/* Cert-O-Matic CGI */ - -#include "nspr.h" -#include "prtypes.h" -#include "prtime.h" -#include "prlong.h" - -#include "pk11func.h" -#include "cert.h" -#include "cryptohi.h" -#include "secoid.h" -#include "secder.h" -#include "genname.h" -#include "xconst.h" -#include "secutil.h" -#include "pk11pqg.h" -#include "certxutl.h" -#include "nss.h" - -/* #define TEST 1 */ -/* #define FILEOUT 1 */ -/* #define OFFLINE 1 */ -#define START_FIELDS 100 -#define PREFIX_LEN 6 -#define SERIAL_FILE "../serial" -#define DB_DIRECTORY ".." - -static char *progName; - -typedef struct PairStr Pair; - -struct PairStr { - char *name; - char *data; -}; - -char prefix[PREFIX_LEN]; - -const SEC_ASN1Template CERTIA5TypeTemplate[] = { - { SEC_ASN1_IA5_STRING } -}; - -SECKEYPrivateKey *privkeys[9] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL }; - -#ifdef notdef -const SEC_ASN1Template CERT_GeneralNameTemplate[] = { - { SEC_ASN1_SEQUENCE_OF, 0, SEC_AnyTemplate } -}; -#endif - -static void -error_out(char *error_string) -{ - printf("Content-type: text/plain\n\n"); - printf("%s", error_string); - fflush(stderr); - fflush(stdout); - exit(1); -} - -static void -error_allocate(void) -{ - error_out("ERROR: Unable to allocate memory"); -} - -static char * -make_copy_string(char *read_pos, - int length, - char sentinal_value) -/* copys string from to a new string it creates and - returns a pointer to the new string */ -{ - int remaining = length; - char *write_pos; - char *new; - - new = write_pos = (char *)PORT_Alloc(length); - if (new == NULL) { - error_allocate(); - } - while (*read_pos != sentinal_value) { - if (remaining == 1) { - remaining += length; - length = length * 2; - new = PORT_Realloc(new, length); - if (new == NULL) { - error_allocate(); - } - write_pos = new + length - remaining; - } - *write_pos = *read_pos; - ++write_pos; - ++read_pos; - remaining = remaining - 1; - } - *write_pos = '\0'; - return new; -} - -static SECStatus -clean_input(Pair *data) -/* converts the non-alphanumeric characters in a form post - from hex codes back to characters */ -{ - int length; - int hi_digit; - int low_digit; - char character; - char *begin_pos; - char *read_pos; - char *write_pos; - PRBool name = PR_TRUE; - - begin_pos = data->name; - while (begin_pos != NULL) { - length = strlen(begin_pos); - read_pos = write_pos = begin_pos; - while ((read_pos - begin_pos) < length) { - if (*read_pos == '+') { - *read_pos = ' '; - } - if (*read_pos == '%') { - hi_digit = *(read_pos + 1); - low_digit = *(read_pos + 2); - read_pos += 3; - if (isdigit(hi_digit)) { - hi_digit = hi_digit - '0'; - } else { - hi_digit = toupper(hi_digit); - if (isxdigit(hi_digit)) { - hi_digit = (hi_digit - 'A') + 10; - } else { - error_out("ERROR: Form data incorrectly formated"); - } - } - if (isdigit(low_digit)) { - low_digit = low_digit - '0'; - } else { - low_digit = toupper(low_digit); - if ((low_digit >= 'A') && (low_digit <= 'F')) { - low_digit = (low_digit - 'A') + 10; - } else { - error_out("ERROR: Form data incorrectly formated"); - } - } - character = (hi_digit << 4) | low_digit; - if (character != 10) { - *write_pos = character; - ++write_pos; - } - } else { - *write_pos = *read_pos; - ++write_pos; - ++read_pos; - } - } - *write_pos = '\0'; - if (name == PR_TRUE) { - begin_pos = data->data; - name = PR_FALSE; - } else { - data++; - begin_pos = data->name; - name = PR_TRUE; - } - } - return SECSuccess; -} - -static char * -make_name(char *new_data) -/* gets the next field name in the input string and returns - a pointer to a string containing a copy of it */ -{ - int length = 20; - char *name; - - name = make_copy_string(new_data, length, '='); - return name; -} - -static char * -make_data(char *new_data) -/* gets the data for the next field in the input string - and returns a pointer to a string containing it */ -{ - int length = 100; - char *data; - char *read_pos; - - read_pos = new_data; - while (*(read_pos - 1) != '=') { - ++read_pos; - } - data = make_copy_string(read_pos, length, '&'); - return data; -} - -static Pair -make_pair(char *new_data) -/* makes a pair name/data pair from the input string */ -{ - Pair temp; - - temp.name = make_name(new_data); - temp.data = make_data(new_data); - return temp; -} - -static Pair * -make_datastruct(char *data, int len) -/* parses the input from the form post into a data - structure of field name/data pairs */ -{ - Pair *datastruct; - Pair *current; - char *curr_pos; - int fields = START_FIELDS; - int remaining = START_FIELDS; - - curr_pos = data; - datastruct = current = (Pair *)PORT_Alloc(fields * sizeof(Pair)); - if (datastruct == NULL) { - error_allocate(); - } - while (curr_pos - data < len) { - if (remaining == 1) { - remaining += fields; - fields = fields * 2; - datastruct = (Pair *)PORT_Realloc(datastruct, fields * - sizeof(Pair)); - if (datastruct == NULL) { - error_allocate(); - } - current = datastruct + (fields - remaining); - } - *current = make_pair(curr_pos); - while (*curr_pos != '&') { - ++curr_pos; - } - ++curr_pos; - ++current; - remaining = remaining - 1; - } - current->name = NULL; - return datastruct; -} - -static char * -return_name(Pair *data_struct, - int n) -/* returns a pointer to the name of the nth - (starting from 0) item in the data structure */ -{ - char *name; - - if ((data_struct + n)->name != NULL) { - name = (data_struct + n)->name; - return name; - } else { - return NULL; - } -} - -static char * -return_data(Pair *data_struct, int n) -/* returns a pointer to the data of the nth (starting from 0) - itme in the data structure */ -{ - char *data; - - data = (data_struct + n)->data; - return data; -} - -static char * -add_prefix(char *field_name) -{ - extern char prefix[PREFIX_LEN]; - int i = 0; - char *rv; - char *write; - - rv = write = PORT_Alloc(PORT_Strlen(prefix) + PORT_Strlen(field_name) + 1); - for (i = 0; i < PORT_Strlen(prefix); i++) { - *write = prefix[i]; - write++; - } - *write = '\0'; - rv = PORT_Strcat(rv, field_name); - return rv; -} - -static char * -find_field(Pair *data, - char *field_name, - PRBool add_pre) -/* returns a pointer to the data of the first pair - thats name matches the string it is passed */ -{ - int i = 0; - char *retrieved; - int found = 0; - - if (add_pre) { - field_name = add_prefix(field_name); - } - while (return_name(data, i) != NULL) { - if (PORT_Strcmp(return_name(data, i), field_name) == 0) { - retrieved = return_data(data, i); - found = 1; - break; - } - i++; - } - if (!found) { - retrieved = NULL; - } - return retrieved; -} - -static PRBool -find_field_bool(Pair *data, - char *fieldname, - PRBool add_pre) -{ - char *rv; - - rv = find_field(data, fieldname, add_pre); - - if ((rv != NULL) && (PORT_Strcmp(rv, "true")) == 0) { - return PR_TRUE; - } else { - return PR_FALSE; - } -} - -static CERTCertificateRequest * -makeCertReq(Pair *form_data, - int which_priv_key) -/* makes and encodes a certrequest */ -{ - - PK11SlotInfo *slot; - CERTCertificateRequest *certReq = NULL; - CERTSubjectPublicKeyInfo *spki; - SECKEYPrivateKey *privkey = NULL; - SECKEYPublicKey *pubkey = NULL; - CERTName *name; - char *key; - extern SECKEYPrivateKey *privkeys[9]; - int keySizeInBits; - char *challenge = "foo"; - SECStatus rv = SECSuccess; - PQGParams *pqgParams = NULL; - PQGVerify *pqgVfy = NULL; - - name = CERT_AsciiToName(find_field(form_data, "subject", PR_TRUE)); - if (name == NULL) { - error_out("ERROR: Unable to create Subject Name"); - } - key = find_field(form_data, "key", PR_TRUE); - if (key == NULL) { - switch (*find_field(form_data, "keysize", PR_TRUE)) { - case '0': - keySizeInBits = 2048; - break; - case '1': - keySizeInBits = 1024; - break; - case '2': - keySizeInBits = 512; - break; - default: - error_out("ERROR: Unsupported Key length selected"); - } - if (find_field_bool(form_data, "keyType-dsa", PR_TRUE)) { - rv = PK11_PQG_ParamGen(keySizeInBits, &pqgParams, &pqgVfy); - if (rv != SECSuccess) { - error_out("ERROR: Unable to generate PQG parameters"); - } - slot = PK11_GetBestSlot(CKM_DSA_KEY_PAIR_GEN, NULL); - privkey = PK11_GenerateKeyPair(slot, CKM_DSA_KEY_PAIR_GEN, - pqgParams, &pubkey, PR_FALSE, - PR_TRUE, NULL); - } else { - privkey = SECKEY_CreateRSAPrivateKey(keySizeInBits, &pubkey, NULL); - } - privkeys[which_priv_key] = privkey; - spki = SECKEY_CreateSubjectPublicKeyInfo(pubkey); - } else { - spki = SECKEY_ConvertAndDecodePublicKeyAndChallenge(key, challenge, - NULL); - if (spki == NULL) { - error_out("ERROR: Unable to decode Public Key and Challenge String"); - } - } - certReq = CERT_CreateCertificateRequest(name, spki, NULL); - if (certReq == NULL) { - error_out("ERROR: Unable to create Certificate Request"); - } - if (pubkey != NULL) { - SECKEY_DestroyPublicKey(pubkey); - } - if (spki != NULL) { - SECKEY_DestroySubjectPublicKeyInfo(spki); - } - if (pqgParams != NULL) { - PK11_PQG_DestroyParams(pqgParams); - } - if (pqgVfy != NULL) { - PK11_PQG_DestroyVerify(pqgVfy); - } - return certReq; -} - -static CERTCertificate * -MakeV1Cert(CERTCertDBHandle *handle, - CERTCertificateRequest *req, - char *issuerNameStr, - PRBool selfsign, - int serialNumber, - int warpmonths, - Pair *data) -{ - CERTCertificate *issuerCert = NULL; - CERTValidity *validity; - CERTCertificate *cert = NULL; - PRExplodedTime printableTime; - PRTime now, - after; - if (!selfsign) { - issuerCert = CERT_FindCertByNameString(handle, issuerNameStr); - if (!issuerCert) { - error_out("ERROR: Could not find issuer's certificate"); - return NULL; - } - } - if (find_field_bool(data, "manValidity", PR_TRUE)) { - (void)DER_AsciiToTime(&now, find_field(data, "notBefore", PR_TRUE)); - } else { - now = PR_Now(); - } - PR_ExplodeTime(now, PR_GMTParameters, &printableTime); - if (warpmonths) { - printableTime.tm_month += warpmonths; - now = PR_ImplodeTime(&printableTime); - PR_ExplodeTime(now, PR_GMTParameters, &printableTime); - } - if (find_field_bool(data, "manValidity", PR_TRUE)) { - (void)DER_AsciiToTime(&after, find_field(data, "notAfter", PR_TRUE)); - PR_ExplodeTime(after, PR_GMTParameters, &printableTime); - } else { - printableTime.tm_month += 3; - after = PR_ImplodeTime(&printableTime); - } - /* note that the time is now in micro-second unit */ - validity = CERT_CreateValidity(now, after); - - if (selfsign) { - cert = CERT_CreateCertificate(serialNumber, &(req->subject), validity, req); - } else { - cert = CERT_CreateCertificate(serialNumber, &(issuerCert->subject), validity, req); - } - - CERT_DestroyValidity(validity); - if (issuerCert) { - CERT_DestroyCertificate(issuerCert); - } - return (cert); -} - -static int -get_serial_number(Pair *data) -{ - int serial = 0; - int error; - char *filename = SERIAL_FILE; - char *SN; - FILE *serialFile; - - if (find_field_bool(data, "serial-auto", PR_TRUE)) { - serialFile = fopen(filename, "r"); - if (serialFile != NULL) { - size_t nread = fread(&serial, sizeof(int), 1, serialFile); - if (ferror(serialFile) != 0 || nread != 1) { - error_out("Error: Unable to read serial number file"); - } - if (serial == -1) { - serial = 21; - } - fclose(serialFile); - ++serial; - serialFile = fopen(filename, "w"); - if (serialFile == NULL) { - error_out("ERROR: Unable to open serial number file for writing"); - } - fwrite(&serial, sizeof(int), 1, serialFile); - if (ferror(serialFile) != 0) { - error_out("Error: Unable to write to serial number file"); - } - } else { - fclose(serialFile); - serialFile = fopen(filename, "w"); - if (serialFile == NULL) { - error_out("ERROR: Unable to open serial number file"); - } - serial = 21; - fwrite(&serial, sizeof(int), 1, serialFile); - if (ferror(serialFile) != 0) { - error_out("Error: Unable to write to serial number file"); - } - error = ferror(serialFile); - if (error != 0) { - error_out("ERROR: Unable to write to serial file"); - } - } - fclose(serialFile); - } else { - SN = find_field(data, "serial_value", PR_TRUE); - while (*SN != '\0') { - serial = serial * 16; - if ((*SN >= 'A') && (*SN <= 'F')) { - serial += *SN - 'A' + 10; - } else { - if ((*SN >= 'a') && (*SN <= 'f')) { - serial += *SN - 'a' + 10; - } else { - serial += *SN - '0'; - } - } - ++SN; - } - } - return serial; -} - -typedef SECStatus (*EXTEN_VALUE_ENCODER)(PLArenaPool *extHandle, void *value, SECItem *encodedValue); - -static SECStatus -EncodeAndAddExtensionValue( - PLArenaPool *arena, - void *extHandle, - void *value, - PRBool criticality, - int extenType, - EXTEN_VALUE_ENCODER EncodeValueFn) -{ - SECItem encodedValue; - SECStatus rv; - - encodedValue.data = NULL; - encodedValue.len = 0; - rv = (*EncodeValueFn)(arena, value, &encodedValue); - if (rv != SECSuccess) { - error_out("ERROR: Unable to encode extension value"); - } - rv = CERT_AddExtension(extHandle, extenType, &encodedValue, criticality, PR_TRUE); - return (rv); -} - -static SECStatus -AddKeyUsage(void *extHandle, - Pair *data) -{ - SECItem bitStringValue; - unsigned char keyUsage = 0x0; - - if (find_field_bool(data, "keyUsage-digitalSignature", PR_TRUE)) { - keyUsage |= (0x80 >> 0); - } - if (find_field_bool(data, "keyUsage-nonRepudiation", PR_TRUE)) { - keyUsage |= (0x80 >> 1); - } - if (find_field_bool(data, "keyUsage-keyEncipherment", PR_TRUE)) { - keyUsage |= (0x80 >> 2); - } - if (find_field_bool(data, "keyUsage-dataEncipherment", PR_TRUE)) { - keyUsage |= (0x80 >> 3); - } - if (find_field_bool(data, "keyUsage-keyAgreement", PR_TRUE)) { - keyUsage |= (0x80 >> 4); - } - if (find_field_bool(data, "keyUsage-keyCertSign", PR_TRUE)) { - keyUsage |= (0x80 >> 5); - } - if (find_field_bool(data, "keyUsage-cRLSign", PR_TRUE)) { - keyUsage |= (0x80 >> 6); - } - - bitStringValue.data = &keyUsage; - bitStringValue.len = 1; - - return (CERT_EncodeAndAddBitStrExtension(extHandle, SEC_OID_X509_KEY_USAGE, &bitStringValue, - (find_field_bool(data, "keyUsage-crit", PR_TRUE)))); -} - -static CERTOidSequence * -CreateOidSequence(void) -{ - CERTOidSequence *rv = (CERTOidSequence *)NULL; - PLArenaPool *arena = (PLArenaPool *)NULL; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ((PLArenaPool *)NULL == arena) { - goto loser; - } - - rv = (CERTOidSequence *)PORT_ArenaZAlloc(arena, sizeof(CERTOidSequence)); - if ((CERTOidSequence *)NULL == rv) { - goto loser; - } - - rv->oids = (SECItem **)PORT_ArenaZAlloc(arena, sizeof(SECItem *)); - if ((SECItem **)NULL == rv->oids) { - goto loser; - } - - rv->arena = arena; - return rv; - -loser: - if ((PLArenaPool *)NULL != arena) { - PORT_FreeArena(arena, PR_FALSE); - } - - return (CERTOidSequence *)NULL; -} - -static SECStatus -AddOidToSequence(CERTOidSequence *os, SECOidTag oidTag) -{ - SECItem **oids; - PRUint32 count = 0; - SECOidData *od; - - od = SECOID_FindOIDByTag(oidTag); - if ((SECOidData *)NULL == od) { - return SECFailure; - } - - for (oids = os->oids; (SECItem *)NULL != *oids; oids++) { - count++; - } - - /* ArenaZRealloc */ - - { - PRUint32 i; - - oids = (SECItem **)PORT_ArenaZAlloc(os->arena, sizeof(SECItem *) * (count + 2)); - if ((SECItem **)NULL == oids) { - return SECFailure; - } - - for (i = 0; i < count; i++) { - oids[i] = os->oids[i]; - } - - /* ArenaZFree(os->oids); */ - } - - os->oids = oids; - os->oids[count] = &od->oid; - - return SECSuccess; -} - -static SECItem * -EncodeOidSequence(CERTOidSequence *os) -{ - SECItem *rv; - extern const SEC_ASN1Template CERT_OidSeqTemplate[]; - - rv = (SECItem *)PORT_ArenaZAlloc(os->arena, sizeof(SECItem)); - if ((SECItem *)NULL == rv) { - goto loser; - } - - if (!SEC_ASN1EncodeItem(os->arena, rv, os, CERT_OidSeqTemplate)) { - goto loser; - } - - return rv; - -loser: - return (SECItem *)NULL; -} - -static SECStatus -AddExtKeyUsage(void *extHandle, Pair *data) -{ - SECStatus rv; - CERTOidSequence *os; - SECItem *value; - PRBool crit; - - os = CreateOidSequence(); - if ((CERTOidSequence *)NULL == os) { - return SECFailure; - } - - if (find_field_bool(data, "extKeyUsage-serverAuth", PR_TRUE)) { - rv = AddOidToSequence(os, SEC_OID_EXT_KEY_USAGE_SERVER_AUTH); - if (SECSuccess != rv) - goto loser; - } - - if (find_field_bool(data, "extKeyUsage-msTrustListSign", PR_TRUE)) { - rv = AddOidToSequence(os, SEC_OID_MS_EXT_KEY_USAGE_CTL_SIGNING); - if (SECSuccess != rv) - goto loser; - } - - if (find_field_bool(data, "extKeyUsage-clientAuth", PR_TRUE)) { - rv = AddOidToSequence(os, SEC_OID_EXT_KEY_USAGE_CLIENT_AUTH); - if (SECSuccess != rv) - goto loser; - } - - if (find_field_bool(data, "extKeyUsage-codeSign", PR_TRUE)) { - rv = AddOidToSequence(os, SEC_OID_EXT_KEY_USAGE_CODE_SIGN); - if (SECSuccess != rv) - goto loser; - } - - if (find_field_bool(data, "extKeyUsage-emailProtect", PR_TRUE)) { - rv = AddOidToSequence(os, SEC_OID_EXT_KEY_USAGE_EMAIL_PROTECT); - if (SECSuccess != rv) - goto loser; - } - - if (find_field_bool(data, "extKeyUsage-timeStamp", PR_TRUE)) { - rv = AddOidToSequence(os, SEC_OID_EXT_KEY_USAGE_TIME_STAMP); - if (SECSuccess != rv) - goto loser; - } - - if (find_field_bool(data, "extKeyUsage-ocspResponder", PR_TRUE)) { - rv = AddOidToSequence(os, SEC_OID_OCSP_RESPONDER); - if (SECSuccess != rv) - goto loser; - } - - if (find_field_bool(data, "extKeyUsage-NS-govtApproved", PR_TRUE)) { - rv = AddOidToSequence(os, SEC_OID_NS_KEY_USAGE_GOVT_APPROVED); - if (SECSuccess != rv) - goto loser; - } - - value = EncodeOidSequence(os); - - crit = find_field_bool(data, "extKeyUsage-crit", PR_TRUE); - - rv = CERT_AddExtension(extHandle, SEC_OID_X509_EXT_KEY_USAGE, value, - crit, PR_TRUE); -/*FALLTHROUGH*/ -loser: - CERT_DestroyOidSequence(os); - return rv; -} - -static SECStatus -AddSubKeyID(void *extHandle, - Pair *data, - CERTCertificate *subjectCert) -{ - SECItem encodedValue; - SECStatus rv; - char *read; - char *write; - char *first; - char character; - int high_digit = 0, - low_digit = 0; - int len; - PRBool odd = PR_FALSE; - - encodedValue.data = NULL; - encodedValue.len = 0; - first = read = write = find_field(data, "subjectKeyIdentifier-text", - PR_TRUE); - len = PORT_Strlen(first); - odd = ((len % 2) != 0) ? PR_TRUE : PR_FALSE; - if (find_field_bool(data, "subjectKeyIdentifier-radio-hex", PR_TRUE)) { - if (odd) { - error_out("ERROR: Improperly formated subject key identifier, hex values must be expressed as an octet string"); - } - while (*read != '\0') { - if (!isxdigit(*read)) { - error_out("ERROR: Improperly formated subject key identifier"); - } - *read = toupper(*read); - if ((*read >= 'A') && (*read <= 'F')) { - high_digit = *read - 'A' + 10; - } else { - high_digit = *read - '0'; - } - ++read; - if (!isxdigit(*read)) { - error_out("ERROR: Improperly formated subject key identifier"); - } - *read = toupper(*read); - if ((*read >= 'A') && (*read <= 'F')) { - low_digit = *(read) - 'A' + 10; - } else { - low_digit = *(read) - '0'; - } - character = (high_digit << 4) | low_digit; - *write = character; - ++write; - ++read; - } - *write = '\0'; - len = write - first; - } - subjectCert->subjectKeyID.data = (unsigned char *)find_field(data, "subjectKeyIdentifier-text", PR_TRUE); - subjectCert->subjectKeyID.len = len; - rv = CERT_EncodeSubjectKeyID(NULL, &subjectCert->subjectKeyID, &encodedValue); - if (rv) { - return (rv); - } - return (CERT_AddExtension(extHandle, SEC_OID_X509_SUBJECT_KEY_ID, - &encodedValue, PR_FALSE, PR_TRUE)); -} - -static SECStatus -AddAuthKeyID(void *extHandle, - Pair *data, - char *issuerNameStr, - CERTCertDBHandle *handle) -{ - CERTAuthKeyID *authKeyID = NULL; - PLArenaPool *arena = NULL; - SECStatus rv = SECSuccess; - CERTCertificate *issuerCert = NULL; - CERTGeneralName *genNames; - CERTName *directoryName = NULL; - - issuerCert = CERT_FindCertByNameString(handle, issuerNameStr); - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if (!arena) { - error_allocate(); - } - - authKeyID = PORT_ArenaZAlloc(arena, sizeof(CERTAuthKeyID)); - if (authKeyID == NULL) { - error_allocate(); - } - if (find_field_bool(data, "authorityKeyIdentifier-radio-keyIdentifier", - PR_TRUE)) { - authKeyID->keyID.data = PORT_ArenaAlloc(arena, PORT_Strlen((char *)issuerCert->subjectKeyID.data)); - if (authKeyID->keyID.data == NULL) { - error_allocate(); - } - PORT_Memcpy(authKeyID->keyID.data, issuerCert->subjectKeyID.data, - authKeyID->keyID.len = - PORT_Strlen((char *)issuerCert->subjectKeyID.data)); - } else { - - PORT_Assert(arena); - genNames = (CERTGeneralName *)PORT_ArenaZAlloc(arena, (sizeof(CERTGeneralName))); - if (genNames == NULL) { - error_allocate(); - } - genNames->l.next = genNames->l.prev = &(genNames->l); - genNames->type = certDirectoryName; - - directoryName = CERT_AsciiToName(issuerCert->subjectName); - if (!directoryName) { - error_out("ERROR: Unable to create Directory Name"); - } - rv = CERT_CopyName(arena, &genNames->name.directoryName, - directoryName); - CERT_DestroyName(directoryName); - if (rv != SECSuccess) { - error_out("ERROR: Unable to copy Directory Name"); - } - authKeyID->authCertIssuer = genNames; - if (authKeyID->authCertIssuer == NULL && SECFailure == PORT_GetError()) { - error_out("ERROR: Unable to get Issuer General Name for Authority Key ID Extension"); - } - authKeyID->authCertSerialNumber = issuerCert->serialNumber; - } - rv = EncodeAndAddExtensionValue(arena, extHandle, authKeyID, PR_FALSE, - SEC_OID_X509_AUTH_KEY_ID, - (EXTEN_VALUE_ENCODER) - CERT_EncodeAuthKeyID); - if (arena) { - PORT_FreeArena(arena, PR_FALSE); - } - return (rv); -} - -static SECStatus -AddPrivKeyUsagePeriod(void *extHandle, - Pair *data, - CERTCertificate *cert) -{ - char *notBeforeStr; - char *notAfterStr; - PLArenaPool *arena = NULL; - SECStatus rv = SECSuccess; - CERTPrivKeyUsagePeriod *pkup; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if (!arena) { - error_allocate(); - } - pkup = PORT_ArenaZNew(arena, CERTPrivKeyUsagePeriod); - if (pkup == NULL) { - error_allocate(); - } - notBeforeStr = (char *)PORT_Alloc(16); - if (notBeforeStr == NULL) { - error_allocate(); - } - notAfterStr = (char *)PORT_Alloc(16); - if (notAfterStr == NULL) { - error_allocate(); - } - *notBeforeStr = '\0'; - *notAfterStr = '\0'; - pkup->arena = arena; - pkup->notBefore.len = 0; - pkup->notBefore.data = NULL; - pkup->notAfter.len = 0; - pkup->notAfter.data = NULL; - if (find_field_bool(data, "privKeyUsagePeriod-radio-notBefore", PR_TRUE) || - find_field_bool(data, "privKeyUsagePeriod-radio-both", PR_TRUE)) { - pkup->notBefore.len = 15; - pkup->notBefore.data = (unsigned char *)notBeforeStr; - if (find_field_bool(data, "privKeyUsagePeriod-notBefore-radio-manual", - PR_TRUE)) { - PORT_Strcat(notBeforeStr, find_field(data, - "privKeyUsagePeriod-notBefore-year", - PR_TRUE)); - PORT_Strcat(notBeforeStr, find_field(data, - "privKeyUsagePeriod-notBefore-month", - PR_TRUE)); - PORT_Strcat(notBeforeStr, find_field(data, - "privKeyUsagePeriod-notBefore-day", - PR_TRUE)); - PORT_Strcat(notBeforeStr, find_field(data, - "privKeyUsagePeriod-notBefore-hour", - PR_TRUE)); - PORT_Strcat(notBeforeStr, find_field(data, - "privKeyUsagePeriod-notBefore-minute", - PR_TRUE)); - PORT_Strcat(notBeforeStr, find_field(data, - "privKeyUsagePeriod-notBefore-second", - PR_TRUE)); - if ((*(notBeforeStr + 14) != '\0') || - (!isdigit(*(notBeforeStr + 13))) || - (*(notBeforeStr + 12) >= '5' && *(notBeforeStr + 12) <= '0') || - (!isdigit(*(notBeforeStr + 11))) || - (*(notBeforeStr + 10) >= '5' && *(notBeforeStr + 10) <= '0') || - (!isdigit(*(notBeforeStr + 9))) || - (*(notBeforeStr + 8) >= '2' && *(notBeforeStr + 8) <= '0') || - (!isdigit(*(notBeforeStr + 7))) || - (*(notBeforeStr + 6) >= '3' && *(notBeforeStr + 6) <= '0') || - (!isdigit(*(notBeforeStr + 5))) || - (*(notBeforeStr + 4) >= '1' && *(notBeforeStr + 4) <= '0') || - (!isdigit(*(notBeforeStr + 3))) || - (!isdigit(*(notBeforeStr + 2))) || - (!isdigit(*(notBeforeStr + 1))) || - (!isdigit(*(notBeforeStr + 0))) || - (*(notBeforeStr + 8) == '2' && *(notBeforeStr + 9) >= '4') || - (*(notBeforeStr + 6) == '3' && *(notBeforeStr + 7) >= '1') || - (*(notBeforeStr + 4) == '1' && *(notBeforeStr + 5) >= '2')) { - error_out("ERROR: Improperly formated private key usage period"); - } - *(notBeforeStr + 14) = 'Z'; - *(notBeforeStr + 15) = '\0'; - } else { - if ((*(cert->validity.notBefore.data) > '5') || - ((*(cert->validity.notBefore.data) == '5') && - (*(cert->validity.notBefore.data + 1) != '0'))) { - PORT_Strcat(notBeforeStr, "19"); - } else { - PORT_Strcat(notBeforeStr, "20"); - } - PORT_Strcat(notBeforeStr, (char *)cert->validity.notBefore.data); - } - } - if (find_field_bool(data, "privKeyUsagePeriod-radio-notAfter", PR_TRUE) || - find_field_bool(data, "privKeyUsagePeriod-radio-both", PR_TRUE)) { - pkup->notAfter.len = 15; - pkup->notAfter.data = (unsigned char *)notAfterStr; - PORT_Strcat(notAfterStr, find_field(data, "privKeyUsagePeriod-notAfter-year", - PR_TRUE)); - PORT_Strcat(notAfterStr, find_field(data, "privKeyUsagePeriod-notAfter-month", - PR_TRUE)); - PORT_Strcat(notAfterStr, find_field(data, "privKeyUsagePeriod-notAfter-day", - PR_TRUE)); - PORT_Strcat(notAfterStr, find_field(data, "privKeyUsagePeriod-notAfter-hour", - PR_TRUE)); - PORT_Strcat(notAfterStr, find_field(data, "privKeyUsagePeriod-notAfter-minute", - PR_TRUE)); - PORT_Strcat(notAfterStr, find_field(data, "privKeyUsagePeriod-notAfter-second", - PR_TRUE)); - if ((*(notAfterStr + 14) != '\0') || - (!isdigit(*(notAfterStr + 13))) || - (*(notAfterStr + 12) >= '5' && *(notAfterStr + 12) <= '0') || - (!isdigit(*(notAfterStr + 11))) || - (*(notAfterStr + 10) >= '5' && *(notAfterStr + 10) <= '0') || - (!isdigit(*(notAfterStr + 9))) || - (*(notAfterStr + 8) >= '2' && *(notAfterStr + 8) <= '0') || - (!isdigit(*(notAfterStr + 7))) || - (*(notAfterStr + 6) >= '3' && *(notAfterStr + 6) <= '0') || - (!isdigit(*(notAfterStr + 5))) || - (*(notAfterStr + 4) >= '1' && *(notAfterStr + 4) <= '0') || - (!isdigit(*(notAfterStr + 3))) || - (!isdigit(*(notAfterStr + 2))) || - (!isdigit(*(notAfterStr + 1))) || - (!isdigit(*(notAfterStr + 0))) || - (*(notAfterStr + 8) == '2' && *(notAfterStr + 9) >= '4') || - (*(notAfterStr + 6) == '3' && *(notAfterStr + 7) >= '1') || - (*(notAfterStr + 4) == '1' && *(notAfterStr + 5) >= '2')) { - error_out("ERROR: Improperly formated private key usage period"); - } - *(notAfterStr + 14) = 'Z'; - *(notAfterStr + 15) = '\0'; - } - - PORT_Assert(arena); - - rv = EncodeAndAddExtensionValue(arena, extHandle, pkup, - find_field_bool(data, - "privKeyUsagePeriod-crit", - PR_TRUE), - SEC_OID_X509_PRIVATE_KEY_USAGE_PERIOD, - (EXTEN_VALUE_ENCODER) - CERT_EncodePrivateKeyUsagePeriod); - PORT_FreeArena(arena, PR_FALSE); - PORT_Free(notBeforeStr); - PORT_Free(notAfterStr); - return (rv); -} - -static SECStatus -AddBasicConstraint(void *extHandle, - Pair *data) -{ - CERTBasicConstraints basicConstraint; - SECItem encodedValue; - SECStatus rv; - - encodedValue.data = NULL; - encodedValue.len = 0; - basicConstraint.pathLenConstraint = CERT_UNLIMITED_PATH_CONSTRAINT; - basicConstraint.isCA = (find_field_bool(data, "basicConstraints-cA-radio-CA", - PR_TRUE)); - if (find_field_bool(data, "basicConstraints-pathLengthConstraint", PR_TRUE)) { - basicConstraint.pathLenConstraint = atoi(find_field(data, "basicConstraints-pathLengthConstraint-text", - PR_TRUE)); - } - - rv = CERT_EncodeBasicConstraintValue(NULL, &basicConstraint, - &encodedValue); - if (rv) - return (rv); - rv = CERT_AddExtension(extHandle, SEC_OID_X509_BASIC_CONSTRAINTS, - &encodedValue, - (find_field_bool(data, "basicConstraints-crit", - PR_TRUE)), - PR_TRUE); - - PORT_Free(encodedValue.data); - return (rv); -} - -static SECStatus -AddNscpCertType(void *extHandle, - Pair *data) -{ - SECItem bitStringValue; - unsigned char CertType = 0x0; - - if (find_field_bool(data, "netscape-cert-type-ssl-client", PR_TRUE)) { - CertType |= (0x80 >> 0); - } - if (find_field_bool(data, "netscape-cert-type-ssl-server", PR_TRUE)) { - CertType |= (0x80 >> 1); - } - if (find_field_bool(data, "netscape-cert-type-smime", PR_TRUE)) { - CertType |= (0x80 >> 2); - } - if (find_field_bool(data, "netscape-cert-type-object-signing", PR_TRUE)) { - CertType |= (0x80 >> 3); - } - if (find_field_bool(data, "netscape-cert-type-reserved", PR_TRUE)) { - CertType |= (0x80 >> 4); - } - if (find_field_bool(data, "netscape-cert-type-ssl-ca", PR_TRUE)) { - CertType |= (0x80 >> 5); - } - if (find_field_bool(data, "netscape-cert-type-smime-ca", PR_TRUE)) { - CertType |= (0x80 >> 6); - } - if (find_field_bool(data, "netscape-cert-type-object-signing-ca", PR_TRUE)) { - CertType |= (0x80 >> 7); - } - - bitStringValue.data = &CertType; - bitStringValue.len = 1; - - return (CERT_EncodeAndAddBitStrExtension(extHandle, SEC_OID_NS_CERT_EXT_CERT_TYPE, &bitStringValue, - (find_field_bool(data, "netscape-cert-type-crit", PR_TRUE)))); -} - -static SECStatus -add_IA5StringExtension(void *extHandle, - char *string, - PRBool crit, - int idtag) -{ - SECItem encodedValue; - SECStatus rv; - - encodedValue.data = NULL; - encodedValue.len = 0; - - rv = CERT_EncodeIA5TypeExtension(NULL, string, &encodedValue); - if (rv) { - return (rv); - } - return (CERT_AddExtension(extHandle, idtag, &encodedValue, crit, PR_TRUE)); -} - -static SECItem * -string_to_oid(char *string) -{ - int i; - int length = 20; - int remaining; - int first_value; - int second_value; - int value; - int oidLength; - unsigned char *oidString; - unsigned char *write; - unsigned char *read; - unsigned char *temp; - SECItem *oid; - - remaining = length; - i = 0; - while (*string == ' ') { - string++; - } - while (isdigit(*(string + i))) { - i++; - } - if (*(string + i) == '.') { - *(string + i) = '\0'; - } else { - error_out("ERROR: Improperly formated OID"); - } - first_value = atoi(string); - if (first_value < 0 || first_value > 2) { - error_out("ERROR: Improperly formated OID"); - } - string += i + 1; - i = 0; - while (isdigit(*(string + i))) { - i++; - } - if (*(string + i) == '.') { - *(string + i) = '\0'; - } else { - error_out("ERROR: Improperly formated OID"); - } - second_value = atoi(string); - if (second_value < 0 || second_value > 39) { - error_out("ERROR: Improperly formated OID"); - } - oidString = PORT_ZAlloc(2); - *oidString = (first_value * 40) + second_value; - *(oidString + 1) = '\0'; - oidLength = 1; - string += i + 1; - i = 0; - temp = write = PORT_ZAlloc(length); - while (*string != '\0') { - value = 0; - while (isdigit(*(string + i))) { - i++; - } - if (*(string + i) == '\0') { - value = atoi(string); - string += i; - } else { - if (*(string + i) == '.') { - *(string + i) = '\0'; - value = atoi(string); - string += i + 1; - } else { - *(string + i) = '\0'; - i++; - value = atoi(string); - while (*(string + i) == ' ') - i++; - if (*(string + i) != '\0') { - error_out("ERROR: Improperly formated OID"); - } - } - } - i = 0; - while (value != 0) { - if (remaining < 1) { - remaining += length; - length = length * 2; - temp = PORT_Realloc(temp, length); - write = temp + length - remaining; - } - *write = (value & 0x7f) | (0x80); - write++; - remaining--; - value = value >> 7; - } - *temp = *temp & (0x7f); - oidLength += write - temp; - oidString = PORT_Realloc(oidString, (oidLength + 1)); - read = write - 1; - write = oidLength + oidString - 1; - for (i = 0; i < (length - remaining); i++) { - *write = *read; - write--; - read++; - } - write = temp; - remaining = length; - } - *(oidString + oidLength) = '\0'; - oid = (SECItem *)PORT_ZAlloc(sizeof(SECItem)); - oid->data = oidString; - oid->len = oidLength; - PORT_Free(temp); - return oid; -} - -static SECItem * -string_to_ipaddress(char *string) -{ - int i = 0; - int value; - int j = 0; - SECItem *ipaddress; - - while (*string == ' ') { - string++; - } - ipaddress = (SECItem *)PORT_ZAlloc(sizeof(SECItem)); - ipaddress->data = PORT_ZAlloc(9); - while (*string != '\0' && j < 8) { - while (isdigit(*(string + i))) { - i++; - } - if (*(string + i) == '.') { - *(string + i) = '\0'; - value = atoi(string); - string = string + i + 1; - i = 0; - } else { - if (*(string + i) == '\0') { - value = atoi(string); - string = string + i; - i = 0; - } else { - *(string + i) = '\0'; - while (*(string + i) == ' ') { - i++; - } - if (*(string + i) == '\0') { - value = atoi(string); - string = string + i; - i = 0; - } else { - error_out("ERROR: Improperly formated IP Address"); - } - } - } - if (value >= 0 && value < 256) { - *(ipaddress->data + j) = value; - } else { - error_out("ERROR: Improperly formated IP Address"); - } - j++; - } - *(ipaddress->data + j) = '\0'; - if (j != 4 && j != 8) { - error_out("ERROR: Improperly formated IP Address"); - } - ipaddress->len = j; - return ipaddress; -} - -static int -chr_to_hex(char c) -{ - if (isdigit(c)) { - return c - '0'; - } - if (isxdigit(c)) { - return toupper(c) - 'A' + 10; - } - return -1; -} - -static SECItem * -string_to_binary(char *string) -{ - SECItem *rv; - - rv = (SECItem *)PORT_ZAlloc(sizeof(SECItem)); - if (rv == NULL) { - error_allocate(); - } - rv->data = (unsigned char *)PORT_ZAlloc((PORT_Strlen(string)) / 3 + 2); - rv->len = 0; - while (*string && !isxdigit(*string)) { - string++; - } - while (*string) { - int high, low; - high = chr_to_hex(*string++); - low = chr_to_hex(*string++); - if (high < 0 || low < 0) { - error_out("ERROR: Improperly formated binary encoding"); - } - rv->data[(rv->len)++] = high << 4 | low; - if (*string != ':') { - break; - } - ++string; - } - while (*string == ' ') { - ++string; - } - if (*string) { - error_out("ERROR: Junk after binary encoding"); - } - - return rv; -} - -static SECStatus -MakeGeneralName(char *name, - CERTGeneralName *genName, - PLArenaPool *arena) -{ - SECItem *oid; - SECOidData *oidData; - SECItem *ipaddress; - SECItem *temp = NULL; - int i; - int nameType; - PRBool binary = PR_FALSE; - SECStatus rv = SECSuccess; - PRBool nickname = PR_FALSE; - - PORT_Assert(genName); - PORT_Assert(arena); - nameType = *(name + PORT_Strlen(name) - 1) - '0'; - if (nameType == 0 && *(name + PORT_Strlen(name) - 2) == '1') { - nickname = PR_TRUE; - nameType = certOtherName; - } - if (nameType < 1 || nameType > 9) { - error_out("ERROR: Unknown General Name Type"); - } - *(name + PORT_Strlen(name) - 4) = '\0'; - genName->type = nameType; - - switch (genName->type) { - case certURI: - case certRFC822Name: - case certDNSName: { - genName->name.other.data = (unsigned char *)name; - genName->name.other.len = PORT_Strlen(name); - break; - } - - case certIPAddress: { - ipaddress = string_to_ipaddress(name); - genName->name.other.data = ipaddress->data; - genName->name.other.len = ipaddress->len; - break; - } - - case certRegisterID: { - oid = string_to_oid(name); - genName->name.other.data = oid->data; - genName->name.other.len = oid->len; - break; - } - - case certEDIPartyName: - case certX400Address: { - - genName->name.other.data = PORT_ArenaAlloc(arena, - PORT_Strlen(name) + 2); - if (genName->name.other.data == NULL) { - error_allocate(); - } - - PORT_Memcpy(genName->name.other.data + 2, name, PORT_Strlen(name)); - /* This may not be accurate for all cases. - For now, use this tag type */ - genName->name.other.data[0] = (char)(((genName->type - 1) & - 0x1f) | - 0x80); - genName->name.other.data[1] = (char)PORT_Strlen(name); - genName->name.other.len = PORT_Strlen(name) + 2; - break; - } - - case certOtherName: { - i = 0; - if (!nickname) { - while (!isdigit(*(name + PORT_Strlen(name) - i))) { - i++; - } - if (*(name + PORT_Strlen(name) - i) == '1') { - binary = PR_TRUE; - } else { - binary = PR_FALSE; - } - while (*(name + PORT_Strlen(name) - i) != '-') { - i++; - } - *(name + PORT_Strlen(name) - i - 1) = '\0'; - i = 0; - while (*(name + i) != '-') { - i++; - } - *(name + i - 1) = '\0'; - oid = string_to_oid(name + i + 2); - } else { - oidData = SECOID_FindOIDByTag(SEC_OID_NETSCAPE_NICKNAME); - oid = &oidData->oid; - while (*(name + PORT_Strlen(name) - i) != '-') { - i++; - } - *(name + PORT_Strlen(name) - i) = '\0'; - } - genName->name.OthName.oid.data = oid->data; - genName->name.OthName.oid.len = oid->len; - if (binary) { - temp = string_to_binary(name); - genName->name.OthName.name.data = temp->data; - genName->name.OthName.name.len = temp->len; - } else { - temp = (SECItem *)PORT_ZAlloc(sizeof(SECItem)); - if (temp == NULL) { - error_allocate(); - } - temp->data = (unsigned char *)name; - temp->len = PORT_Strlen(name); - SEC_ASN1EncodeItem(arena, &(genName->name.OthName.name), temp, - CERTIA5TypeTemplate); - } - PORT_Free(temp); - break; - } - - case certDirectoryName: { - CERTName *directoryName = NULL; - - directoryName = CERT_AsciiToName(name); - if (!directoryName) { - error_out("ERROR: Improperly formated alternative name"); - break; - } - rv = CERT_CopyName(arena, &genName->name.directoryName, - directoryName); - CERT_DestroyName(directoryName); - - break; - } - } - genName->l.next = &(genName->l); - genName->l.prev = &(genName->l); - return rv; -} - -static CERTGeneralName * -MakeAltName(Pair *data, - char *which, - PLArenaPool *arena) -{ - CERTGeneralName *SubAltName; - CERTGeneralName *current; - CERTGeneralName *newname; - char *name = NULL; - SECStatus rv = SECSuccess; - int len; - - len = PORT_Strlen(which); - name = find_field(data, which, PR_TRUE); - SubAltName = current = (CERTGeneralName *)PORT_ZAlloc(sizeof(CERTGeneralName)); - if (current == NULL) { - error_allocate(); - } - while (name != NULL) { - - rv = MakeGeneralName(name, current, arena); - - if (rv != SECSuccess) { - break; - } - if (*(which + len - 1) < '9') { - *(which + len - 1) = *(which + len - 1) + 1; - } else { - if (isdigit(*(which + len - 2))) { - *(which + len - 2) = *(which + len - 2) + 1; - *(which + len - 1) = '0'; - } else { - *(which + len - 1) = '1'; - *(which + len) = '0'; - *(which + len + 1) = '\0'; - len++; - } - } - len = PORT_Strlen(which); - name = find_field(data, which, PR_TRUE); - if (name != NULL) { - newname = (CERTGeneralName *)PORT_ZAlloc(sizeof(CERTGeneralName)); - if (newname == NULL) { - error_allocate(); - } - current->l.next = &(newname->l); - newname->l.prev = &(current->l); - current = newname; - newname = NULL; - } else { - current->l.next = &(SubAltName->l); - SubAltName->l.prev = &(current->l); - } - } - if (rv == SECFailure) { - return NULL; - } - return SubAltName; -} - -static CERTNameConstraints * -MakeNameConstraints(Pair *data, - PLArenaPool *arena) -{ - CERTNameConstraints *NameConstraints; - CERTNameConstraint *current = NULL; - CERTNameConstraint *last_permited = NULL; - CERTNameConstraint *last_excluded = NULL; - char *constraint = NULL; - char *which; - SECStatus rv = SECSuccess; - int len; - int i; - long max; - long min; - PRBool permited; - - NameConstraints = (CERTNameConstraints *)PORT_ZAlloc(sizeof(CERTNameConstraints)); - which = make_copy_string("NameConstraintSelect0", 25, '\0'); - len = PORT_Strlen(which); - constraint = find_field(data, which, PR_TRUE); - NameConstraints->permited = NameConstraints->excluded = NULL; - while (constraint != NULL) { - current = (CERTNameConstraint *)PORT_ZAlloc(sizeof(CERTNameConstraint)); - if (current == NULL) { - error_allocate(); - } - i = 0; - while (*(constraint + PORT_Strlen(constraint) - i) != '-') { - i++; - } - *(constraint + PORT_Strlen(constraint) - i - 1) = '\0'; - max = (long)atoi(constraint + PORT_Strlen(constraint) + 3); - if (max > 0) { - (void)SEC_ASN1EncodeInteger(arena, ¤t->max, max); - } - i = 0; - while (*(constraint + PORT_Strlen(constraint) - i) != '-') { - i++; - } - *(constraint + PORT_Strlen(constraint) - i - 1) = '\0'; - min = (long)atoi(constraint + PORT_Strlen(constraint) + 3); - (void)SEC_ASN1EncodeInteger(arena, ¤t->min, min); - while (*(constraint + PORT_Strlen(constraint) - i) != '-') { - i++; - } - *(constraint + PORT_Strlen(constraint) - i - 1) = '\0'; - if (*(constraint + PORT_Strlen(constraint) + 3) == 'p') { - permited = PR_TRUE; - } else { - permited = PR_FALSE; - } - rv = MakeGeneralName(constraint, &(current->name), arena); - - if (rv != SECSuccess) { - break; - } - if (*(which + len - 1) < '9') { - *(which + len - 1) = *(which + len - 1) + 1; - } else { - if (isdigit(*(which + len - 2))) { - *(which + len - 2) = *(which + len - 2) + 1; - *(which + len - 1) = '0'; - } else { - *(which + len - 1) = '1'; - *(which + len) = '0'; - *(which + len + 1) = '\0'; - len++; - } - } - len = PORT_Strlen(which); - if (permited) { - if (NameConstraints->permited == NULL) { - NameConstraints->permited = last_permited = current; - } - last_permited->l.next = &(current->l); - current->l.prev = &(last_permited->l); - last_permited = current; - } else { - if (NameConstraints->excluded == NULL) { - NameConstraints->excluded = last_excluded = current; - } - last_excluded->l.next = &(current->l); - current->l.prev = &(last_excluded->l); - last_excluded = current; - } - constraint = find_field(data, which, PR_TRUE); - if (constraint != NULL) { - current = (CERTNameConstraint *)PORT_ZAlloc(sizeof(CERTNameConstraint)); - if (current == NULL) { - error_allocate(); - } - } - } - if (NameConstraints->permited != NULL) { - last_permited->l.next = &(NameConstraints->permited->l); - NameConstraints->permited->l.prev = &(last_permited->l); - } - if (NameConstraints->excluded != NULL) { - last_excluded->l.next = &(NameConstraints->excluded->l); - NameConstraints->excluded->l.prev = &(last_excluded->l); - } - if (which != NULL) { - PORT_Free(which); - } - if (rv == SECFailure) { - return NULL; - } - return NameConstraints; -} - -static SECStatus -AddAltName(void *extHandle, - Pair *data, - char *issuerNameStr, - CERTCertDBHandle *handle, - int type) -{ - PRBool autoIssuer = PR_FALSE; - PLArenaPool *arena = NULL; - CERTGeneralName *genName = NULL; - char *which = NULL; - char *name = NULL; - SECStatus rv = SECSuccess; - SECItem *issuersAltName = NULL; - CERTCertificate *issuerCert = NULL; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if (arena == NULL) { - error_allocate(); - } - if (type == 0) { - which = make_copy_string("SubAltNameSelect0", 20, '\0'); - genName = MakeAltName(data, which, arena); - } else { - if (autoIssuer) { - autoIssuer = find_field_bool(data, "IssuerAltNameSourceRadio-auto", - PR_TRUE); - issuerCert = CERT_FindCertByNameString(handle, issuerNameStr); - rv = cert_FindExtension((*issuerCert).extensions, - SEC_OID_X509_SUBJECT_ALT_NAME, - issuersAltName); - if (issuersAltName == NULL) { - name = PORT_Alloc(PORT_Strlen((*issuerCert).subjectName) + 4); - PORT_Strcpy(name, (*issuerCert).subjectName); - PORT_Strcat(name, " - 5"); - } - } else { - which = make_copy_string("IssuerAltNameSelect0", 20, '\0'); - genName = MakeAltName(data, which, arena); - } - } - if (type == 0) { - EncodeAndAddExtensionValue(arena, extHandle, genName, - find_field_bool(data, "SubAltName-crit", - PR_TRUE), - SEC_OID_X509_SUBJECT_ALT_NAME, - (EXTEN_VALUE_ENCODER) - CERT_EncodeAltNameExtension); - - } else { - if (autoIssuer && (name == NULL)) { - rv = CERT_AddExtension(extHandle, SEC_OID_X509_ISSUER_ALT_NAME, issuersAltName, - find_field_bool(data, "IssuerAltName-crit", PR_TRUE), PR_TRUE); - } else { - EncodeAndAddExtensionValue(arena, extHandle, genName, - find_field_bool(data, - "IssuerAltName-crit", - PR_TRUE), - SEC_OID_X509_ISSUER_ALT_NAME, - (EXTEN_VALUE_ENCODER) - CERT_EncodeAltNameExtension); - } - } - if (which != NULL) { - PORT_Free(which); - } - if (issuerCert != NULL) { - CERT_DestroyCertificate(issuerCert); - } - return rv; -} - -static SECStatus -AddNameConstraints(void *extHandle, - Pair *data) -{ - PLArenaPool *arena = NULL; - CERTNameConstraints *constraints = NULL; - SECStatus rv = SECSuccess; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if (arena == NULL) { - error_allocate(); - } - constraints = MakeNameConstraints(data, arena); - if (constraints != NULL) { - EncodeAndAddExtensionValue(arena, extHandle, constraints, PR_TRUE, - SEC_OID_X509_NAME_CONSTRAINTS, - (EXTEN_VALUE_ENCODER) - CERT_EncodeNameConstraintsExtension); - } - if (arena != NULL) { - PORT_ArenaRelease(arena, NULL); - } - return rv; -} - -static SECStatus -add_extensions(CERTCertificate *subjectCert, - Pair *data, - char *issuerNameStr, - CERTCertDBHandle *handle) -{ - void *extHandle; - SECStatus rv = SECSuccess; - - extHandle = CERT_StartCertExtensions(subjectCert); - if (extHandle == NULL) { - error_out("ERROR: Unable to get certificates extension handle"); - } - if (find_field_bool(data, "keyUsage", PR_TRUE)) { - rv = AddKeyUsage(extHandle, data); - if (rv != SECSuccess) { - error_out("ERROR: Unable to add Key Usage extension"); - } - } - - if (find_field_bool(data, "extKeyUsage", PR_TRUE)) { - rv = AddExtKeyUsage(extHandle, data); - if (SECSuccess != rv) { - error_out("ERROR: Unable to add Extended Key Usage extension"); - } - } - - if (find_field_bool(data, "basicConstraints", PR_TRUE)) { - rv = AddBasicConstraint(extHandle, data); - if (rv != SECSuccess) { - error_out("ERROR: Unable to add Basic Constraint extension"); - } - } - if (find_field_bool(data, "subjectKeyIdentifier", PR_TRUE)) { - rv = AddSubKeyID(extHandle, data, subjectCert); - if (rv != SECSuccess) { - error_out("ERROR: Unable to add Subject Key Identifier Extension"); - } - } - if (find_field_bool(data, "authorityKeyIdentifier", PR_TRUE)) { - rv = AddAuthKeyID(extHandle, data, issuerNameStr, handle); - if (rv != SECSuccess) { - error_out("ERROR: Unable to add Authority Key Identifier extension"); - } - } - if (find_field_bool(data, "privKeyUsagePeriod", PR_TRUE)) { - rv = AddPrivKeyUsagePeriod(extHandle, data, subjectCert); - if (rv != SECSuccess) { - error_out("ERROR: Unable to add Private Key Usage Period extension"); - } - } - if (find_field_bool(data, "SubAltName", PR_TRUE)) { - rv = AddAltName(extHandle, data, NULL, NULL, 0); - if (rv != SECSuccess) { - error_out("ERROR: Unable to add Subject Alternative Name extension"); - } - } - if (find_field_bool(data, "IssuerAltName", PR_TRUE)) { - rv = AddAltName(extHandle, data, issuerNameStr, handle, 1); - if (rv != SECSuccess) { - error_out("ERROR: Unable to add Issuer Alternative Name Extension"); - } - } - if (find_field_bool(data, "NameConstraints", PR_TRUE)) { - rv = AddNameConstraints(extHandle, data); - if (rv != SECSuccess) { - error_out("ERROR: Unable to add Name Constraints Extension"); - } - } - if (find_field_bool(data, "netscape-cert-type", PR_TRUE)) { - rv = AddNscpCertType(extHandle, data); - if (rv != SECSuccess) { - error_out("ERROR: Unable to add Netscape Certificate Type Extension"); - } - } - if (find_field_bool(data, "netscape-base-url", PR_TRUE)) { - rv = add_IA5StringExtension(extHandle, - find_field(data, "netscape-base-url-text", - PR_TRUE), - find_field_bool(data, - "netscape-base-url-crit", - PR_TRUE), - SEC_OID_NS_CERT_EXT_BASE_URL); - if (rv != SECSuccess) { - error_out("ERROR: Unable to add Netscape Base URL Extension"); - } - } - if (find_field_bool(data, "netscape-revocation-url", PR_TRUE)) { - rv = add_IA5StringExtension(extHandle, - find_field(data, - "netscape-revocation-url-text", - PR_TRUE), - find_field_bool(data, "netscape-revocation-url-crit", - PR_TRUE), - SEC_OID_NS_CERT_EXT_REVOCATION_URL); - if (rv != SECSuccess) { - error_out("ERROR: Unable to add Netscape Revocation URL Extension"); - } - } - if (find_field_bool(data, "netscape-ca-revocation-url", PR_TRUE)) { - rv = add_IA5StringExtension(extHandle, - find_field(data, - "netscape-ca-revocation-url-text", - PR_TRUE), - find_field_bool(data, "netscape-ca-revocation-url-crit", PR_TRUE), - SEC_OID_NS_CERT_EXT_CA_REVOCATION_URL); - if (rv != SECSuccess) { - error_out("ERROR: Unable to add Netscape CA Revocation URL Extension"); - } - } - if (find_field_bool(data, "netscape-cert-renewal-url", PR_TRUE)) { - rv = add_IA5StringExtension(extHandle, - find_field(data, - "netscape-cert-renewal-url-text", - PR_TRUE), - find_field_bool(data, "netscape-cert-renewal-url-crit", - PR_TRUE), - SEC_OID_NS_CERT_EXT_CERT_RENEWAL_URL); - if (rv != SECSuccess) { - error_out("ERROR: Unable to add Netscape Certificate Renewal URL Extension"); - } - } - if (find_field_bool(data, "netscape-ca-policy-url", PR_TRUE)) { - rv = add_IA5StringExtension(extHandle, - find_field(data, - "netscape-ca-policy-url-text", - PR_TRUE), - find_field_bool(data, "netscape-ca-policy-url-crit", - PR_TRUE), - SEC_OID_NS_CERT_EXT_CA_POLICY_URL); - if (rv != SECSuccess) { - error_out("ERROR: Unable to add Netscape CA Policy URL Extension"); - } - } - if (find_field_bool(data, "netscape-ssl-server-name", PR_TRUE)) { - rv = add_IA5StringExtension(extHandle, - find_field(data, - "netscape-ssl-server-name-text", - PR_TRUE), - find_field_bool(data, "netscape-ssl-server-name-crit", - PR_TRUE), - SEC_OID_NS_CERT_EXT_SSL_SERVER_NAME); - if (rv != SECSuccess) { - error_out("ERROR: Unable to add Netscape SSL Server Name Extension"); - } - } - if (find_field_bool(data, "netscape-comment", PR_TRUE)) { - rv = add_IA5StringExtension(extHandle, - find_field(data, "netscape-comment-text", - PR_TRUE), - find_field_bool(data, - "netscape-comment-crit", - PR_TRUE), - SEC_OID_NS_CERT_EXT_COMMENT); - if (rv != SECSuccess) { - error_out("ERROR: Unable to add Netscape Comment Extension"); - } - } - CERT_FinishExtensions(extHandle); - return (rv); -} - -char * -return_dbpasswd(PK11SlotInfo *slot, PRBool retry, void *data) -{ - char *rv; - - /* don't clobber our poor smart card */ - if (retry == PR_TRUE) { - return NULL; - } - rv = PORT_Alloc(4); - PORT_Strcpy(rv, "foo"); - return rv; -} - -SECKEYPrivateKey * -FindPrivateKeyFromNameStr(char *name, - CERTCertDBHandle *certHandle) -{ - SECKEYPrivateKey *key; - CERTCertificate *cert; - CERTCertificate *p11Cert; - - /* We don't presently have a PK11 function to find a cert by - ** subject name. - ** We do have a function to find a cert in the internal slot's - ** cert db by subject name, but it doesn't setup the slot info. - ** So, this HACK works, but should be replaced as soon as we - ** have a function to search for certs accross slots by subject name. - */ - cert = CERT_FindCertByNameString(certHandle, name); - if (cert == NULL || cert->nickname == NULL) { - error_out("ERROR: Unable to retrieve issuers certificate"); - } - p11Cert = PK11_FindCertFromNickname(cert->nickname, NULL); - if (p11Cert == NULL) { - error_out("ERROR: Unable to retrieve issuers certificate"); - } - key = PK11_FindKeyByAnyCert(p11Cert, NULL); - return key; -} - -static SECItem * -SignCert(CERTCertificate *cert, - char *issuerNameStr, - Pair *data, - CERTCertDBHandle *handle, - int which_key) -{ - SECItem der; - SECKEYPrivateKey *caPrivateKey = NULL; - SECStatus rv; - PLArenaPool *arena; - SECOidTag algID; - - if (which_key == 0) { - caPrivateKey = FindPrivateKeyFromNameStr(issuerNameStr, handle); - } else { - caPrivateKey = privkeys[which_key - 1]; - } - if (caPrivateKey == NULL) { - error_out("ERROR: unable to retrieve issuers key"); - } - - arena = cert->arena; - - algID = SEC_GetSignatureAlgorithmOidTag(caPrivateKey->keyType, - SEC_OID_UNKNOWN); - if (algID == SEC_OID_UNKNOWN) { - error_out("ERROR: Unknown key type for issuer."); - goto done; - } - - rv = SECOID_SetAlgorithmID(arena, &cert->signature, algID, 0); - if (rv != SECSuccess) { - error_out("ERROR: Could not set signature algorithm id."); - } - - if (find_field_bool(data, "ver-1", PR_TRUE)) { - *(cert->version.data) = 0; - cert->version.len = 1; - } else { - *(cert->version.data) = 2; - cert->version.len = 1; - } - der.data = NULL; - der.len = 0; - (void)SEC_ASN1EncodeItem(arena, &der, cert, CERT_CertificateTemplate); - if (der.data == NULL) { - error_out("ERROR: Could not encode certificate.\n"); - } - rv = SEC_DerSignData(arena, &(cert->derCert), der.data, der.len, caPrivateKey, - algID); - if (rv != SECSuccess) { - error_out("ERROR: Could not sign encoded certificate data.\n"); - } -done: - SECKEY_DestroyPrivateKey(caPrivateKey); - return &(cert->derCert); -} - -int -main(int argc, char **argv) -{ - int length = 500; - int remaining = 500; - int n; - int i; - int serial; - int chainLen; - int which_key; - char *pos; -#ifdef OFFLINE - char *form_output = "key=MIIBPTCBpzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA7" - "SLqjWBL9Wl11Vlg%0AaMqZCvcQOL%2FnvSqYPPRP0XZy9SoAeyWzQnBOiCm2t8H5mK7r2" - "jnKdAQOmfhjaJil%0A3hNVu3SekHOXF6Ze7bkWa6%2FSGVcY%2FojkydxFSgY43nd1iyd" - "zPQDp8WWLL%2BpVpt%2B%2B%0ATRhFtVXbF0fQI03j9h3BoTgP2lkCAwEAARYDZm9vMA0" - "GCSqGSIb3DQEBBAUAA4GB%0AAJ8UfRKJ0GtG%2B%2BufCC6tAfTzKrq3CTBHnom55EyXc" - "sAsv6WbDqI%2F0rLAPkn2Xo1r%0AnNhtMxIuj441blMt%2Fa3AGLOy5zmC7Qawt8IytvQ" - "ikQ1XTpTBCXevytrmLjCmlURr%0ANJryTM48WaMQHiMiJpbXCqVJC1d%2FpEWBtqvALzZ" - "aOOIy&subject=CN%3D%22test%22%26serial-auto%3Dtrue%26serial_value%3D%" - "26ver-1%3Dtrue%26ver-3%3Dfalse%26caChoiceradio-SignWithDefaultkey%3Dt" - "rue%26caChoiceradio-SignWithRandomChain%3Dfalse%26autoCAs%3D%26caChoi" - "ceradio-SignWithSpecifiedChain%3Dfalse%26manCAs%3D%26%24"; -#else - char *form_output; -#endif - char *issuerNameStr; - char *certName; - char *DBdir = DB_DIRECTORY; - char *prefixs[10] = { "CA#1-", "CA#2-", "CA#3-", - "CA#4-", "CA#5-", "CA#6-", - "CA#7-", "CA#8-", "CA#9-", "" }; - Pair *form_data; - CERTCertificate *cert; - CERTCertDBHandle *handle; - CERTCertificateRequest *certReq = NULL; - int warpmonths = 0; - SECItem *certDER; -#ifdef FILEOUT - FILE *outfile; -#endif - SECStatus status = SECSuccess; - extern char prefix[PREFIX_LEN]; - SEC_PKCS7ContentInfo *certChain; - SECItem *encodedCertChain; - PRBool UChain = PR_FALSE; - - progName = strrchr(argv[0], '/'); - progName = progName ? progName + 1 : argv[0]; - -#ifdef TEST - sleep(20); -#endif - SECU_ConfigDirectory(DBdir); - - PK11_SetPasswordFunc(return_dbpasswd); - status = NSS_InitReadWrite(DBdir); - if (status != SECSuccess) { - SECU_PrintPRandOSError(progName); - return -1; - } - handle = CERT_GetDefaultCertDB(); - - prefix[0] = '\0'; -#if !defined(OFFLINE) - form_output = (char *)PORT_Alloc(length); - if (form_output == NULL) { - error_allocate(); - } - pos = form_output; - while (feof(stdin) == 0) { - if (remaining <= 1) { - remaining += length; - length = length * 2; - form_output = PORT_Realloc(form_output, (length)); - if (form_output == NULL) { - error_allocate(); - } - pos = form_output + length - remaining; - } - n = fread(pos, 1, (size_t)(remaining - 1), stdin); - pos += n; - remaining -= n; - } - *pos = '&'; - pos++; - length = pos - form_output; -#else - length = PORT_Strlen(form_output); -#endif -#ifdef FILEOUT - printf("Content-type: text/plain\n\n"); - fwrite(form_output, 1, (size_t)length, stdout); - printf("\n"); -#endif -#ifdef FILEOUT - fwrite(form_output, 1, (size_t)length, stdout); - printf("\n"); - fflush(stdout); -#endif - form_data = make_datastruct(form_output, length); - status = clean_input(form_data); -#if !defined(OFFLINE) - PORT_Free(form_output); -#endif -#ifdef FILEOUT - i = 0; - while (return_name(form_data, i) != NULL) { - printf("%s", return_name(form_data, i)); - printf("=\n"); - printf("%s", return_data(form_data, i)); - printf("\n"); - i++; - } - printf("I got that done, woo hoo\n"); - fflush(stdout); -#endif - issuerNameStr = PORT_Alloc(200); - if (find_field_bool(form_data, "caChoiceradio-SignWithSpecifiedChain", - PR_FALSE)) { - UChain = PR_TRUE; - chainLen = atoi(find_field(form_data, "manCAs", PR_FALSE)); - PORT_Strcpy(prefix, prefixs[0]); - issuerNameStr = PORT_Strcpy(issuerNameStr, - "CN=Cert-O-Matic II, O=Cert-O-Matic II"); - if (chainLen == 0) { - UChain = PR_FALSE; - } - } else { - if (find_field_bool(form_data, "caChoiceradio-SignWithRandomChain", - PR_FALSE)) { - PORT_Strcpy(prefix, prefixs[9]); - chainLen = atoi(find_field(form_data, "autoCAs", PR_FALSE)); - if (chainLen < 1 || chainLen > 18) { - issuerNameStr = PORT_Strcpy(issuerNameStr, - "CN=CA18, O=Cert-O-Matic II"); - } - issuerNameStr = PORT_Strcpy(issuerNameStr, "CN=CA"); - issuerNameStr = PORT_Strcat(issuerNameStr, - find_field(form_data, "autoCAs", PR_FALSE)); - issuerNameStr = PORT_Strcat(issuerNameStr, ", O=Cert-O-Matic II"); - } else { - issuerNameStr = PORT_Strcpy(issuerNameStr, - "CN=Cert-O-Matic II, O=Cert-O-Matic II"); - } - chainLen = 0; - } - - i = -1; - which_key = 0; - do { - extern SECStatus cert_GetKeyID(CERTCertificate * cert); - i++; - if (i != 0 && UChain) { - PORT_Strcpy(prefix, prefixs[i]); - } - /* find_field(form_data,"subject", PR_TRUE); */ - certReq = makeCertReq(form_data, which_key); -#ifdef OFFLINE - serial = 900; -#else - serial = get_serial_number(form_data); -#endif - cert = MakeV1Cert(handle, certReq, issuerNameStr, PR_FALSE, - serial, warpmonths, form_data); - if (certReq != NULL) { - CERT_DestroyCertificateRequest(certReq); - } - if (find_field_bool(form_data, "ver-3", PR_TRUE)) { - status = add_extensions(cert, form_data, issuerNameStr, handle); - if (status != SECSuccess) { - error_out("ERROR: Unable to add extensions"); - } - } - status = cert_GetKeyID(cert); - if (status == SECFailure) { - error_out("ERROR: Unable to get Key ID."); - } - certDER = SignCert(cert, issuerNameStr, form_data, handle, which_key); - CERT_NewTempCertificate(handle, certDER, NULL, PR_FALSE, PR_TRUE); - issuerNameStr = find_field(form_data, "subject", PR_TRUE); - /* SECITEM_FreeItem(certDER, PR_TRUE); */ - CERT_DestroyCertificate(cert); - if (i == (chainLen - 1)) { - i = 8; - } - ++which_key; - } while (i < 9 && UChain); - -#ifdef FILEOUT - outfile = fopen("../certout", "wb"); -#endif - certName = find_field(form_data, "subject", PR_FALSE); - cert = CERT_FindCertByNameString(handle, certName); - certChain = SEC_PKCS7CreateCertsOnly(cert, PR_TRUE, handle); - if (certChain == NULL) { - error_out("ERROR: No certificates in cert chain"); - } - encodedCertChain = SEC_PKCS7EncodeItem(NULL, NULL, certChain, NULL, NULL, - NULL); - if (encodedCertChain) { -#if !defined(FILEOUT) - printf("Content-type: application/x-x509-user-cert\r\n"); - printf("Content-length: %d\r\n\r\n", encodedCertChain->len); - fwrite(encodedCertChain->data, 1, encodedCertChain->len, stdout); -#else - fwrite(encodedCertChain->data, 1, encodedCertChain->len, outfile); -#endif - - } else { - error_out("Error: Unable to DER encode certificate"); - } -#ifdef FILEOUT - printf("\nI got here!\n"); - fflush(outfile); - fclose(outfile); -#endif - fflush(stdout); - if (NSS_Shutdown() != SECSuccess) { - exit(1); - } - return 0; -} diff --git a/security/nss/cmd/certcgi/index.html b/security/nss/cmd/certcgi/index.html deleted file mode 100644 index 3ae6a10d4..000000000 --- a/security/nss/cmd/certcgi/index.html +++ /dev/null @@ -1,789 +0,0 @@ -<HTML> <!-- -*- Mode: Java; tab-width: 8 -*- --> -<!-- 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/. --> -<HEAD> -<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> -<SCRIPT LANGUAGE="JavaScript1.2"> - -script_url = 'http://interzone.mcom.com/cgi-bin/certomatic/bin/certcgi.cgi' - -ext_page_ver1 = - make_page_intro('Version 1 extensions', "#FFFFFF") + - '<IFRAME WIDTH="100%" HEIGHT="100%" FRAMEBORDER=0 ID="ext1">' + - 'Version 1 X.509 certs do not support extensions' + - '</IFRAME>' + - '</body></html>'; - -num_ca = 0; - -your_certificate_index_label = 'Your Certificate'; -netscape_extensions_index_label = 'Netscape X.509 Extensions'; -standard_extensions_index_label = 'Standard X.509 Extensions'; -certifying_authorities_index_label = 'Certifying Authorities'; -add_sub_alt_name_index_label = 'Add Subject Alternative Name'; - -index_list = - '0, your_certificate_index_label,' + - '0, netscape_extensions_index_label,' + - '0, standard_extensions_index_label,' + - '0, certifying_authorities_index_label'; - -add_index_list = ''; - -ver = 3 - -max_pages = 13; -cur_page = 1; - -ext_page_array = new Array(max_pages); - -index_label = 'Options'; - -var main_page = - make_page_intro('Your Key', "#FFFFFF") + - '<IFRAME WIDTH="100%" HEIGHT="100%" FRAMEBORDER=0 ID="main" SRC="main.html">' + - '</IFRAME>' + - '</body></html>' ; - -function setSubAltNameType(form) -{ - with(form) { - if (SubAltNameRadio[0].checked) { - return true; - } - if (SubAltNameRadio[3].checked || SubAltNameRadio[5].checked) { - SubAltNameDataType.checked = true; - return true; - } - if (SubAltNameRadio[1].checked || SubAltNameRadio[2].checked || - SubAltNameRadio[4].checked || SubAltNameRadio[6].checked || - SubAltNameRadio[7].checked || SubAltNameRadio[8].checked) { - SubAltNameDataType.checked = false; - return true; - } - } - return true; -} - -function setIssuerAltNameType(form) -{ - with(form) { - if (IssuerAltNameRadio[0].checked) { - return true; - } - if (IssuerAltNameRadio[3].checked || IssuerAltNameRadio[5].checked) { - IssuerAltNameDataType.checked = true; - return true; - } - if (IssuerAltNameRadio[1].checked || IssuerAltNameRadio[2].checked || - IssuerAltNameRadio[4].checked || IssuerAltNameRadio[6].checked || - IssuerAltNameRadio[7].checked || IssuerAltNameRadio[8].checked) { - IssuerAltNameDataType.checked = false; - return true; - } - } - return true; -} - - -function setNameConstraintNameType(form) -{ - with(form) { - if (NameConstraintRadio[0].checked) { - return true; - } - if (NameConstraintRadio[3].checked || NameConstraintRadio[5].checked) { - NameConstraintNameDataType.checked = true; - return true; - } - if (NameConstraintRadio[1].checked || NameConstraintRadio[2].checked || - NameConstraintRadio[4].checked || NameConstraintRadio[6].checked || - NameConstraintRadio[7].checked || NameConstraintRadio[8].checked) { - NameConstraintNameDataType.checked = false; - return true; - } - } - return true; -} - - -function addSubAltName(form) -{ - with(form) { - var len = SubAltNameSelect.length; - var value; - var i = 0; - while(!(i == (SubAltNameRadio.length - 1)) & - !(SubAltNameRadio[i].checked == true)) { - i++; - } - if (i != 0) { - value = SubAltNameText.value + " - " + (i + 1); - } else { - value = SubAltNameText.value + " - " + - SubAltNameOtherNameOID.value + " - "; - if (SubAltNameDataType.checked) { - value += "1 - "; - } else { - value += "0 - "; - } - value += (i + 1); - if (SubAltNameOtherNameOID.value == "") { - alert("Other names must include an OID"); - return false; - } - } - - if ((SubAltNameText.value == "") | (SubAltNameRadio[i].checked != true)) { - alert("Alternative Names must include values for name and name type."); - } else { - SubAltNameSelect.options[len] = new Option(value, value); - } - } - return true; -} - -function deleteSubAltName(form) -{ - with(form) { - while (SubAltNameSelect.selectedIndex >= 0) { - SubAltNameSelect[SubAltNameSelect.selectedIndex] = null; - } - } -} - -function addIssuerAltName(form) -{ - with(form) - { - var len = IssuerAltNameSelect.length; - var value; - var i = 0; - - while(!(i == (IssuerAltNameRadio.length -1)) & - !(IssuerAltNameRadio[i].checked == true)) { - i++; - } - if (i != 0) { - value = IssuerAltNameText.value + " - " + (i + 1); - } else { - value = IssuerAltNameText.value + " - " + - IssuerAltNameOtherNameOID.value + " - "; - if (IssuerAltNameDataType.checked) { - value += "1 - "; - } else { - value += "0 - "; - } - value += (i + 1); - if (IssuerAltNameOtherNameOID.value == "") { - alert("Other names must include an OID"); - return false; - } - } - if ((IssuerAltNameText.value == "") | - (IssuerAltNameRadio[i].checked != true)) { - alert("Alternative Names must include values for name and name type.") - } else { - IssuerAltNameSelect.options[len] = new Option(value, value); - } - } - return true; -} - -function deleteIssuerAltName(form) -{ - with(form) { - while (IssuerAltNameSelect.selectedIndex >= 0) { - IssuerAltNameSelect[IssuerAltNameSelect.selectedIndex] = null; - } - } -} - - - -function addNameConstraint(form) -{ - with(form) { - var len = NameConstraintSelect.length; - var value; - var i = 0; - var min = NameConstraintMin.value; - var max = NameConstraintMax.value; - - while(!(i == (NameConstraintRadio.length - 1) ) & - !(NameConstraintRadio[i].checked == true)) { - i++; - } - value = NameConstraintText.value + " - "; - if (i == 0) { - value += NameConstraintOtherNameOID.value + " - "; - if (NameConstraintNameDataType.checked) { - value += "1 - "; - } else { - value += "0 - "; - } - if (NameConstraintOtherNameOID.value == "") { - alert("Other names must include an OID"); - return false; - } - } - value += (i + 1) + " - "; - if (NameConstraintTypeRadio[0].checked == true) { - value += "p - "; - } else { - value += "e - "; - } - value += min + " - " + max; - if ((min == "") | (NameConstraintText.value == "") | - (NameConstraintRadio[i].checked != true)) { - alert("Name Constraints must include values for minimum, name, and name type.") - } else { - NameConstraintSelect.options[len] = new Option(value, value); - } - } - return true; -} - -function deleteNameConstraint(form) -{ - with(form) { - while (NameConstraintSelect.selectedIndex >= 0) { - NameConstraintSelect[NameConstraintSelect.selectedIndex] = null; - } - } -} - - -function submit_it() -{ - save_cur_page(cur_page); - - var ver1 = (ver == 1); - var ver3 = (ver == 3); - var array_string; - var serial = ext_page_array[0][10][0]; - var serial_number = ext_page_array[0][12][0]; - var manValidity = ext_page_array[0][19][0]; - var notBefore = ext_page_array[0][20][0]; - var notAfter = ext_page_array[0][21][0]; - var subject = ext_page_array[0][22][0]; - - if (subject == "") { - alert("The DN field must contain some data"); - return false; - } - if (!serial & serial_number == "") { - alert("No serial number specified"); - return false; - } - if (ext_page_array[0][15][0]) { - var keygen = "<keygen name=\"key\" challenge=\"foo\">"; - } else { - switch (ext_page_array[0][17][0]) { - case 2: - var keygen = "<keygen keytype=\"dsa\" pqg=\"MIGdAkEAjfKklEkidqo9JXWbsGhpy+rA2Dr7jQz3y7gyTw14guXQdi/FtyEOr8Lprawyq3qsSWk9+/g3JMLsBzbuMcgCkQIVAMdzIYxzfsjumTtPLe0w9I7azpFfAkEAYm0CeDnqChNBMWOlW0y1ACmdVSKVbO/LO/8Q85nOLC5xy53l+iS6v1jlt5UhklycxC6fb0ZLCIzFcq9T5teIAg==\" name=\"key\" challenge=\"foo\">"; - break; - case 1: - var keygen = "<keygen keytype=\"dsa\" pqg=\"MIHaAmDCboVgX0+6pEeMlbwsasWDVBcJNHPKMzkq9kbCRK2U3k+tE15n+Dc2g3ZjDYr1um51e2iLC34/BwAAAAAAAAAAAAAAAAAAAAAAAAABbBhnlFN5Djmt0Mk8cdEBY5H8iPMCFMhUnFtbpjn3EyfH2DjVg3ALh7FtAmA2zWzhpeCwvOTjYnQorlXiv0WcnSiWmaC79CRYkFt5i+UEfRxwP1eNGJBVB1T+CPW6JGd4WhgsqtSf53pn5DEtv++O7lNfXyOhWhb3KaWHYIx8fuAXtioIWkWmpfEIVZA=\" name=\"key\" challenge=\"foo\">"; - break; - case 0: - var keygen = "<keygen keytype=\"dsa\" pqg=\"MIIBHAKBgId8SiiWrcdua5zbsBhPkKfFcnHBG7T/bQla7c6OixGjjmSSuq2fJLvMKa579CaxHxLZzZZXIHmAk9poRgWl2GUUkCJ68XSum8OQzDPXPsofcEdeANjw3mIAAAAAAAAAAAAAAAAAAAAAAAAIE+MkW5hguLIQqWvEVi9dMpbNu6OZAhTIA+y3TgyiwA0D8pt686ofaL1IOQKBgAiZQC6UCXztr2iXxJrAC+51gN5oX/R9Thilln9RGegsWnHrdxUOpcm5vAWp1LU8TOXtujE8kqkm3UxIRhUWQORe9IxLANAXmZJqkw9FEVHkxj6Cy9detwT2MyBzSwS6avsf7aLisgHmI/IHSeapJsQ3NQa3rikb6zRiqIV+TVa6\" name=\"key\" challenge=\"foo\">"; - break; - } - } - array_string = build_array_string(); - hiddens = "<input type=\"hidden\" name=\"subject\" value=\'" + subject + "\'> \n" + - "<input type=\"hidden\" name=\"serial-auto\" value=\"" + serial + "\"> \n" + - "<input type=\"hidden\" name=\"serial_value\" value=\"" + serial_number + "\"> \n" + - "<input type=\"hidden\" name=\"ver-1\" value=\"" + ver1 + "\"> \n" + - "<input type=\"hidden\" name=\"ver-3\" value=\"" + ver3 + "\"> \n" + - "<input type=\"hidden\" name=\"notBefore\" value=\"" + notBefore + "\"> \n" + - "<input type=\"hidden\" name=\"notAfter\" value=\"" + notAfter + "\"> \n" + - "<input type=\"hidden\" name=\"manValidity\" value=\"" + manValidity + "\"> \n" + - array_string; - - var good_submit_page = - '<html>' + - '<BODY TEXT="#000000" LINK="#000000" VLINK="#000000" ALINK="#FF0000" BGCOLOR="#FFFFFF">' + - '<form method="post" action="' + script_url + '">' + - 'Select size for your key:' + keygen + '</p>' + - '<input type="submit"></p>' + - hiddens + - '</form>\n' + - '</body>\n' + - '</html>\n'; - - window.frames['right'].document.write(good_submit_page); - window.frames['right'].document.close(); - cur_page = max_pages + 1; - make_left_frame(window); - return false; -} - - - -function build_array_string() -{ - var pg; - var array_string = ''; - var pages; - - if ((ext_page_array[3][4][0] > 0) && ext_page_array[3][3][0]) { - pages = 4 + parseInt(ext_page_array[3][4][0]); - } else { - pages = 4; - } - for (pg = 1; pg < pages; pg++) { - if ((pg > 1 || (ver == 3)) && (ext_page_array[pg].length > 1)) { - if (pg < 4) { - for (i = 0; i < ext_page_array[pg].length; i++) { - if (ext_page_array[pg][i][3].indexOf("radio") == -1) { - if (ext_page_array[pg][i][3].indexOf("multiple") == -1) { - array_string += '<input type=\"hidden\" name=\"' + - ext_page_array[pg][i][1] + '\" value=\'' + - ext_page_array[pg][i][0] + '\'> \n'; - } else { - for (k = 0; k < ext_page_array[pg][i][0].length; k++) { - array_string += '<input type=\"hidden\" name=\"' + - ext_page_array[pg][i][1] + k + '\" value=\'' + - ext_page_array[pg][i][0][k] + '\'> \n'; - } - } - } else { - array_string += '<input type=\"hidden\" name=\"' + - ext_page_array[pg][i][1] + '-' + - ext_page_array[pg][i][2] + '\" value=\'' + - ext_page_array[pg][i][0] + '\'> \n'; - } - } - } else { - for (i = 0; i < ext_page_array[pg].length; i++) { - if (ext_page_array[pg][i][3].indexOf("radio") == -1) { - if (ext_page_array[pg][i][3].indexOf("multiple") == -1) { - array_string += '<input type=\"hidden\" name=\"' + - 'CA#' + (pg - 3) + '-' + - ext_page_array[pg][i][1] + '\" value=\'' + - ext_page_array[pg][i][0] +'\'> \n'; - } else { - for (k = 0; k < ext_page_array[pg][i][0].length; k++) { - array_string += '<input type=\"hidden\" name=\"' + - 'CA#' + (pg - 3) + '-' + - ext_page_array[pg][i][1] + k + '\" value=\'' + - ext_page_array[pg][i][0][k] + '\'> \n'; - } - } - } else { - array_string += '<input type=\"hidden\" name=\"' + - 'CA#' + (pg - 3) + '-' + - ext_page_array[pg][i][1] + '-' + - ext_page_array[pg][i][2] + '\" value=\'' + - ext_page_array[pg][i][0] + '\'> \n'; - } - } - } - } - } - return array_string; -} - - - -function init_ext_page_array() -{ - for (i = 0; i < max_pages; i++) { - ext_page_array[i] = ''; - } -} - -function ca_num_change(n,ca_form) -{ - with(ca_form) { - n = parseInt(n,10); - if (caChoiceradio[2].checked) { - if (n) { - update_left_frame(n); - } else { - update_left_frame(0); - } - } - } -} - -function choice_change(ca_form) -{ - with(ca_form) { - if (caChoiceradio[2].checked) { - ca_num_change(manCAs.value,ca_form); - } else { - update_left_frame(0); - } - } -} - -function update_left_frame(n) -{ - var add_string = ''; - for (var i = 0; i < n; i++) { - var j = i + 1; - add_string = add_string + ',1, \'CA #' + j + '\''; - } - top.add_index_list = add_string; - num_ca = n; - make_left_frame(window); -} - -function set_ver1() -// redraws the extensions page for version 1 certificates -{ - ver = 1 - if (cur_page == 2 || cur_page == 3) { - switch_right_frame(window, cur_page, cur_page); - } -} - - -function set_ver3() -// redraws the extensions page for version 3 certificates -{ - ver = 3 - if (cur_page == 2) { - switch_right_frame(window, 0, 2); - } else if (cur_page == 3) { - switch_right_frame(window, 0, 3); - } -} - -function reset_subject(marker, value, form) -// Updates the subject field from a subordinate field -{ - with(form) { - var field_sep = '", '; - var begin_index = subject.value.indexOf(marker); - if (begin_index != 0 && subject.value[begin_index - 1] != ' ') { - begin_index = subject.value.indexOf(marker, begin_index +1); - } - var end_index = subject.value.indexOf(field_sep, begin_index); - if (begin_index > -1) { // is it a delete/change? - if (end_index == -1) { // is it the last one (includes only one)? - if (value.length > 0) { // do I have to change it? - if (begin_index == 0) { // is is the only one? - subject.value = marker + '"' + value + '"'; - } else { // it is the last of many - subject.value = subject.value.substring(0,begin_index) + - marker + '"' + value + '"'; - } - } else { // must be a delete - if (begin_index == 0) { // is it the only one? - begin_index += 2; - } - subject.value = subject.value.substring(0,(begin_index - 2)); - } - } else { // it is the first of many or a middle one - if (value.length >0) { // do I have to change it? - subject.value = - subject.value.substring(0,(begin_index + marker.length + 1)) + - value + subject.value.substring(end_index,subject.length); - } else { // it is a delete - subject.value = subject.value.substring(0,begin_index) + - subject.value.substring((end_index + 3),subject.length); - } - } - } else { // It is either an insert or a do nothing - if (value.length > 0) { // is it an insert? - if (subject.value.length == 0) { // is subject currently empty? - subject.value = marker + '"' + value + '"'; - } else { - subject.value = subject.value + ', ' + marker + '"' + value + '"'; - } - } - } - } -} - - - -function reset_subjectFields(form) -// updates all the subordinate fields from the subject field of a form -// **** move the strings to global variables, to make maintentance easier **** -{ - - update_subject_Field(form, 'CN=\"', form.name); - update_subject_Field(form, 'MAIL=\"', form.email); - update_subject_Field(form, 'O=\"', form.org); - update_subject_Field(form, 'C=\"', form.country); - update_subject_Field(form, ' L=\"', form.loc); - update_subject_Field(form, 'ST=\"', form.state); - update_subject_Field(form, 'E=\"', form.email); - update_subject_Field(form, 'OU=\"', form.org_unit); - update_subject_Field(form, 'UID=\"', form.uid); -} - -function update_subject_Field(form, marker, update_field) -//updates a single subordinate field from the subject field of a form -// *** need to deal with the two types of e-mail addresses ************** -{ - with(form) { - var field_sep = '", '; - var begin_index = subject.value.indexOf(marker) + marker.length; - var end_index = subject.value.indexOf(field_sep, begin_index); - if (end_index == -1) { - end_index = subject.value.indexOf('"',begin_index); - } - if (begin_index != (-1 + marker.length) ) { - update_field.value = subject.value.substring(begin_index, end_index); - } else { - update_field.value = ''; - } - } -} - - -function switch_mail(form) -// **** Do I want to delete the other type of e-mail address ? ************ -{ - if (form.email_type[0].checked) { - var del = 'E='; - var ins = 'MAIL='; - } else { - var del = 'MAIL='; - var ins = 'E='; - } - reset_subject(del, '', form); - reset_subject(ins, form.email.value, form); -} - -function make_page_intro(title, bgcolor) -{ - var style = '<STYLE TYPE="text/css">BODY{' + - 'font-family: Geneva,MS Sans Serif,Arial,Lucida,Helvetica,sans-serif;' + - 'font-size: 10pt;' + - '}' + - 'TD{' + - 'font-family: Geneva,MS Sans Serif,Arial,Lucida,Helvetica,sans-serif;' + - 'font-size: 10pt;}' + - '</STYLE>'; - - if (bgcolor == null) { bgcolor = "#C0C0C0"; } - return '<HTML><HEAD>' + - '<TITLE>' + title + '</TITLE>' + - '</HEAD>' + - '<BODY TEXT="#000000" LINK="#000000" VLINK="#000000" ALINK="#FF0000" ' + - 'BGCOLOR="' + bgcolor + '">'; -} - - -function make_left_frame(window) -{ - with (window.frames['index']) { - eval ('index_string = make_left_frame_page(cur_page, ' - + index_list + add_index_list + ' )'); - fool1 = make_page_intro(index_label, "#FFFFFF") + - index_string + '</BODY></HTML>'; - document.write(fool1); - document.close(); - } -} - - -function save_cur_page(page_number) -{ - var len; - var pg = page_number - 1; - if (window.frames['right'].document.forms.length != 0) { - with (window.frames['right'].document) { - if ((page_number != 2 && page_number != 3 && page_number <= max_pages) || - ver == 3) { - ext_page_array[pg] = new Array(forms[0].elements.length); - for (i = 0; i < forms[0].elements.length; i++) { - ext_page_array[pg][i] = new Array(4); - switch (forms[0].elements[i].type) { - case 'radio': - case 'checkbox': - ext_page_array[pg][i][0] = forms[0].elements[i].checked; - break; - case 'select-one': - ext_page_array[pg][i][0] = forms[0].elements[i].selectedIndex; - break; - case 'select-multiple': - len = forms[0].elements[i].options.length; - ext_page_array[pg][i][0] = new Array(len); - for(k = 0; k < len; k++) { - ext_page_array[pg][i][0][k] = forms[0].elements[i].options[k].value; - } - break; - default: - ext_page_array[pg][i][0] = forms[0].elements[i].value; - } - ext_page_array[pg][i][1] = forms[0].elements[i].name; - ext_page_array[pg][i][2] = forms[0].elements[i].value; - ext_page_array[pg][i][3] = forms[0].elements[i].type; - } - } - } - } -} - -function reload_form(page_number) -{ - var j = page_number - 1; - with (window.frames['right'].document) { - if (((page_number < 2 || page_number > 3) || ver == 3) - && page_number != 0 && (ext_page_array[j].length > 1)) { - for (i = 0; i < ext_page_array[j].length; i++) { - switch (forms[0].elements[i].type) { - case 'radio': case 'checkbox': - forms[0].elements[i].checked = ext_page_array[j][i][0]; - break; - case 'select-one': - forms[0].elements[i].selectedIndex = ext_page_array[j][i][0]; - break; - case 'select-multiple': - for (k = 0; k < ext_page_array[j][i][0].length; k++) { - forms[0].elements[i].options[k] = - new Option(ext_page_array[j][i][0][k], - ext_page_array[j][i][0][k]); - } - break; - default: - forms[0].elements[i].value = ext_page_array[j][i][0]; - } - } - } - } -} - -function switch_right_frame(top_window, old_pane, new_pane) -{ - var ext_page_stnd = - make_page_intro(standard_extensions_index_label, "#FFFFFF") + - '<IFRAME WIDTH="100%" HEIGHT="100%" FRAMEBORDER=0 ID="ext" ' + - 'SRC="stnd_ext_form.html">' + - '</IFRAME></body></html>'; - - var ext_page_nscp = - make_page_intro(netscape_extensions_index_label, "#FFFFFF") + - '<IFRAME WIDTH="100%" HEIGHT="100%" FRAMEBORDER=0 ID="ext" ' + - 'SRC="nscp_ext_form.html">' + - '</IFRAME></body></html>'; - - var ext_page_ca = - make_page_intro(certifying_authorities_index_label, "#FFFFFF") + - '<IFRAME WIDTH="100%" HEIGHT="100%" FRAMEBORDER=0 ID="ext" ' + - 'SRC="ca.html">' + - '</IFRAME></body</html>'; - - var ext_page_ca_exp = - make_page_intro('Certifying Authority Details', "#FFFFFF") + - '<IFRAME WIDTH="100%" HEIGHT="100%" FRAMEBORDER=0 ID="ext" ' + - 'SRC="ca_form.html">' + - '</IFRAME></body></html>'; - - - if (old_pane > 0 && cur_page <= max_pages) { - save_cur_page(old_pane); - } - cur_page = new_pane; - make_left_frame(top_window); - if (new_pane == 2 || new_pane == 3) { - if (ver == 1) { - frames['right'].document.write(ext_page_ver1); - frames['right'].document.close(); - } else if (new_pane == 2) { - frames['right'].document.write(ext_page_nscp); - frames['right'].document.close(); - reload_form(new_pane); - } else { - frames['right'].document.write(ext_page_stnd); - frames['right'].document.close(); - reload_form(new_pane); - } - } else if (new_pane == 4) { - frames['right'].document.write(ext_page_ca); - frames['right'].document.close(); - reload_form(new_pane); - } else if (new_pane == 1) { - frames['right'].document.write(main_page); - frames['right'].document.close(); - reload_form(new_pane); - } else { - frames['right'].document.write(ext_page_ca_exp); - frames['right'].document.close(); - reload_form(new_pane); - } -} - -function make_left_frame_page(selected) -{ - var n_strings = ( make_left_frame_page.arguments.length - 1 ) / 2; - var table_background; - var command; - var indent; - var label; - var ret_string = ""; - - ret_string += '<TABLE CELLSPACING=4>'; - for ( var i = 1; i <= n_strings; i++ ) { - if ( i == selected ) { - table_background = 'BGCOLOR=#BBCCBB'; - } else { - table_background = ''; - } - - indent = make_left_frame_page.arguments[(i*2) - 1]; - label = make_left_frame_page.arguments[(i*2)]; - - if ( indent == 0 ) { - ret_string += ('<TR><TD COLSPAN=2 ' + table_background + '>'); - } else { - ret_string += ('<TR><TD> </TD><TD ' + table_background + '>'); - } - - command = "'parent.switch_right_frame(parent," + selected + "," + i + ")'"; - ret_string += ('<A HREF="javascript:void setTimeout(' + command + ',0)">'); - if ( indent == 0 ) { ret_string += "<B>"; } - ret_string += label; - if ( indent == 0 ) { ret_string += "</B>"; } - ret_string += '</A></TD></TR>'; - } - if (selected == (max_pages + 1)) { - table_background = 'BGCOLOR=#BBCCBB'; - } else { - table_background = ''; - } - ret_string += - '<TR><TD COLSPAN=2 ' + table_background + - '><b><A HREF="javascript:void setTimeout(\'top.submit_it()\', 0)">Finish</A></b>' + - '</TD></TR>' + - '<input type="submit"></form>' + - '</TABLE>'; - return(ret_string); -} - - -function make_page(window) -// Draws the initial page setup -{ - selected = cur_page - init_ext_page_array() - - with (window.frames['right']) { - location="main.html"; -// document.write(main_page); -// document.close(); - } - - make_left_frame(window); - -} -</script> - -</HEAD> -<title>Cert-O-Matic</title> - <FRAMESET cols="150,*" BORDER=3 ONLOAD="make_page(window)"> - <FRAME SRC="about:blank" ID="index" NAME="index" - MARGINWIDTH=15 MARGINHEIGHT=10 BORDER=3> - <FRAME SRC="about:blank" ID="right" NAME="right" - MARGINWIDTH=15 MARGINHEIGHT=10 BORDER=3> - </FRAMESET> -</HTML> diff --git a/security/nss/cmd/certcgi/main.html b/security/nss/cmd/certcgi/main.html deleted file mode 100644 index 05dd9daad..000000000 --- a/security/nss/cmd/certcgi/main.html +++ /dev/null @@ -1,76 +0,0 @@ -<HTML> -<!-- 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/. --> -<HEAD> - <TITLE>Main Layer for CertOMatic</TITLE> -</HEAD> - - <form method="post" name="primary_form" action="http://interzone.mcom.com/burp.cgi"> - <table border=0 cellspacing=10 cellpadding=0> - <tr> - <td> - Common Name:</td><td> <input type="text" name="name" onChange="{window.top.reset_subject('CN=', value, form)}"></p> - </td> - <td></td><td></td> - <td> - Organization: </td><td> <input type="text" name="org" onChange="{window.top.reset_subject('O=', value, form)}"></p></td> - <tr> - <td> - <input type="radio" name="email_type" value="1" onClick="window.top.switch_mail(form)">MAIL= - - <input type="radio" name="email_type" value="2" checked onClick="window.top.switch_mail(form)">E= - </td> - <td> - <input type="text" name="email" onChange="var temp;{if (email_type[0].checked) {temp = 'MAIL='} else {temp = 'E='}} ;{window.top.reset_subject(temp, value, form)}"> - </td> - <td></td><td></td><td> - Organizational Unit: </td><td><input type="text" name="org_unit" onChange="{window.top.reset_subject('OU=', value, form)}"></p></td> - <tr> - <td> - UID= </td><td><input type="text" name="uid" onChange="{window.top.reset_subject('UID=', value, form)}"></p></td> - <td></td><td></td><td> - Locality: </td><td><input type="text" name="loc" onChange="{window.top.reset_subject('L=', value, form)}"></p></td> - <tr> - <td> - State or Province: </td><td><input type="text" name="state" onChange="{window.top.reset_subject('ST=', value, form)}"></p></td> - <td></td><td></td><td> - Country: </td><td><input type="text" size="2" name="country" onChange="{window.top.reset_subject('C=', value, form)}" maxlength="2"></p></td> - <tr> - <td COLSPAN=2> - Serial Number: - <DD><input type="radio" name="serial" value="auto" checked> Auto Generate - <DD><input type="radio" name="serial" value="input"> - Use this hex value: <input type="text" name="serial_value" size="8" maxlength="8"></p> - </td> - <td></td> <td></td> - <td COLSPAN=2> - X.509 version: - <DD><input type="radio" name="ver" value="1" onClick="if (this.checked) {window.top.set_ver1();}"> Version 1 - <DD><input type="radio" name="ver" value="3" checked onClick="if (this.checked) {window.top.set_ver3();}"> Version 3</P></td> - <tr> - <td COLSPAN=2> - Key Type: - <DD><input type="radio" name="keyType" value="rsa" checked> RSA - <DD><input type="radio" name="keyType" value="dsa"> DSA</p> - Intermediate CA Key Sizes: - <DD><select name="keysize"> - <option>2048 (Very High Grade) - <option>1024 (High Grade) - <option>512 (Low Grade) - </select> - </td> - <td></td> <td></td> - <td COLSPAN=2> - Validity: - <DD><input type="radio" name="validity" value="auto" checked> - Generate Automatically - <DD><input type="radio" name="validity" value="man"> Use these values: - <DD>Not Before: <input type="text" size="15" maxlength="17" name="notBefore"> - <DD>Not After: <input type="text" size="15" maxlength="17" name="notAfter"> - <DD> - <FONT SIZE=-1><TT>YYMMDDhhmm[ss]{Z|+hhmm|-hhmm} </TT></FONT> - </table> - DN: <input type="text" name="subject" size="70" onChange="{window.top.reset_subjectFields(form)}"></P> - </form> -</HTML> diff --git a/security/nss/cmd/certcgi/manifest.mn b/security/nss/cmd/certcgi/manifest.mn deleted file mode 100644 index 9e17cef9d..000000000 --- a/security/nss/cmd/certcgi/manifest.mn +++ /dev/null @@ -1,22 +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 public and private header directories are implicitly REQUIREd. -MODULE = nss - -# This next line is used by .mk files -# and gets translated into $LINCS in manifest.mnw -REQUIRES = seccmd dbm - -DEFINES = -DNSPR20 - -CSRCS = certcgi.c - -PROGRAM = certcgi - -USE_STATIC_LIBS = 1 - diff --git a/security/nss/cmd/certcgi/nscp_ext_form.html b/security/nss/cmd/certcgi/nscp_ext_form.html deleted file mode 100644 index f2a4a20c3..000000000 --- a/security/nss/cmd/certcgi/nscp_ext_form.html +++ /dev/null @@ -1,84 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> -<html> -<!-- 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/. --> - - <body> - <table border=1 cellspacing=5 cellpadding=5> - <form method="post" name="primary_form" action="http://interzone.mcom.com/burp.cgi"> - <tr> - <td> - <b>Netscape Certificate Type: </b></p> - Activate extension: <input type="checkbox" name="netscape-cert-type"></P> - Critical: <input type="checkbox" name="netscape-cert-type-crit"> - <td> - <input type="checkbox" name="netscape-cert-type-ssl-client"> SSL Client</P> - <input type="checkbox" name="netscape-cert-type-ssl-server"> SSL Server</P> - <input type="checkbox" name="netscape-cert-type-smime"> S/MIME</P> - <input type="checkbox" name="netscape-cert-type-object-signing"> Object Signing</P> - <input type="checkbox" name="netscape-cert-type-reserved"> Reserved for future use (bit 4)</P> - <input type="checkbox" name="netscape-cert-type-ssl-ca"> SSL CA</P> - <input type="checkbox" name="netscape-cert-type-smime-ca"> S/MIME CA</P> - <input type="checkbox" name="netscape-cert-type-object-signing-ca"> Object Signing CA</P> - </tr> - <tr> - <td> - <b>Netscape Base URL:</b></p> - Activate extension: <input type="checkbox" name="netscape-base-url"></P> - Critical: <input type="checkbox" name="netscape-base-url-crit"> - <td> - <input type="text" name="netscape-base-url-text" size="50"> - </tr> - <tr> - <td> - <b>Netscape Revocation URL:</b></p> - Activate extension: <input type="checkbox" name="netscape-revocation-url"></P> - Critical: <input type="checkbox" name="netscape-revocation-url-crit"> - <td> - <input type="text" name="netscape-revocation-url-text" size="50"> - </tr> - <tr> - <td> - <b>Netscape CA Revocation URL:</b></p> - Activate extension: <input type="checkbox" name="netscape-ca-revocation-url"></P> - Critical: <input type="checkbox" name="netscape-ca-revocation-url-crit"> - <td> - <input type="text" name="netscape-ca-revocation-url-text" size="50"> - </tr> - <tr> - <td> - <b>Netscape Certificate Renewal URL:</b></p> - Activate extension: <input type="checkbox" name="netscape-cert-renewal-url"></P> - Critical: <input type="checkbox" name="netscape-cert-renewal-url-crit"> - <td> - <input type="text" name="netscape-cert-renewal-url-text" size="50"> - </tr> - <tr> - <td> - <b>Netscape CA Policy URL:</b></p> - Activate extension: <input type="checkbox" name="netscape-ca-policy-url"></P> - Critical: <input type="checkbox" name="netscape-ca-policy-url-crit"> - <td> - <input type="text" name="netscape-ca-policy-url-text" size="50"> - </tr> - <tr> - <td> - <b>Netscape SSL Server Name:</b></p> - Activate extension: <input type="checkbox" name="netscape-ssl-server-name"></P> - Critical: <input type="checkbox" name="netscape-ssl-server-name-crit"> - <td> - <input type="text" name="netscape-ssl-server-name-text" size="50"> - </tr> - <tr> - <td> - <b>Netscape Comment:</b></p> - Activate extension: <input type="checkbox" name="netscape-comment"></P> - Critical: <input type="checkbox" name="netscape-comment-crit"> - <td> - <textarea name="netscape-comment-text" rows="5" cols="50"></textarea> - </tr> - - </table> - </body> -</html> diff --git a/security/nss/cmd/certcgi/stnd_ext_form.html b/security/nss/cmd/certcgi/stnd_ext_form.html deleted file mode 100644 index 60d4d86a0..000000000 --- a/security/nss/cmd/certcgi/stnd_ext_form.html +++ /dev/null @@ -1,219 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> -<html> -<!-- 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/. --> - - <body> - <table border=1 cellspacing=5 cellpadding=5> - <form method="post" name="primary_form" action="http://interzone.mcom.com/burp.cgi"> - <tr> - <td> - <b>Key Usage: </b></p> - Activate extension: <input type="checkbox" name="keyUsage"></P> - Critical: <input type="checkbox" name="keyUsage-crit"> - <td> - <input type="checkbox" name="keyUsage-digitalSignature"> Digital Signature</P> - <input type="checkbox" name="keyUsage-nonRepudiation"> Non Repudiation</P> - <input type="checkbox" name="keyUsage-keyEncipherment"> Key Encipherment</P> - <input type="checkbox" name="keyUsage-dataEncipherment"> Data Encipherment</P> - <input type="checkbox" name="keyUsage-keyAgreement"> Key Agreement</P> - <input type="checkbox" name="keyUsage-keyCertSign"> Key Certificate Signing</P> - <input type="checkbox" name="keyUsage-cRLSign"> CRL Signing</P> - </tr> - <tr> - <td> - <b>Extended Key Usage: </b></p> - Activate extension: <input type="checkbox" name="extKeyUsage"></P> - Critical: <input type="checkbox" name="extKeyUsage-crit"> - <td> - <input type="checkbox" name="extKeyUsage-serverAuth"> Server Auth</P> - <input type="checkbox" name="extKeyUsage-clientAuth"> Client Auth</P> - <input type="checkbox" name="extKeyUsage-codeSign"> Code Signing</P> - <input type="checkbox" name="extKeyUsage-emailProtect"> Email Protection</P> - <input type="checkbox" name="extKeyUsage-timeStamp"> Timestamp</P> - <input type="checkbox" name="extKeyUsage-ocspResponder"> OCSP Responder</P> - <input type="checkbox" name="extKeyUsage-NS-govtApproved"> Step-up</P> - <input type="checkbox" name="extKeyUsage-msTrustListSign"> Microsoft Trust List Signing</P> - </tr> - <tr> - <td> - <b>Basic Constraints:</b></p> - Activate extension: <input type="checkbox" name="basicConstraints"></P> - Critical: <input type="checkbox" name="basicConstraints-crit"> - <td> - CA:</p> - <dd><input type=radio name="basicConstraints-cA-radio" value="CA"> True</p> - <dd><input type=radio name="basicConstraints-cA-radio" value="NotCA"> False</p> - <input type="checkbox" name="basicConstraints-pathLengthConstraint"> - Include Path length: <input type="text" name="basicConstraints-pathLengthConstraint-text" size="2"></p> - </tr> - <tr> - <td> - <b>Authority Key Identifier:</b></p> - Activate extension: <input type="checkbox" name="authorityKeyIdentifier"> - <td> - <input type="radio" name="authorityKeyIdentifier-radio" value="keyIdentifier"> Key Identider</p> - <input type="radio" name="authorityKeyIdentifier-radio" value="authorityCertIssuer"> Issuer Name and Serial number</p> - </tr> - <tr> - <td> - <b>Subject Key Identifier:</b></p> - Activate extension: <input type="checkbox" name="subjectKeyIdentifier"> - <td> - Key Identifier: - <input type="text" name="subjectKeyIdentifier-text"></p> - This is an:<p> - <dd><dd><input type="radio" name="subjectKeyIdentifier-radio" value="ascii"> ascii text value<p> - <dd><dd><input type="radio" name="subjectKeyIdentifier-radio" value="hex"> hex value<p> - </tr> - <tr> - <td> - <b>Private Key Usage Period:</b></p> - Activate extension: <input type="checkbox" name="privKeyUsagePeriod"></p> - Critical: <input type="checkbox" name="privKeyUsagePeriod-crit"> - <td> - Use:</p> - <dd><input type="radio" name="privKeyUsagePeriod-radio" value="notBefore"> Not Before</p> - <dd><input type="radio" name="privKeyUsagePeriod-radio" value="notAfter"> Not After</p> - <dd><input type="radio" name="privKeyUsagePeriod-radio" value="both" > Both</p> - <b>Not to be used to sign before:</b></p> - <dd><input type="radio" name="privKeyUsagePeriod-notBefore-radio" value="auto"> Set to time of certificate issue</p> - <dd><input type="radio" name="privKeyUsagePeriod-notBefore-radio" value="manual"> Use This value</p> - <dd><dd>(YYYY/MM/DD HH:MM:SS): - <input type="text" name="privKeyUsagePeriod-notBefore-year" size="4" maxlength="4">/ - <input type="text" name="privKeyUsagePeriod-notBefore-month" size="2" maxlength="2">/ - <input type="text" name="privKeyUsagePeriod-notBefore-day" size="2" maxlength="2"> - <input type="text" name="privKeyUsagePeriod-notBefore-hour" size="2" maxlength="2">: - <input type="text" name="privKeyUsagePeriod-notBefore-minute" size="2" maxlength="2">: - <input type="text" name="privKeyUsagePeriod-notBefore-second" size="2" maxlength="2"></p> - <b>Not to be used to sign after:</b></p> - <dd>(YYYY/MM/DD HH:MM:SS): - <input type="text" name="privKeyUsagePeriod-notAfter-year" size="4" maxlength="4">/ - <input type="text" name="privKeyUsagePeriod-notAfter-month" size="2" maxlength="2">/ - <input type="text" name="privKeyUsagePeriod-notAfter-day" size="2" maxlength="2"> - <input type="text" name="privKeyUsagePeriod-notAfter-hour" size="2" maxlength="2">: - <input type="text" name="privKeyUsagePeriod-notAfter-minute" size="2" maxlength="2">: - <input type="text" name="privKeyUsagePeriod-notAfter-second" size="2" maxlength="2"></p> - </tr> - <tr> - <td> - <b>Subject Alternative Name:</b></p> - Activate extension: <input type="checkbox" name="SubAltName"></P> - Critical: <input type="checkbox" name="SubAltName-crit"> - <td> - <table> - <tr> - <td> - General Names:</p> - <select name="SubAltNameSelect" multiple size="10"> - </select></p></p> - <input type="button" name="SubAltName-add" value="Add" onClick="{parent.addSubAltName(this.form)}"> - <input type="button" name="SubAltName-delete" value="Delete" onClick="parent.deleteSubAltName(this.form)"> - </td><td> - <table><tr><td> - Name Type: </td></tr><tr><td> - <input type="radio" name="SubAltNameRadio" value="otherName" onClick="parent.setSubAltNameType(form)"> Other Name, - OID: <input type="text" name="SubAltNameOtherNameOID" size="6"> </td><td> - <input type="radio" name="SubAltNameRadio" value="rfc822Name" onClick="parent.setSubAltNameType(form)"> RFC 822 Name</td></tr><td> - <input type="radio" name="SubAltNameRadio" value="dnsName" onClick="parent.setSubAltNameType(form)"> DNS Name </td><td> - <input type="radio" name="SubAltNameRadio" value="x400" onClick="parent.setSubAltNameType(form)"> X400 Address</td></tr><td> - <input type="radio" name="SubAltNameRadio" value="directoryName" onClick="parent.setSubAltNameType(form)"> Directory Name</td><td> - <input type="radio" name="SubAltNameRadio" value="ediPartyName" onClick="parent.setSubAltNameType(form)"> EDI Party Name</td></tr><td> - <input type="radio" name="SubAltNameRadio" value="URL" onClick="parent.setSubAltNameType(form)"> Uniform Resource Locator</td><td> - <input type="radio" name="SubAltNameRadio" value="ipAddress" onClick="parent.setSubAltNameType(form)"> IP Address</td></tr><td> - <input type="radio" name="SubAltNameRadio" value="regID"onClick="parent.setSubAltNameType(form)"> Registered ID</td><td> - <input type="radio" name="SubAltNameRadio" value="nscpNickname" onClick="parent.setSubAltNameType(form)"> Netscape Certificate Nickname</td><td></tr> - </table> - Name: <input type="text" name="SubAltNameText"> - Binary Encoded: <input type="checkbox" name="SubAltNameDataType" value="binary" onClick="parent.setSubAltNameType(form)"></p> - </tr> - </table> - </tr> - - - <tr> - <td> - <b>Issuer Alternative Name:</b></p> - Activate extension: <input type="checkbox" name="IssuerAltName"></P> - Critical: <input type="checkbox" name="IssuerAltName-crit"> - <td> - <input type="radio" name="IssuerAltNameSourceRadio" value="auto"> Use the Subject Alternative Name from the Issuers Certificate</p> - <input type="radio" name="IssuerAltNameSourceRadio" value="man"> Use this Name: - <table> - <tr> - <td> - General Names:</p> - <select name="IssuerAltNameSelect" multiple size="10"> - </select></p></p> - <input type="button" name="IssuerAltName-add" value="Add" onClick="{parent.addIssuerAltName(this.form)}"> - <input type="button" name="IssuerAltName-delete" value="Delete" onClick="parent.deleteIssuerAltName(this.form)"> - </td><td> - <table><tr><td> - Name Type: </td></tr><tr><td> - <input type="radio" name="IssuerAltNameRadio" value="otherName" onClick="parent.setIssuerAltNameType(form)"> Other Name, - OID: <input type="text" name="IssuerAltNameOtherNameOID" size="6"> </td><td> - <input type="radio" name="IssuerAltNameRadio" value="rfc822Name" onClick="parent.setIssuerAltNameType(form)"> RFC 822 Name</td></tr><td> - <input type="radio" name="IssuerAltNameRadio" value="dnsName" onClick="parent.setIssuerAltNameType(form)"> DNS Name </td><td> - <input type="radio" name="IssuerAltNameRadio" value="x400" onClick="parent.setIssuerAltNameType(form)"> X400 Address</td></tr><td> - <input type="radio" name="IssuerAltNameRadio" value="directoryName" onClick="parent.setIssuerAltNameType(form)"> Directory Name</td><td> - <input type="radio" name="IssuerAltNameRadio" value="ediPartyName" onClick="parent.setIssuerAltNameType(form)"> EDI Party Name</td></tr><td> - <input type="radio" name="IssuerAltNameRadio" value="URL" onClick="parent.setIssuerAltNameType(form)"> Uniform Resource Locator</td><td> - <input type="radio" name="IssuerAltNameRadio" value="ipAddress" onClick="parent.setIssuerAltNameType(form)"> IP Address</td></tr><td> - <input type="radio" name="IssuerAltNameRadio" value="regID" onClick="parent.setIssuerAltNameType(form)"> Registered ID</td><td></tr> - </table> - Name: <input type="text" name="IssuerAltNameText"> - Binary Encoded: <input type="checkbox" name="IssuerAltNameDataType" value="binary" onClick="parent.setIssuerAltNameType(form)"></p> - </tr> - </table> - </tr> - - <tr> - <td> - <b>Name Constraints:</b></p> - Activate extension: <input type="checkbox" name="NameConstraints"></P> - <td> - <table> - <tr> - <td> - Name Constraints:</p> - <select name="NameConstraintSelect" multiple size="10"> - </select></p></p> - <input type="button" name="NameConstraint-add" value="Add" onClick="{parent.addNameConstraint(this.form)}"> - <input type="button" name="NameConstraint-delete" value="Delete" onClick="parent.deleteNameConstraint(this.form)"> - </td><td> - <table><tr><td> - Name Type: </td></tr><tr><td> - <input type="radio" name="NameConstraintRadio" value="otherName" onClick="parent.setNameConstraintNameType(form)"> Other Name, - OID: <input type="text" name="NameConstraintOtherNameOID" size="6"> </td><td> - <input type="radio" name="NameConstraintRadio" value="rfc822Name" onClick="parent.setNameConstraintNameType(form)"> RFC 822 Name</td></tr><td> - <input type="radio" name="NameConstraintRadio" value="dnsName" onClick="parent.setNameConstraintNameType(form)"> DNS Name </td><td> - <input type="radio" name="NameConstraintRadio" value="x400" onClick="parent.setNameConstraintNameType(form)"> X400 Address</td></tr><td> - <input type="radio" name="NameConstraintRadio" value="directoryName" onClick="parent.setNameConstraintNameType(form)"> Directory Name</td><td> - <input type="radio" name="NameConstraintRadio" value="ediPartyName" onClick="parent.setNameConstraintNameType(form)"> EDI Party Name</td></tr><td> - <input type="radio" name="NameConstraintRadio" value="URL" onClick="parent.setNameConstraintNameType(form)"> Uniform Resource Locator</td><td> - <input type="radio" name="NameConstraintRadio" value="ipAddress" onClick="parent.setNameConstraintNameType(form)"> IP Address</td></tr><td> - <input type="radio" name="NameConstraintRadio" value="regID" onClick="parent.setNameConstraintNameType(form)"> Registered ID</td><td></tr> - </table> - Name: <input type="text" name="NameConstraintText"> - Binary Encoded: <input type="checkbox" name="NameConstraintNameDataType" value="binary" onClick="parent.setNameConstraintNameType(form)"></p> - Constraint type:<p> - <dd><input type="radio" name="NameConstraintTypeRadio" value="permited"> permited<p> - <dd><input type="radio" name="NameConstraintTypeRadio" value="excluded"> excluded<p> - Minimum: <input type="text" name="NameConstraintMin" size="8" maxlength="8"></p> - Maximum: <input type="text" name="NameConstraintMax" size="8" maxlength="8"></p> - </tr> - </table> - </tr> - - </table> - </body> -</html> - - - - - - - - diff --git a/security/nss/cmd/certutil/certutil.c b/security/nss/cmd/certutil/certutil.c index fbc752c1b..20722ae78 100644 --- a/security/nss/cmd/certutil/certutil.c +++ b/security/nss/cmd/certutil/certutil.c @@ -194,6 +194,8 @@ CertReq(SECKEYPrivateKey *privk, SECKEYPublicKey *pubk, KeyType keyType, PLArenaPool *arena; void *extHandle; SECItem signedReq = { siBuffer, NULL, 0 }; + SECAlgorithmID signAlg; + SECItem *params = NULL; arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if (!arena) { @@ -211,11 +213,26 @@ CertReq(SECKEYPrivateKey *privk, SECKEYPublicKey *pubk, KeyType keyType, /* Change cert type to RSA-PSS, if desired. */ if (pssCertificate) { + params = SEC_CreateSignatureAlgorithmParameters(arena, + NULL, + SEC_OID_PKCS1_RSA_PSS_SIGNATURE, + hashAlgTag, + NULL, + privk); + if (!params) { + PORT_FreeArena(arena, PR_FALSE); + SECKEY_DestroySubjectPublicKeyInfo(spki); + SECU_PrintError(progName, "unable to create RSA-PSS parameters"); + return SECFailure; + } + spki->algorithm.parameters.data = NULL; rv = SECOID_SetAlgorithmID(arena, &spki->algorithm, - SEC_OID_PKCS1_RSA_PSS_SIGNATURE, 0); + SEC_OID_PKCS1_RSA_PSS_SIGNATURE, + hashAlgTag == SEC_OID_UNKNOWN ? NULL : params); if (rv != SECSuccess) { PORT_FreeArena(arena, PR_FALSE); + SECKEY_DestroySubjectPublicKeyInfo(spki); SECU_PrintError(progName, "unable to set algorithm ID"); return SECFailure; } @@ -256,16 +273,34 @@ CertReq(SECKEYPrivateKey *privk, SECKEYPublicKey *pubk, KeyType keyType, return SECFailure; } - /* Sign the request */ - signAlgTag = SEC_GetSignatureAlgorithmOidTag(keyType, hashAlgTag); - if (signAlgTag == SEC_OID_UNKNOWN) { - PORT_FreeArena(arena, PR_FALSE); - SECU_PrintError(progName, "unknown Key or Hash type"); - return SECFailure; + PORT_Memset(&signAlg, 0, sizeof(signAlg)); + if (pssCertificate) { + rv = SECOID_SetAlgorithmID(arena, &signAlg, + SEC_OID_PKCS1_RSA_PSS_SIGNATURE, params); + if (rv != SECSuccess) { + PORT_FreeArena(arena, PR_FALSE); + SECU_PrintError(progName, "unable to set algorithm ID"); + return SECFailure; + } + } else { + signAlgTag = SEC_GetSignatureAlgorithmOidTag(keyType, hashAlgTag); + if (signAlgTag == SEC_OID_UNKNOWN) { + PORT_FreeArena(arena, PR_FALSE); + SECU_PrintError(progName, "unknown Key or Hash type"); + return SECFailure; + } + rv = SECOID_SetAlgorithmID(arena, &signAlg, signAlgTag, 0); + if (rv != SECSuccess) { + PORT_FreeArena(arena, PR_FALSE); + SECU_PrintError(progName, "unable to set algorithm ID"); + return SECFailure; + } } - rv = SEC_DerSignData(arena, &signedReq, encoding->data, encoding->len, - privk, signAlgTag); + /* Sign the request */ + rv = SEC_DerSignDataWithAlgorithmID(arena, &signedReq, + encoding->data, encoding->len, + privk, &signAlg); if (rv) { PORT_FreeArena(arena, PR_FALSE); SECU_PrintError(progName, "signing of data failed"); @@ -365,7 +400,7 @@ ChangeTrustAttributes(CERTCertDBHandle *handle, PK11SlotInfo *slot, CERTCertificate *cert; CERTCertTrust *trust; - cert = CERT_FindCertByNicknameOrEmailAddr(handle, name); + cert = CERT_FindCertByNicknameOrEmailAddrCX(handle, name, pwdata); if (!cert) { SECU_PrintError(progName, "could not find certificate named \"%s\"", name); @@ -591,6 +626,10 @@ ListCerts(CERTCertDBHandle *handle, char *nickname, char *email, { SECStatus rv; + if (slot && PK11_NeedUserInit(slot)) { + printf("\nDatabase needs user init\n"); + } + if (!ascii && !raw && !nickname && !email) { PR_fprintf(outfile, "\n%-60s %-5s\n%-60s %-5s\n\n", "Certificate Nickname", "Trust Attributes", "", @@ -614,12 +653,12 @@ ListCerts(CERTCertDBHandle *handle, char *nickname, char *email, } static SECStatus -DeleteCert(CERTCertDBHandle *handle, char *name) +DeleteCert(CERTCertDBHandle *handle, char *name, void *pwdata) { SECStatus rv; CERTCertificate *cert; - cert = CERT_FindCertByNicknameOrEmailAddr(handle, name); + cert = CERT_FindCertByNicknameOrEmailAddrCX(handle, name, pwdata); if (!cert) { SECU_PrintError(progName, "could not find certificate named \"%s\"", name); @@ -635,12 +674,12 @@ DeleteCert(CERTCertDBHandle *handle, char *name) } static SECStatus -RenameCert(CERTCertDBHandle *handle, char *name, char *newName) +RenameCert(CERTCertDBHandle *handle, char *name, char *newName, void *pwdata) { SECStatus rv; CERTCertificate *cert; - cert = CERT_FindCertByNicknameOrEmailAddr(handle, name); + cert = CERT_FindCertByNicknameOrEmailAddrCX(handle, name, pwdata); if (!cert) { SECU_PrintError(progName, "could not find certificate named \"%s\"", name); @@ -1015,6 +1054,18 @@ ListModules(void) } static void +PrintBuildFlags() +{ +#ifdef NSS_FIPS_DISABLED + PR_fprintf(PR_STDOUT, "NSS_FIPS_DISABLED\n"); +#endif +#ifdef NSS_NO_INIT_SUPPORT + PR_fprintf(PR_STDOUT, "NSS_NO_INIT_SUPPORT\n"); +#endif + exit(0); +} + +static void PrintSyntax(char *progName) { #define FPS fprintf(stderr, @@ -1044,15 +1095,10 @@ PrintSyntax(char *progName) "\t\t [-f pwfile] [-z noisefile] [-d certdir] [-P dbprefix]\n", progName); FPS "\t%s -G [-h token-name] -k dsa [-q pqgfile -g key-size] [-f pwfile]\n" "\t\t [-z noisefile] [-d certdir] [-P dbprefix]\n", progName); -#ifndef NSS_DISABLE_ECC FPS "\t%s -G [-h token-name] -k ec -q curve [-f pwfile]\n" "\t\t [-z noisefile] [-d certdir] [-P dbprefix]\n", progName); FPS "\t%s -K [-n key-name] [-h token-name] [-k dsa|ec|rsa|all]\n", progName); -#else - FPS "\t%s -K [-n key-name] [-h token-name] [-k dsa|rsa|all]\n", - progName); -#endif /* NSS_DISABLE_ECC */ FPS "\t\t [-f pwfile] [-X] [-d certdir] [-P dbprefix]\n"); FPS "\t%s --upgrade-merge --source-dir upgradeDir --upgrade-id uniqueID\n", progName); @@ -1066,6 +1112,7 @@ PrintSyntax(char *progName) FPS "\t%s -L [-n cert-name] [-h token-name] [--email email-address]\n", progName); FPS "\t\t [-X] [-r] [-a] [--dump-ext-val OID] [-d certdir] [-P dbprefix]\n"); + 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); @@ -1184,6 +1231,8 @@ luC(enum usage_level ul, const char *command) " -o output-cert"); FPS "%-20s Self sign\n", " -x"); + FPS "%-20s Sign the certificate with RSA-PSS (the issuer key must be rsa)\n", + " --pss-sign"); FPS "%-20s Cert serial number\n", " -m serial-number"); FPS "%-20s Time Warp\n", @@ -1244,17 +1293,10 @@ luG(enum usage_level ul, const char *command) return; FPS "%-20s Name of token in which to generate key (default is internal)\n", " -h token-name"); -#ifndef NSS_DISABLE_ECC FPS "%-20s Type of key pair to generate (\"dsa\", \"ec\", \"rsa\" (default))\n", " -k key-type"); FPS "%-20s Key size in bits, (min %d, max %d, default %d) (not for ec)\n", " -g key-size", MIN_KEY_BITS, MAX_KEY_BITS, DEFAULT_KEY_BITS); -#else - FPS "%-20s Type of key pair to generate (\"dsa\", \"rsa\" (default))\n", - " -k key-type"); - FPS "%-20s Key size in bits, (min %d, max %d, default %d)\n", - " -g key-size", MIN_KEY_BITS, MAX_KEY_BITS, DEFAULT_KEY_BITS); -#endif /* NSS_DISABLE_ECC */ FPS "%-20s Set the public exponent value (3, 17, 65537) (rsa only)\n", " -y exp"); FPS "%-20s Specify the password file\n", @@ -1263,7 +1305,6 @@ luG(enum usage_level ul, const char *command) " -z noisefile"); FPS "%-20s read PQG value from pqgfile (dsa only)\n", " -q pqgfile"); -#ifndef NSS_DISABLE_ECC FPS "%-20s Elliptic curve name (ec only)\n", " -q curve-name"); FPS "%-20s One of nistp256, nistp384, nistp521, curve25519.\n", ""); @@ -1285,7 +1326,6 @@ luG(enum usage_level ul, const char *command) FPS "%-20s c2tnb359w1, c2pnb368w1, c2tnb431r1, secp112r1, \n", ""); FPS "%-20s secp112r2, secp128r1, secp128r2, sect113r1, sect113r2\n", ""); FPS "%-20s sect131r1, sect131r2\n", ""); -#endif FPS "%-20s Key database directory (default is ~/.netscape)\n", " -d keydir"); FPS "%-20s Cert & Key database prefix\n", @@ -1331,7 +1371,7 @@ luF(enum usage_level ul, const char *command) { int is_my_command = (command && 0 == strcmp(command, "F")); if (ul == usage_all || !command || is_my_command) - FPS "%-15s Delete a key from the database\n", + FPS "%-15s Delete a key and associated certificate from the database\n", "-F"); if (ul == usage_selected && !is_my_command) return; @@ -1375,9 +1415,7 @@ luK(enum usage_level ul, const char *command) " -h token-name "); FPS "%-20s Key type (\"all\" (default), \"dsa\"," -#ifndef NSS_DISABLE_ECC " \"ec\"," -#endif " \"rsa\")\n", " -k key-type"); FPS "%-20s The nickname of the key or associated certificate\n", @@ -1520,11 +1558,7 @@ luR(enum usage_level ul, const char *command) " -s subject"); FPS "%-20s Output the cert request to this file\n", " -o output-req"); -#ifndef NSS_DISABLE_ECC FPS "%-20s Type of key pair to generate (\"dsa\", \"ec\", \"rsa\" (default))\n", -#else - FPS "%-20s Type of key pair to generate (\"dsa\", \"rsa\" (default))\n", -#endif /* NSS_DISABLE_ECC */ " -k key-type-or-id"); FPS "%-20s or nickname of the cert key to use \n", ""); @@ -1532,14 +1566,14 @@ luR(enum usage_level ul, const char *command) " -h token-name"); FPS "%-20s Key size in bits, RSA keys only (min %d, max %d, default %d)\n", " -g key-size", MIN_KEY_BITS, MAX_KEY_BITS, DEFAULT_KEY_BITS); + FPS "%-20s Create a certificate request restricted to RSA-PSS (rsa only)\n", + " --pss"); FPS "%-20s Name of file containing PQG parameters (dsa only)\n", " -q pqgfile"); -#ifndef NSS_DISABLE_ECC FPS "%-20s Elliptic curve name (ec only)\n", " -q curve-name"); FPS "%-20s See the \"-G\" option for a full list of supported names.\n", ""); -#endif /* NSS_DISABLE_ECC */ FPS "%-20s Specify the password file\n", " -f pwfile"); FPS "%-20s Key database directory (default is ~/.netscape)\n", @@ -1705,26 +1739,24 @@ luS(enum usage_level ul, const char *command) " -c issuer-name"); FPS "%-20s Set the certificate trust attributes (see -A above)\n", " -t trustargs"); -#ifndef NSS_DISABLE_ECC FPS "%-20s Type of key pair to generate (\"dsa\", \"ec\", \"rsa\" (default))\n", -#else - FPS "%-20s Type of key pair to generate (\"dsa\", \"rsa\" (default))\n", -#endif /* NSS_DISABLE_ECC */ " -k key-type-or-id"); FPS "%-20s Name of token in which to generate key (default is internal)\n", " -h token-name"); FPS "%-20s Key size in bits, RSA keys only (min %d, max %d, default %d)\n", " -g key-size", MIN_KEY_BITS, MAX_KEY_BITS, DEFAULT_KEY_BITS); + FPS "%-20s Create a certificate restricted to RSA-PSS (rsa only)\n", + " --pss"); FPS "%-20s Name of file containing PQG parameters (dsa only)\n", " -q pqgfile"); -#ifndef NSS_DISABLE_ECC FPS "%-20s Elliptic curve name (ec only)\n", " -q curve-name"); FPS "%-20s See the \"-G\" option for a full list of supported names.\n", ""); -#endif /* NSS_DISABLE_ECC */ FPS "%-20s Self sign\n", " -x"); + FPS "%-20s Sign the certificate with RSA-PSS (the issuer key must be rsa)\n", + " --pss-sign"); FPS "%-20s Cert serial number\n", " -m serial-number"); FPS "%-20s Time Warp\n", @@ -1794,6 +1826,18 @@ luS(enum usage_level ul, const char *command) } static void +luBuildFlags(enum usage_level ul, const char *command) +{ + int is_my_command = (command && 0 == strcmp(command, "build-flags")); + if (ul == usage_all || !command || is_my_command) + FPS "%-15s Print enabled build flags relevant for NSS test execution\n", + "--build-flags"); + if (ul == usage_selected && !is_my_command) + return; + FPS "\n"); +} + +static void LongUsage(char *progName, enum usage_level ul, const char *command) { luA(ul, command); @@ -1807,6 +1851,7 @@ LongUsage(char *progName, enum usage_level ul, const char *command) luU(ul, command); luK(ul, command); luL(ul, command); + luBuildFlags(ul, command); luM(ul, command); luN(ul, command); luT(ul, command); @@ -1889,46 +1934,119 @@ MakeV1Cert(CERTCertDBHandle *handle, } static SECStatus +SetSignatureAlgorithm(PLArenaPool *arena, + SECAlgorithmID *signAlg, + SECAlgorithmID *spkiAlg, + SECOidTag hashAlgTag, + SECKEYPrivateKey *privKey, + PRBool pssSign) +{ + SECStatus rv; + + if (pssSign || + SECOID_GetAlgorithmTag(spkiAlg) == SEC_OID_PKCS1_RSA_PSS_SIGNATURE) { + SECItem *srcParams; + SECItem *params; + + if (SECOID_GetAlgorithmTag(spkiAlg) == SEC_OID_PKCS1_RSA_PSS_SIGNATURE) { + srcParams = &spkiAlg->parameters; + } else { + /* If the issuer's public key is RSA, the parameter field + * of the SPKI should be NULL, which can't be used as a + * basis of RSA-PSS parameters. */ + srcParams = NULL; + } + params = SEC_CreateSignatureAlgorithmParameters(arena, + NULL, + SEC_OID_PKCS1_RSA_PSS_SIGNATURE, + hashAlgTag, + srcParams, + privKey); + if (!params) { + SECU_PrintError(progName, "Could not create RSA-PSS parameters"); + return SECFailure; + } + rv = SECOID_SetAlgorithmID(arena, signAlg, + SEC_OID_PKCS1_RSA_PSS_SIGNATURE, + params); + if (rv != SECSuccess) { + SECU_PrintError(progName, "Could not set signature algorithm id."); + return rv; + } + } else { + KeyType keyType = SECKEY_GetPrivateKeyType(privKey); + SECOidTag algID; + + algID = SEC_GetSignatureAlgorithmOidTag(keyType, hashAlgTag); + if (algID == SEC_OID_UNKNOWN) { + SECU_PrintError(progName, "Unknown key or hash type for issuer."); + return SECFailure; + } + rv = SECOID_SetAlgorithmID(arena, signAlg, algID, 0); + if (rv != SECSuccess) { + SECU_PrintError(progName, "Could not set signature algorithm id."); + return rv; + } + } + return SECSuccess; +} + +static SECStatus SignCert(CERTCertDBHandle *handle, CERTCertificate *cert, PRBool selfsign, SECOidTag hashAlgTag, SECKEYPrivateKey *privKey, char *issuerNickName, - int certVersion, void *pwarg) + int certVersion, PRBool pssSign, void *pwarg) { SECItem der; SECKEYPrivateKey *caPrivateKey = NULL; SECStatus rv; PLArenaPool *arena; - SECOidTag algID; + CERTCertificate *issuer; void *dummy; - if (!selfsign) { - CERTCertificate *issuer = PK11_FindCertFromNickname(issuerNickName, pwarg); + arena = cert->arena; + + if (selfsign) { + issuer = cert; + } else { + issuer = PK11_FindCertFromNickname(issuerNickName, pwarg); if ((CERTCertificate *)NULL == issuer) { SECU_PrintError(progName, "unable to find issuer with nickname %s", issuerNickName); - return SECFailure; + rv = SECFailure; + goto done; } - privKey = caPrivateKey = PK11_FindKeyByAnyCert(issuer, pwarg); - CERT_DestroyCertificate(issuer); if (caPrivateKey == NULL) { SECU_PrintError(progName, "unable to retrieve key %s", issuerNickName); - return SECFailure; + rv = SECFailure; + CERT_DestroyCertificate(issuer); + goto done; } } - arena = cert->arena; - - algID = SEC_GetSignatureAlgorithmOidTag(privKey->keyType, hashAlgTag); - if (algID == SEC_OID_UNKNOWN) { - fprintf(stderr, "Unknown key or hash type for issuer."); + if (pssSign && + (SECKEY_GetPrivateKeyType(privKey) != rsaKey && + SECKEY_GetPrivateKeyType(privKey) != rsaPssKey)) { + SECU_PrintError(progName, "unable to create RSA-PSS signature with key %s", + issuerNickName); rv = SECFailure; + if (!selfsign) { + CERT_DestroyCertificate(issuer); + } goto done; } - rv = SECOID_SetAlgorithmID(arena, &cert->signature, algID, 0); + rv = SetSignatureAlgorithm(arena, + &cert->signature, + &issuer->subjectPublicKeyInfo.algorithm, + hashAlgTag, + privKey, + pssSign); + if (!selfsign) { + CERT_DestroyCertificate(issuer); + } if (rv != SECSuccess) { - fprintf(stderr, "Could not set signature algorithm id."); goto done; } @@ -1947,7 +2065,8 @@ SignCert(CERTCertDBHandle *handle, CERTCertificate *cert, PRBool selfsign, break; default: PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; + rv = SECFailure; + goto done; } der.len = 0; @@ -1960,7 +2079,8 @@ SignCert(CERTCertDBHandle *handle, CERTCertificate *cert, PRBool selfsign, goto done; } - rv = SEC_DerSignData(arena, &cert->derCert, der.data, der.len, privKey, algID); + rv = SEC_DerSignDataWithAlgorithmID(arena, &cert->derCert, der.data, der.len, + privKey, &cert->signature); if (rv != SECSuccess) { fprintf(stderr, "Could not sign encoded certificate data.\n"); /* result allocated out of the arena, it will be freed @@ -1993,6 +2113,7 @@ CreateCert( certutilExtnList extnList, const char *extGeneric, int certVersion, + PRBool pssSign, SECItem *certDER) { void *extHandle = NULL; @@ -2053,7 +2174,7 @@ CreateCert( rv = SignCert(handle, subjectCert, selfsign, hashAlgTag, *selfsignprivkey, issuerNickName, - certVersion, pwarg); + certVersion, pssSign, pwarg); if (rv != SECSuccess) break; @@ -2306,6 +2427,7 @@ enum { cmd_Merge, cmd_UpgradeMerge, /* test only */ cmd_Rename, + cmd_BuildFlags, max_cmd }; @@ -2376,6 +2498,7 @@ enum certutilOpts { opt_GenericExtensions, opt_NewNickname, opt_Pss, + opt_PssSign, opt_Help }; @@ -2407,7 +2530,9 @@ static const secuCommandFlag commands_init[] = { /* cmd_UpgradeMerge */ 0, PR_FALSE, 0, PR_FALSE, "upgrade-merge" }, { /* cmd_Rename */ 0, PR_FALSE, 0, PR_FALSE, - "rename" } + "rename" }, + { /* cmd_BuildFlags */ 0, PR_FALSE, 0, PR_FALSE, + "build-flags" } }; #define NUM_COMMANDS ((sizeof commands_init) / (sizeof commands_init[0])) @@ -2496,6 +2621,8 @@ static const secuCommandFlag options_init[] = "new-n" }, { /* opt_Pss */ 0, PR_FALSE, 0, PR_FALSE, "pss" }, + { /* opt_PssSign */ 0, PR_FALSE, 0, PR_FALSE, + "pss-sign" }, }; #define NUM_OPTIONS ((sizeof options_init) / (sizeof options_init[0])) @@ -2592,6 +2719,10 @@ certutil_main(int argc, char **argv, PRBool initialize) exit(1); } + if (certutil.commands[cmd_BuildFlags].activated) { + PrintBuildFlags(); + } + if (certutil.options[opt_PasswordFile].arg) { pwdata.source = PW_FROMFILE; pwdata.data = certutil.options[opt_PasswordFile].arg; @@ -2621,12 +2752,10 @@ certutil_main(int argc, char **argv, PRBool initialize) progName, MIN_KEY_BITS, MAX_KEY_BITS); return 255; } -#ifndef NSS_DISABLE_ECC if (keytype == ecKey) { PR_fprintf(PR_STDERR, "%s -g: Not for ec keys.\n", progName); return 255; } -#endif /* NSS_DISABLE_ECC */ } /* -h specify token name */ @@ -2655,10 +2784,8 @@ certutil_main(int argc, char **argv, PRBool initialize) keytype = rsaKey; } else if (PL_strcmp(arg, "dsa") == 0) { keytype = dsaKey; -#ifndef NSS_DISABLE_ECC } else if (PL_strcmp(arg, "ec") == 0) { keytype = ecKey; -#endif /* NSS_DISABLE_ECC */ } else if (PL_strcmp(arg, "all") == 0) { keytype = nullKey; } else { @@ -2711,16 +2838,10 @@ certutil_main(int argc, char **argv, PRBool initialize) /* -q PQG file or curve name */ if (certutil.options[opt_PQGFile].activated) { -#ifndef NSS_DISABLE_ECC if ((keytype != dsaKey) && (keytype != ecKey)) { PR_fprintf(PR_STDERR, "%s -q: specifies a PQG file for DSA keys" " (-k dsa) or a named curve for EC keys (-k ec)\n)", progName); -#else /* } */ - if (keytype != dsaKey) { - PR_fprintf(PR_STDERR, "%s -q: PQG file is for DSA key (-k dsa).\n)", - progName); -#endif /* NSS_DISABLE_ECC */ return 255; } } @@ -3032,11 +3153,43 @@ certutil_main(int argc, char **argv, PRBool initialize) /* If creating new database, initialize the password. */ if (certutil.commands[cmd_NewDBs].activated) { - if (certutil.options[opt_EmptyPassword].activated && (PK11_NeedUserInit(slot))) - PK11_InitPin(slot, (char *)NULL, ""); - else - SECU_ChangePW2(slot, 0, 0, certutil.options[opt_PasswordFile].arg, - certutil.options[opt_NewPasswordFile].arg); + if (certutil.options[opt_EmptyPassword].activated && (PK11_NeedUserInit(slot))) { + rv = PK11_InitPin(slot, (char *)NULL, ""); + } else { + rv = SECU_ChangePW2(slot, 0, 0, certutil.options[opt_PasswordFile].arg, + certutil.options[opt_NewPasswordFile].arg); + } + if (rv != SECSuccess) { + SECU_PrintError(progName, "Could not set password for the slot"); + goto shutdown; + } + } + + /* if we are going to modify the cert database, + * make sure it's initialized */ + if (certutil.commands[cmd_ModifyCertTrust].activated || + certutil.commands[cmd_CreateAndAddCert].activated || + certutil.commands[cmd_AddCert].activated || + certutil.commands[cmd_AddEmailCert].activated) { + if (PK11_NeedLogin(slot) && PK11_NeedUserInit(slot)) { + char *password = NULL; + /* fetch the password from the command line or the file + * if no password is supplied, initialize the password to NULL */ + if (pwdata.source == PW_FROMFILE) { + password = SECU_FilePasswd(slot, PR_FALSE, pwdata.data); + } else if (pwdata.source == PW_PLAINTEXT) { + password = PL_strdup(pwdata.data); + } + rv = PK11_InitPin(slot, (char *)NULL, password ? password : ""); + if (password) { + PORT_Memset(password, 0, PL_strlen(password)); + PORT_Free(password); + } + if (rv != SECSuccess) { + SECU_PrintError(progName, "Could not set password for the slot"); + goto shutdown; + } + } } /* walk through the upgrade merge if necessary. @@ -3214,12 +3367,12 @@ certutil_main(int argc, char **argv, PRBool initialize) } /* Delete cert (-D) */ if (certutil.commands[cmd_DeleteCert].activated) { - rv = DeleteCert(certHandle, name); + rv = DeleteCert(certHandle, name, &pwdata); goto shutdown; } /* Rename cert (--rename) */ if (certutil.commands[cmd_Rename].activated) { - rv = RenameCert(certHandle, name, newName); + rv = RenameCert(certHandle, name, newName, &pwdata); goto shutdown; } /* Delete key (-F) */ @@ -3237,7 +3390,10 @@ certutil_main(int argc, char **argv, PRBool initialize) if (certutil.commands[cmd_ChangePassword].activated) { rv = SECU_ChangePW2(slot, 0, 0, certutil.options[opt_PasswordFile].arg, certutil.options[opt_NewPasswordFile].arg); - goto shutdown; + if (rv != SECSuccess) { + SECU_PrintError(progName, "Could not set password for the slot"); + goto shutdown; + } } /* Reset the a token */ if (certutil.commands[cmd_TokenReset].activated) { @@ -3362,6 +3518,25 @@ certutil_main(int argc, char **argv, PRBool initialize) } } + /* --pss-sign is to sign a certificate with RSA-PSS, even if the + * issuer's key is an RSA key. If the key is an RSA-PSS key, the + * generated signature is always RSA-PSS. */ + if (certutil.options[opt_PssSign].activated) { + if (!certutil.commands[cmd_CreateNewCert].activated && + !certutil.commands[cmd_CreateAndAddCert].activated) { + PR_fprintf(PR_STDERR, + "%s -%c: --pss-sign only works with -C or -S.\n", + progName, commandToRun); + return 255; + } + if (keytype != rsaKey) { + PR_fprintf(PR_STDERR, + "%s -%c: --pss-sign only works with RSA keys.\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 || @@ -3499,6 +3674,7 @@ certutil_main(int argc, char **argv, PRBool initialize) (certutil.options[opt_GenericExtensions].activated ? certutil.options[opt_GenericExtensions].arg : NULL), certVersion, + certutil.options[opt_PssSign].activated, &certDER); if (rv) goto shutdown; diff --git a/security/nss/cmd/certutil/keystuff.c b/security/nss/cmd/certutil/keystuff.c index 2878e3765..330284c61 100644 --- a/security/nss/cmd/certutil/keystuff.c +++ b/security/nss/cmd/certutil/keystuff.c @@ -380,7 +380,6 @@ CERTUTIL_FileForRNG(const char *noise) return SECSuccess; } -#ifndef NSS_DISABLE_ECC typedef struct curveNameTagPairStr { char *curveName; SECOidTag curveOidTag; @@ -495,9 +494,9 @@ getECParams(const char *curve) ecparams = SECITEM_AllocItem(NULL, NULL, (2 + oidData->oid.len)); - /* + /* * ecparams->data needs to contain the ASN encoding of an object ID (OID) - * representing the named curve. The actual OID is in + * representing the named curve. The actual OID is in * oidData->oid.data so we simply prepend 0x06 and OID length */ ecparams->data[0] = SEC_ASN1_OBJECT_ID; @@ -506,7 +505,6 @@ getECParams(const char *curve) return ecparams; } -#endif /* NSS_DISABLE_ECC */ SECKEYPrivateKey * CERTUTIL_GeneratePrivateKey(KeyType keytype, PK11SlotInfo *slot, int size, @@ -564,14 +562,12 @@ CERTUTIL_GeneratePrivateKey(KeyType keytype, PK11SlotInfo *slot, int size, params = (void *)&default_pqg_params; } break; -#ifndef NSS_DISABLE_ECC case ecKey: mechanism = CKM_EC_KEY_PAIR_GEN; /* For EC keys, PQGFile determines EC parameters */ if ((params = (void *)getECParams(pqgFile)) == NULL) return NULL; break; -#endif /* NSS_DISABLE_ECC */ default: return NULL; } @@ -580,8 +576,7 @@ CERTUTIL_GeneratePrivateKey(KeyType keytype, PK11SlotInfo *slot, int size, fprintf(stderr, "Generating key. This may take a few moments...\n\n"); privKey = PK11_GenerateKeyPairWithOpFlags(slot, mechanism, params, pubkeyp, - attrFlags, opFlagsOn, opFlagsOn | - opFlagsOff, + attrFlags, opFlagsOn, opFlagsOn | opFlagsOff, pwdata /*wincx*/); /* free up the params */ switch (keytype) { @@ -589,11 +584,9 @@ CERTUTIL_GeneratePrivateKey(KeyType keytype, PK11SlotInfo *slot, int size, if (dsaparams) CERTUTIL_DestroyParamsPQG(dsaparams); break; -#ifndef NSS_DISABLE_ECC case ecKey: SECITEM_FreeItem((SECItem *)params, PR_TRUE); break; -#endif default: /* nothing to free */ break; } diff --git a/security/nss/cmd/crlutil/crlgen.c b/security/nss/cmd/crlutil/crlgen.c index 1f9dc4b43..fce5e2a60 100644 --- a/security/nss/cmd/crlutil/crlgen.c +++ b/security/nss/cmd/crlutil/crlgen.c @@ -616,8 +616,7 @@ crlgen_CreateInvalidityDate(PLArenaPool *arena, const char **dataArr, goto loser; } - PORT_Memcpy(encodedItem->data, dataArr[2], (encodedItem->len = length) * - sizeof(char)); + PORT_Memcpy(encodedItem->data, dataArr[2], (encodedItem->len = length) * sizeof(char)); *extCode = SEC_OID_X509_INVALID_DATE; return encodedItem; diff --git a/security/nss/cmd/fipstest/fipstest.c b/security/nss/cmd/fipstest/fipstest.c index ab73e42a5..061f3dde0 100644 --- a/security/nss/cmd/fipstest/fipstest.c +++ b/security/nss/cmd/fipstest/fipstest.c @@ -35,13 +35,11 @@ #include "../../lib/freebl/mpi/mpi.h" #endif -#ifndef NSS_DISABLE_ECC extern SECStatus EC_DecodeParams(const SECItem *encodedParams, ECParams **ecparams); extern SECStatus EC_CopyParams(PLArenaPool *arena, ECParams *dstParams, const ECParams *srcParams); -#endif #define ENCRYPT 1 #define DECRYPT 0 @@ -2094,7 +2092,6 @@ get_next_line(FILE *req, char *key, char *val, FILE *rsp) return (c == EOF) ? -1 : ignore; } -#ifndef NSS_DISABLE_ECC typedef struct curveNameTagPairStr { char *curveName; SECOidTag curveOidTag; @@ -2958,7 +2955,6 @@ loser: } fclose(ecdsareq); } -#endif /* NSS_DISABLE_ECC */ PRBool isblankline(char *b) @@ -5926,8 +5922,7 @@ tls(char *reqfn) goto loser; } crv = NSC_DeriveKey(session, &master_mech, pms_handle, - derive_template, derive_template_count - - 1, + derive_template, derive_template_count - 1, &master_handle); if (crv != CKR_OK) { fprintf(stderr, "NSC_DeriveKey(master) failed crv=0x%x\n", @@ -6094,7 +6089,6 @@ main(int argc, char **argv) /* Signature Verification Test */ dsa_sigver_test(argv[3]); } -#ifndef NSS_DISABLE_ECC /*************/ /* ECDSA */ /*************/ @@ -6113,7 +6107,6 @@ main(int argc, char **argv) /* Signature Verification Test */ ecdsa_sigver_test(argv[3]); } -#endif /* NSS_DISABLE_ECC */ /*************/ /* RNG */ /*************/ diff --git a/security/nss/cmd/fipstest/runtest.sh b/security/nss/cmd/fipstest/runtest.sh index 99cefed77..5f8e66a08 100644 --- a/security/nss/cmd/fipstest/runtest.sh +++ b/security/nss/cmd/fipstest/runtest.sh @@ -7,9 +7,6 @@ TESTDIR=${1-.} COMMAND=${2-run} TESTS="aes aesgcm dsa ecdsa hmac tls rng rsa sha tdea" -if [ ${NSS_ENABLE_ECC}x = 1x ]; then - TESTS=${TESTS} ecdsa -fi for i in $TESTS do echo "********************Running $i tests" diff --git a/security/nss/cmd/lib/secutil.c b/security/nss/cmd/lib/secutil.c index cb4752df9..2b33f8963 100644 --- a/security/nss/cmd/lib/secutil.c +++ b/security/nss/cmd/lib/secutil.c @@ -54,6 +54,10 @@ static char consoleName[] = { static PRBool utf8DisplayEnabled = PR_FALSE; +/* The minimum password/pin length (in Unicode characters) in FIPS mode, + * defined in lib/softoken/pkcs11i.h. */ +#define FIPS_MIN_PIN 7 + void SECU_EnableUtf8Display(PRBool enable) { @@ -236,7 +240,8 @@ SECU_GetModulePassword(PK11SlotInfo *slot, PRBool retry, void *arg) sprintf(prompt, "Press Enter, then enter PIN for \"%s\" on external device.\n", PK11_GetTokenName(slot)); - (void)SECU_GetPasswordString(NULL, prompt); + char *pw = SECU_GetPasswordString(NULL, prompt); + PORT_Free(pw); /* Fall Through */ case PW_PLAINTEXT: return PL_strdup(pwdata->data); @@ -276,10 +281,25 @@ secu_InitSlotPassword(PK11SlotInfo *slot, PRBool retry, void *arg) } /* we have no password, so initialize database with one */ - PR_fprintf(PR_STDERR, - "Enter a password which will be used to encrypt your keys.\n" - "The password should be at least 8 characters long,\n" - "and should contain at least one non-alphabetic character.\n\n"); + if (PK11_IsFIPS()) { + PR_fprintf(PR_STDERR, + "Enter a password which will be used to encrypt your keys.\n" + "The password should be at least %d characters long,\n" + "and should consist of at least three character classes.\n" + "The available character classes are: digits (0-9), ASCII\n" + "lowercase letters, ASCII uppercase letters, ASCII\n" + "non-alphanumeric characters, and non-ASCII characters.\n\n" + "If an ASCII uppercase letter appears at the beginning of\n" + "the password, it is not counted toward its character class.\n" + "Similarly, if a digit appears at the end of the password,\n" + "it is not counted toward its character class.\n\n", + FIPS_MIN_PIN); + } else { + PR_fprintf(PR_STDERR, + "Enter a password which will be used to encrypt your keys.\n" + "The password should be at least 8 characters long,\n" + "and should contain at least one non-alphabetic character.\n\n"); + } output = fopen(consoleName, "w"); if (output == NULL) { @@ -465,48 +485,6 @@ SECU_ConfigDirectory(const char *base) return buf; } -/*Turn off SSL for now */ -/* This gets called by SSL when server wants our cert & key */ -int -SECU_GetClientAuthData(void *arg, PRFileDesc *fd, - struct CERTDistNamesStr *caNames, - struct CERTCertificateStr **pRetCert, - struct SECKEYPrivateKeyStr **pRetKey) -{ - SECKEYPrivateKey *key; - CERTCertificate *cert; - int errsave; - - if (arg == NULL) { - fprintf(stderr, "no key/cert name specified for client auth\n"); - return -1; - } - cert = PK11_FindCertFromNickname(arg, NULL); - errsave = PORT_GetError(); - if (!cert) { - if (errsave == SEC_ERROR_BAD_PASSWORD) - fprintf(stderr, "Bad password\n"); - else if (errsave > 0) - fprintf(stderr, "Unable to read cert (error %d)\n", errsave); - else if (errsave == SEC_ERROR_BAD_DATABASE) - fprintf(stderr, "Unable to get cert from database (%d)\n", errsave); - else - fprintf(stderr, "SECKEY_FindKeyByName: internal error %d\n", errsave); - return -1; - } - - key = PK11_FindKeyByAnyCert(arg, NULL); - if (!key) { - fprintf(stderr, "Unable to get key (%d)\n", PORT_GetError()); - return -1; - } - - *pRetCert = cert; - *pRetKey = key; - - return 0; -} - SECStatus SECU_ReadDERFromFile(SECItem *der, PRFileDesc *inFile, PRBool ascii, PRBool warnOnPrivateKeyInAsciiFile) @@ -991,7 +969,7 @@ secu_PrintUniversalString(FILE *out, const SECItem *i, const char *m, int level) for (s = my.data, d = tmp.data; len > 0; len--) { PRUint32 bmpChar = (s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3]; s += 4; - if (!isprint(bmpChar)) + if (!isprint(bmpChar & 0xFF)) goto loser; *d++ = (unsigned char)bmpChar; } @@ -1215,7 +1193,7 @@ secu_PrintRSAPSSParams(FILE *out, SECItem *value, char *m, int level) SECU_Indent(out, level + 1); fprintf(out, "Salt length: default, %i (0x%2X)\n", 20, 20); } else { - SECU_PrintInteger(out, ¶m.saltLength, "Salt Length", level + 1); + SECU_PrintInteger(out, ¶m.saltLength, "Salt length", level + 1); } } else { SECU_Indent(out, level + 1); @@ -1335,15 +1313,12 @@ SECU_PrintAlgorithmID(FILE *out, SECAlgorithmID *a, char *m, int level) return; } - if (algtag == SEC_OID_PKCS1_RSA_PSS_SIGNATURE) { - secu_PrintRSAPSSParams(out, &a->parameters, "Parameters", level + 1); - return; - } - if (a->parameters.len == 0 || (a->parameters.len == 2 && PORT_Memcmp(a->parameters.data, "\005\000", 2) == 0)) { /* No arguments or NULL argument */ + } else if (algtag == SEC_OID_PKCS1_RSA_PSS_SIGNATURE) { + secu_PrintRSAPSSParams(out, &a->parameters, "Parameters", level + 1); } else { /* Print args to algorithm */ SECU_PrintAsHex(out, &a->parameters, "Args", level + 1); @@ -1390,7 +1365,6 @@ secu_PrintAttribute(FILE *out, SEC_PKCS7Attribute *attr, char *m, int level) } } -#ifndef NSS_DISABLE_ECC static void secu_PrintECPublicKey(FILE *out, SECKEYPublicKey *pk, char *m, int level) { @@ -1409,7 +1383,6 @@ secu_PrintECPublicKey(FILE *out, SECKEYPublicKey *pk, char *m, int level) SECU_PrintObjectID(out, &curveOID, "Curve", level + 1); } } -#endif /* NSS_DISABLE_ECC */ void SECU_PrintRSAPublicKey(FILE *out, SECKEYPublicKey *pk, char *m, int level) @@ -1457,11 +1430,9 @@ secu_PrintSubjectPublicKeyInfo(FILE *out, PLArenaPool *arena, SECU_PrintDSAPublicKey(out, pk, "DSA Public Key", level + 1); break; -#ifndef NSS_DISABLE_ECC case ecKey: secu_PrintECPublicKey(out, pk, "EC Public Key", level + 1); break; -#endif case dhKey: case fortezzaKey: @@ -3614,44 +3585,6 @@ loser: return rv; } -#if 0 - -/* we need access to the private function cert_FindExtension for this code to work */ - -CERTAuthKeyID * -SECU_FindCRLAuthKeyIDExten (PLArenaPool *arena, CERTSignedCrl *scrl) -{ - SECItem encodedExtenValue; - SECStatus rv; - CERTAuthKeyID *ret; - CERTCrl* crl; - - if (!scrl) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return NULL; - } - - crl = &scrl->crl; - - encodedExtenValue.data = NULL; - encodedExtenValue.len = 0; - - rv = cert_FindExtension(crl->extensions, SEC_OID_X509_AUTH_KEY_ID, - &encodedExtenValue); - if ( rv != SECSuccess ) { - return (NULL); - } - - ret = CERT_DecodeAuthKeyID (arena, &encodedExtenValue); - - PORT_Free(encodedExtenValue.data); - encodedExtenValue.data = NULL; - - return(ret); -} - -#endif - /* * Find the issuer of a Crl. Use the authorityKeyID if it exists. */ @@ -3725,7 +3658,7 @@ SECU_FindCertByNicknameOrFilename(CERTCertDBHandle *handle, void *pwarg) { CERTCertificate *the_cert; - the_cert = CERT_FindCertByNicknameOrEmailAddr(handle, name); + the_cert = CERT_FindCertByNicknameOrEmailAddrCX(handle, name, pwarg); if (the_cert) { return the_cert; } diff --git a/security/nss/cmd/libpkix/pkix/util/test_list2.c b/security/nss/cmd/libpkix/pkix/util/test_list2.c index 7e4114e52..b802ff0e6 100644 --- a/security/nss/cmd/libpkix/pkix/util/test_list2.c +++ b/security/nss/cmd/libpkix/pkix/util/test_list2.c @@ -78,16 +78,14 @@ test_list2(int argc, char *argv[]) for (i = 0; i < size; i++) for (j = 9; j > i; j--) { PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetItem(list, j, &obj, plContext)); - PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetItem(list, j - - 1, + PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetItem(list, j - 1, &obj2, plContext)); PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Compare(obj, obj2, &cmpResult, plContext)); if (cmpResult < 0) { /* Exchange the items */ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_SetItem(list, j, obj2, plContext)); - PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_SetItem(list, j - - 1, + PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_SetItem(list, j - 1, obj, plContext)); } /* DecRef objects */ diff --git a/security/nss/cmd/listsuites/listsuites.c b/security/nss/cmd/listsuites/listsuites.c index 458130e5e..8eb2c3553 100644 --- a/security/nss/cmd/listsuites/listsuites.c +++ b/security/nss/cmd/listsuites/listsuites.c @@ -10,7 +10,9 @@ #include <errno.h> #include <stdio.h> +#include "nss.h" #include "secport.h" +#include "secutil.h" #include "ssl.h" int @@ -19,6 +21,43 @@ main(int argc, char **argv) const PRUint16 *cipherSuites = SSL_ImplementedCiphers; int i; int errCount = 0; + SECStatus rv; + PRErrorCode err; + char *certDir = NULL; + + /* load policy from $SSL_DIR/pkcs11.txt, for testing */ + certDir = SECU_DefaultSSLDir(); + if (certDir) { + rv = NSS_Init(certDir); + } else { + rv = NSS_NoDB_Init(NULL); + } + if (rv != SECSuccess) { + err = PR_GetError(); + ++errCount; + fprintf(stderr, "NSS_Init failed: %s\n", PORT_ErrorToString(err)); + goto out; + } + + /* apply policy */ + rv = NSS_SetAlgorithmPolicy(SEC_OID_APPLY_SSL_POLICY, NSS_USE_POLICY_IN_SSL, 0); + if (rv != SECSuccess) { + err = PR_GetError(); + ++errCount; + fprintf(stderr, "NSS_SetAlgorithmPolicy failed: %s\n", + PORT_ErrorToString(err)); + goto out; + } + + /* update the default cipher suites according to the policy */ + rv = SSL_OptionSetDefault(SSL_SECURITY, PR_TRUE); + if (rv != SECSuccess) { + err = PR_GetError(); + ++errCount; + fprintf(stderr, "SSL_OptionSetDefault failed: %s\n", + PORT_ErrorToString(err)); + goto out; + } fputs("This version of libSSL supports these cipher suites:\n\n", stdout); @@ -58,5 +97,14 @@ main(int argc, char **argv) info.isFIPS ? "FIPS" : "", info.nonStandard ? "nonStandard" : ""); } + +out: + rv = NSS_Shutdown(); + if (rv != SECSuccess) { + err = PR_GetError(); + ++errCount; + fprintf(stderr, "NSS_Shutdown failed: %s\n", PORT_ErrorToString(err)); + } + return errCount; } diff --git a/security/nss/cmd/manifest.mn b/security/nss/cmd/manifest.mn index 153384ce1..567c6bb9d 100644 --- a/security/nss/cmd/manifest.mn +++ b/security/nss/cmd/manifest.mn @@ -36,7 +36,6 @@ NSS_SRCDIRS = \ addbuiltin \ atob \ btoa \ - certcgi \ certutil \ chktest \ crlutil \ @@ -63,6 +62,7 @@ NSS_SRCDIRS = \ pp \ pwdecrypt \ rsaperf \ + rsapoptst \ sdrtest \ selfserv \ signtool \ diff --git a/security/nss/cmd/modutil/error.h b/security/nss/cmd/modutil/error.h index b328afebc..d9f06592f 100644 --- a/security/nss/cmd/modutil/error.h +++ b/security/nss/cmd/modutil/error.h @@ -57,6 +57,7 @@ typedef enum { UNSPECIFIED_ERR, NOCERTDB_MISUSE_ERR, NSS_INITIALIZE_FAILED_ERR, + INITPW_FAILED_ERR, LAST_ERR /* must be last */ } Error; @@ -109,8 +110,9 @@ static char *errStrings[] = { "ERROR: Failed to change default.\n", "ERROR: Unable to read from standard input.\n", "ERROR: Unknown error occurred.\n", - "ERROR: -nocertdb option can only be used with the -jar command.\n" - "ERROR: NSS_Initialize() failed.\n" + "ERROR: -nocertdb option can only be used with the -jar command.\n", + "ERROR: NSS_Initialize() failed.\n", + "ERROR: Unable to set initial password on the database.\n" }; typedef enum { diff --git a/security/nss/cmd/modutil/install-ds.c b/security/nss/cmd/modutil/install-ds.c index c8fef7897..030568762 100644 --- a/security/nss/cmd/modutil/install-ds.c +++ b/security/nss/cmd/modutil/install-ds.c @@ -975,8 +975,7 @@ Pk11Install_Platform_Print(Pk11Install_Platform* _this, int pad) printf("Doesn't use equiv\n"); } PAD(pad); - printf("Module File: %s\n", _this->moduleFile ? _this->moduleFile - : "<NULL>"); + printf("Module File: %s\n", _this->moduleFile ? _this->moduleFile : "<NULL>"); PAD(pad); printf("mechFlags: %lx\n", _this->mechFlags); PAD(pad); diff --git a/security/nss/cmd/modutil/modutil.c b/security/nss/cmd/modutil/modutil.c index 02972f7b4..c1b44be53 100644 --- a/security/nss/cmd/modutil/modutil.c +++ b/security/nss/cmd/modutil/modutil.c @@ -865,7 +865,7 @@ main(int argc, char* argv[]) errcode = ChangePW(tokenName, pwFile, newpwFile); break; case CREATE_COMMAND: - /* The work was already done in init_crypto() */ + errcode = InitPW(); break; case DEFAULT_COMMAND: errcode = SetDefaultModule(moduleName, slotName, mechanisms); diff --git a/security/nss/cmd/modutil/modutil.h b/security/nss/cmd/modutil/modutil.h index 127d0d0da..04aa908c8 100644 --- a/security/nss/cmd/modutil/modutil.h +++ b/security/nss/cmd/modutil/modutil.h @@ -29,6 +29,7 @@ Error AddModule(char *moduleName, char *libFile, char *ciphers, Error DeleteModule(char *moduleName); Error ListModule(char *moduleName); Error ListModules(); +Error InitPW(void); Error ChangePW(char *tokenName, char *pwFile, char *newpwFile); Error EnableModule(char *moduleName, char *slotName, PRBool enable); Error RawAddModule(char *dbmodulespec, char *modulespec); diff --git a/security/nss/cmd/modutil/pk11.c b/security/nss/cmd/modutil/pk11.c index 834469af1..1efc1895c 100644 --- a/security/nss/cmd/modutil/pk11.c +++ b/security/nss/cmd/modutil/pk11.c @@ -670,6 +670,39 @@ loser: /************************************************************************ * + * I n i t P W + */ +Error +InitPW(void) +{ + PK11SlotInfo *slot; + Error ret = UNSPECIFIED_ERR; + + slot = PK11_GetInternalKeySlot(); + if (!slot) { + PR_fprintf(PR_STDERR, errStrings[NO_SUCH_TOKEN_ERR], "internal"); + return NO_SUCH_TOKEN_ERR; + } + + /* Set the initial password to empty */ + if (PK11_NeedUserInit(slot)) { + if (PK11_InitPin(slot, NULL, "") != SECSuccess) { + PR_fprintf(PR_STDERR, errStrings[INITPW_FAILED_ERR]); + ret = INITPW_FAILED_ERR; + goto loser; + } + } + + ret = SUCCESS; + +loser: + PK11_FreeSlot(slot); + + return ret; +} + +/************************************************************************ + * * C h a n g e P W */ Error @@ -695,7 +728,7 @@ ChangePW(char *tokenName, char *pwFile, char *newpwFile) ret = BAD_PW_ERR; goto loser; } - } else { + } else if (PK11_NeedLogin(slot)) { for (matching = PR_FALSE; !matching;) { oldpw = SECU_GetPasswordString(NULL, "Enter old password: "); if (PK11_CheckUserPassword(slot, oldpw) == SECSuccess) { diff --git a/security/nss/cmd/multinit/multinit.c b/security/nss/cmd/multinit/multinit.c index a57c4819f..874263e56 100644 --- a/security/nss/cmd/multinit/multinit.c +++ b/security/nss/cmd/multinit/multinit.c @@ -502,8 +502,7 @@ do_list_certs(const char *progName, int log) SECU_PrintCertNickname(node, stderr); if (log) { - fprintf(stderr, "* Slot=%s*\n", cert->slot ? PK11_GetTokenName(cert->slot) - : "none"); + fprintf(stderr, "* Slot=%s*\n", cert->slot ? PK11_GetTokenName(cert->slot) : "none"); fprintf(stderr, "* Nickname=%s*\n", cert->nickname); fprintf(stderr, "* Subject=<%s>*\n", cert->subjectName); fprintf(stderr, "* Issuer=<%s>*\n", cert->issuerName); diff --git a/security/nss/cmd/pk11mode/pk11mode.c b/security/nss/cmd/pk11mode/pk11mode.c index 2f1fa374e..99891096c 100644 --- a/security/nss/cmd/pk11mode/pk11mode.c +++ b/security/nss/cmd/pk11mode/pk11mode.c @@ -2169,36 +2169,22 @@ PKM_Mechanism(CK_FUNCTION_LIST_PTR pFunctionList, PKM_LogIt(" ulMinKeySize = %lu\n", minfo.ulMinKeySize); PKM_LogIt(" ulMaxKeySize = %lu\n", minfo.ulMaxKeySize); PKM_LogIt(" flags = 0x%08x\n", minfo.flags); - PKM_LogIt(" -> HW = %s\n", minfo.flags & CKF_HW ? "TRUE" - : "FALSE"); - PKM_LogIt(" -> ENCRYPT = %s\n", minfo.flags & CKF_ENCRYPT ? "TRUE" - : "FALSE"); - PKM_LogIt(" -> DECRYPT = %s\n", minfo.flags & CKF_DECRYPT ? "TRUE" - : "FALSE"); - PKM_LogIt(" -> DIGEST = %s\n", minfo.flags & CKF_DIGEST ? "TRUE" - : "FALSE"); - PKM_LogIt(" -> SIGN = %s\n", minfo.flags & CKF_SIGN ? "TRUE" - : "FALSE"); - PKM_LogIt(" -> SIGN_RECOVER = %s\n", minfo.flags & - CKF_SIGN_RECOVER - ? "TRUE" - : "FALSE"); - PKM_LogIt(" -> VERIFY = %s\n", minfo.flags & CKF_VERIFY ? "TRUE" - : "FALSE"); + PKM_LogIt(" -> HW = %s\n", minfo.flags & CKF_HW ? "TRUE" : "FALSE"); + PKM_LogIt(" -> ENCRYPT = %s\n", minfo.flags & CKF_ENCRYPT ? "TRUE" : "FALSE"); + PKM_LogIt(" -> DECRYPT = %s\n", minfo.flags & CKF_DECRYPT ? "TRUE" : "FALSE"); + PKM_LogIt(" -> DIGEST = %s\n", minfo.flags & CKF_DIGEST ? "TRUE" : "FALSE"); + PKM_LogIt(" -> SIGN = %s\n", minfo.flags & CKF_SIGN ? "TRUE" : "FALSE"); + PKM_LogIt(" -> SIGN_RECOVER = %s\n", minfo.flags & CKF_SIGN_RECOVER ? "TRUE" : "FALSE"); + PKM_LogIt(" -> VERIFY = %s\n", minfo.flags & CKF_VERIFY ? "TRUE" : "FALSE"); PKM_LogIt(" -> VERIFY_RECOVER = %s\n", minfo.flags & CKF_VERIFY_RECOVER ? "TRUE" : "FALSE"); - PKM_LogIt(" -> GENERATE = %s\n", minfo.flags & CKF_GENERATE ? "TRUE" - : "FALSE"); + PKM_LogIt(" -> GENERATE = %s\n", minfo.flags & CKF_GENERATE ? "TRUE" : "FALSE"); PKM_LogIt(" -> GENERATE_KEY_PAIR = %s\n", minfo.flags & CKF_GENERATE_KEY_PAIR ? "TRUE" : "FALSE"); - PKM_LogIt(" -> WRAP = %s\n", minfo.flags & CKF_WRAP ? "TRUE" - : "FALSE"); - PKM_LogIt(" -> UNWRAP = %s\n", minfo.flags & CKF_UNWRAP ? "TRUE" - : "FALSE"); - PKM_LogIt(" -> DERIVE = %s\n", minfo.flags & CKF_DERIVE ? "TRUE" - : "FALSE"); - PKM_LogIt(" -> EXTENSION = %s\n", minfo.flags & CKF_EXTENSION ? "TRUE" - : "FALSE"); + PKM_LogIt(" -> WRAP = %s\n", minfo.flags & CKF_WRAP ? "TRUE" : "FALSE"); + PKM_LogIt(" -> UNWRAP = %s\n", minfo.flags & CKF_UNWRAP ? "TRUE" : "FALSE"); + PKM_LogIt(" -> DERIVE = %s\n", minfo.flags & CKF_DERIVE ? "TRUE" : "FALSE"); + PKM_LogIt(" -> EXTENSION = %s\n", minfo.flags & CKF_EXTENSION ? "TRUE" : "FALSE"); PKM_LogIt("\n"); } @@ -3604,24 +3590,12 @@ PKM_FindAllObjects(CK_FUNCTION_LIST_PTR pFunctionList, PKM_LogIt(" state = %lu\n", sinfo.state); PKM_LogIt(" flags = 0x%08x\n", sinfo.flags); #ifdef CKF_EXCLUSIVE_SESSION - PKM_LogIt(" -> EXCLUSIVE SESSION = %s\n", sinfo.flags & - CKF_EXCLUSIVE_SESSION - ? "TRUE" - : "FALSE"); + PKM_LogIt(" -> EXCLUSIVE SESSION = %s\n", sinfo.flags & CKF_EXCLUSIVE_SESSION ? "TRUE" : "FALSE"); #endif /* CKF_EXCLUSIVE_SESSION */ - PKM_LogIt(" -> RW SESSION = %s\n", sinfo.flags & - CKF_RW_SESSION - ? "TRUE" - : "FALSE"); - PKM_LogIt(" -> SERIAL SESSION = %s\n", sinfo.flags & - CKF_SERIAL_SESSION - ? "TRUE" - : "FALSE"); + PKM_LogIt(" -> RW SESSION = %s\n", sinfo.flags & CKF_RW_SESSION ? "TRUE" : "FALSE"); + PKM_LogIt(" -> SERIAL SESSION = %s\n", sinfo.flags & CKF_SERIAL_SESSION ? "TRUE" : "FALSE"); #ifdef CKF_INSERTION_CALLBACK - PKM_LogIt(" -> INSERTION CALLBACK = %s\n", sinfo.flags & - CKF_INSERTION_CALLBACK - ? "TRUE" - : "FALSE"); + PKM_LogIt(" -> INSERTION CALLBACK = %s\n", sinfo.flags & CKF_INSERTION_CALLBACK ? "TRUE" : "FALSE"); #endif /* CKF_INSERTION_CALLBACK */ PKM_LogIt(" ulDeviceError = %lu\n", sinfo.ulDeviceError); PKM_LogIt("\n"); diff --git a/security/nss/cmd/pk12util/pk12util.c b/security/nss/cmd/pk12util/pk12util.c index 0ac1ba00e..70454a0d8 100644 --- a/security/nss/cmd/pk12util/pk12util.c +++ b/security/nss/cmd/pk12util/pk12util.c @@ -23,6 +23,7 @@ static char *progName; PRBool pk12_debugging = PR_FALSE; PRBool dumpRawFile; +static PRBool pk12uForceUnicode; PRIntn pk12uErrno = 0; @@ -357,6 +358,7 @@ p12U_ReadPKCS12File(SECItem *uniPwp, char *in_file, PK11SlotInfo *slot, SECItem p12file = { 0 }; SECStatus rv = SECFailure; PRBool swapUnicode = PR_FALSE; + PRBool forceUnicode = pk12uForceUnicode; PRBool trypw; int error; @@ -424,6 +426,18 @@ p12U_ReadPKCS12File(SECItem *uniPwp, char *in_file, PK11SlotInfo *slot, SEC_PKCS12DecoderFinish(p12dcx); uniPwp->len = 0; trypw = PR_TRUE; + } else if (forceUnicode == pk12uForceUnicode) { + /* try again with a different password encoding */ + forceUnicode = !pk12uForceUnicode; + rv = NSS_OptionSet(__NSS_PKCS12_DECODE_FORCE_UNICODE, + forceUnicode); + if (rv != SECSuccess) { + SECU_PrintError(progName, "PKCS12 decoding failed to set option"); + pk12uErrno = PK12UERR_DECODEVERIFY; + break; + } + SEC_PKCS12DecoderFinish(p12dcx); + trypw = PR_TRUE; } else { SECU_PrintError(progName, "PKCS12 decode not verified"); pk12uErrno = PK12UERR_DECODEVERIFY; @@ -431,6 +445,15 @@ p12U_ReadPKCS12File(SECItem *uniPwp, char *in_file, PK11SlotInfo *slot, } } } while (trypw == PR_TRUE); + + /* revert the option setting */ + if (forceUnicode != pk12uForceUnicode) { + rv = NSS_OptionSet(__NSS_PKCS12_DECODE_FORCE_UNICODE, pk12uForceUnicode); + if (rv != SECSuccess) { + SECU_PrintError(progName, "PKCS12 decoding failed to set option"); + pk12uErrno = PK12UERR_DECODEVERIFY; + } + } /* rv has been set at this point */ done: @@ -470,6 +493,8 @@ P12U_ImportPKCS12Object(char *in_file, PK11SlotInfo *slot, { SEC_PKCS12DecoderContext *p12dcx = NULL; SECItem uniPwitem = { 0 }; + PRBool forceUnicode = pk12uForceUnicode; + PRBool trypw; SECStatus rv = SECFailure; rv = P12U_InitSlot(slot, slotPw); @@ -480,31 +505,62 @@ P12U_ImportPKCS12Object(char *in_file, PK11SlotInfo *slot, return rv; } - rv = SECFailure; - p12dcx = p12U_ReadPKCS12File(&uniPwitem, in_file, slot, slotPw, p12FilePw); + do { + trypw = PR_FALSE; /* normally we do this once */ + rv = SECFailure; + p12dcx = p12U_ReadPKCS12File(&uniPwitem, in_file, slot, slotPw, p12FilePw); - if (p12dcx == NULL) { - goto loser; - } + if (p12dcx == NULL) { + goto loser; + } - /* make sure the bags are okey dokey -- nicknames correct, etc. */ - rv = SEC_PKCS12DecoderValidateBags(p12dcx, P12U_NicknameCollisionCallback); - if (rv != SECSuccess) { - if (PORT_GetError() == SEC_ERROR_PKCS12_DUPLICATE_DATA) { - pk12uErrno = PK12UERR_CERTALREADYEXISTS; - } else { - pk12uErrno = PK12UERR_DECODEVALIBAGS; + /* make sure the bags are okey dokey -- nicknames correct, etc. */ + rv = SEC_PKCS12DecoderValidateBags(p12dcx, P12U_NicknameCollisionCallback); + if (rv != SECSuccess) { + if (PORT_GetError() == SEC_ERROR_PKCS12_DUPLICATE_DATA) { + pk12uErrno = PK12UERR_CERTALREADYEXISTS; + } else { + pk12uErrno = PK12UERR_DECODEVALIBAGS; + } + SECU_PrintError(progName, "PKCS12 decode validate bags failed"); + goto loser; } - SECU_PrintError(progName, "PKCS12 decode validate bags failed"); - goto loser; - } - /* stuff 'em in */ - rv = SEC_PKCS12DecoderImportBags(p12dcx); - if (rv != SECSuccess) { - SECU_PrintError(progName, "PKCS12 decode import bags failed"); - pk12uErrno = PK12UERR_DECODEIMPTBAGS; - goto loser; + /* stuff 'em in */ + if (forceUnicode != pk12uForceUnicode) { + rv = NSS_OptionSet(__NSS_PKCS12_DECODE_FORCE_UNICODE, + forceUnicode); + if (rv != SECSuccess) { + SECU_PrintError(progName, "PKCS12 decode set option failed"); + pk12uErrno = PK12UERR_DECODEIMPTBAGS; + goto loser; + } + } + rv = SEC_PKCS12DecoderImportBags(p12dcx); + if (rv != SECSuccess) { + if (PR_GetError() == SEC_ERROR_PKCS12_UNABLE_TO_IMPORT_KEY && + forceUnicode == pk12uForceUnicode) { + /* try again with a different password encoding */ + forceUnicode = !pk12uForceUnicode; + SEC_PKCS12DecoderFinish(p12dcx); + SECITEM_ZfreeItem(&uniPwitem, PR_FALSE); + trypw = PR_TRUE; + } else { + SECU_PrintError(progName, "PKCS12 decode import bags failed"); + pk12uErrno = PK12UERR_DECODEIMPTBAGS; + goto loser; + } + } + } while (trypw); + + /* revert the option setting */ + if (forceUnicode != pk12uForceUnicode) { + rv = NSS_OptionSet(__NSS_PKCS12_DECODE_FORCE_UNICODE, pk12uForceUnicode); + if (rv != SECSuccess) { + SECU_PrintError(progName, "PKCS12 decode set option failed"); + pk12uErrno = PK12UERR_DECODEIMPTBAGS; + goto loser; + } } fprintf(stdout, "%s: PKCS12 IMPORT SUCCESSFUL\n", progName); @@ -947,6 +1003,7 @@ main(int argc, char **argv) int keyLen = 0; int certKeyLen = 0; secuCommand pk12util; + PRInt32 forceUnicode; #ifdef _CRTDBG_MAP_ALLOC _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); @@ -978,6 +1035,14 @@ main(int argc, char **argv) Usage(progName); } + 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); + } + pk12uForceUnicode = forceUnicode; + slotname = SECU_GetOptionArg(&pk12util, opt_TokenName); import_file = (pk12util.options[opt_List].activated) ? SECU_GetOptionArg(&pk12util, opt_List) diff --git a/security/nss/cmd/pp/pp.c b/security/nss/cmd/pp/pp.c index 9f33d10a4..d6e276834 100644 --- a/security/nss/cmd/pp/pp.c +++ b/security/nss/cmd/pp/pp.c @@ -84,6 +84,8 @@ main(int argc, char **argv) if (!inFile) { fprintf(stderr, "%s: unable to open \"%s\" for reading\n", progName, optstate->value); + PORT_Free(typeTag); + PL_DestroyOptState(optstate); return -1; } break; @@ -93,6 +95,8 @@ main(int argc, char **argv) if (!outFile) { fprintf(stderr, "%s: unable to open \"%s\" for writing\n", progName, optstate->value); + PORT_Free(typeTag); + PL_DestroyOptState(optstate); return -1; } break; diff --git a/security/nss/cmd/rsaperf/rsaperf.c b/security/nss/cmd/rsaperf/rsaperf.c index 556030f6a..2bb23856e 100644 --- a/security/nss/cmd/rsaperf/rsaperf.c +++ b/security/nss/cmd/rsaperf/rsaperf.c @@ -671,8 +671,7 @@ main(int argc, char **argv) printf("%ld iterations in %s\n", iters, TimingGenerateString(timeCtx)); - printf("%.2f operations/s .\n", ((double)(iters) * (double)1000000.0) / - (double)timeCtx->interval); + printf("%.2f operations/s .\n", ((double)(iters) * (double)1000000.0) / (double)timeCtx->interval); TimingDivide(timeCtx, iters); printf("one operation every %s\n", TimingGenerateString(timeCtx)); diff --git a/security/nss/cmd/rsapoptst/rsapoptst.c b/security/nss/cmd/rsapoptst/rsapoptst.c index 81ddcd6c4..d9468e6d6 100644 --- a/security/nss/cmd/rsapoptst/rsapoptst.c +++ b/security/nss/cmd/rsapoptst/rsapoptst.c @@ -23,7 +23,7 @@ static const struct test_args test_array[] = { { "d_n_q", 0x02, "private exponent, modulus, prime2" }, { "d_p_q", 0x04, "private exponent, prime1, prime2" }, { "e_d_q", 0x08, "public exponent, private exponent, prime2" }, - { "e_d_n", 0x10, "public exponent, private exponent, moduls" } + { "e_d_n", 0x10, "public exponent, private exponent, modulus" } }; static const int test_array_size = (sizeof(test_array) / sizeof(struct test_args)); @@ -58,6 +58,7 @@ const static CK_ATTRIBUTE rsaTemplate[] = { { CKA_TOKEN, NULL, 0 }, { CKA_SENSITIVE, NULL, 0 }, { CKA_PRIVATE, NULL, 0 }, + { CKA_ID, NULL, 0 }, { CKA_MODULUS, NULL, 0 }, { CKA_PUBLIC_EXPONENT, NULL, 0 }, { CKA_PRIVATE_EXPONENT, NULL, 0 }, @@ -123,46 +124,77 @@ fail: #define ATTR_STRING(x) getNameFromAttribute(x) +static void +dumphex(FILE *file, const unsigned char *cpval, int start, int end) +{ + int i; + for (i = start; i < end; i++) { + if ((i % 16) == 0) + fprintf(file, "\n "); + fprintf(file, " %02x", cpval[i]); + } + return; +} + void -dumpTemplate(CK_ATTRIBUTE *template, int start, int end) +dumpTemplate(FILE *file, const CK_ATTRIBUTE *template, int start, int end) { - int i, j; - for (i = 0; i < end; i++) { + int i; + for (i = start; i < end; i++) { unsigned char cval; CK_ULONG ulval; - unsigned char *cpval; + const unsigned char *cpval; - fprintf(stderr, "%s:", ATTR_STRING(template[i].type)); + fprintf(file, "%s:", ATTR_STRING(template[i].type)); switch (template[i].ulValueLen) { case 1: cval = *(unsigned char *)template[i].pValue; switch (cval) { case 0: - fprintf(stderr, " false"); + fprintf(file, " false"); break; case 1: - fprintf(stderr, " true"); + fprintf(file, " true"); break; default: - fprintf(stderr, " %d (=0x%02x,'%c')", cval, cval, cval); + fprintf(file, " %d (=0x%02x,'%c')", cval, cval, cval); break; } break; case sizeof(CK_ULONG): ulval = *(CK_ULONG *)template[i].pValue; - fprintf(stderr, " %ld (=0x%04lx)", ulval, ulval); + fprintf(file, " %ld (=0x%04lx)", ulval, ulval); break; default: - cpval = (unsigned char *)template[i].pValue; - for (j = 0; j < template[i].ulValueLen; j++) { - if ((j % 16) == 0) - fprintf(stderr, "\n "); - fprintf(stderr, " %02x", cpval[j]); - } + cpval = (const unsigned char *)template[i].pValue; + dumphex(file, cpval, 0, template[i].ulValueLen); break; } - fprintf(stderr, "\n"); + fprintf(file, "\n"); + } +} + +void +dumpItem(FILE *file, const SECItem *item) +{ + const unsigned char *cpval; + + if (item == NULL) { + fprintf(file, " pNULL "); + return; + } + if (item->data == NULL) { + fprintf(file, " NULL "); + return; } + if (item->len == 0) { + fprintf(file, " Empty "); + return; + } + cpval = item->data; + dumphex(file, cpval, 0, item->len); + fprintf(file, " "); + return; } PRBool @@ -184,13 +216,16 @@ rsaKeysAreEqual(PK11ObjectType srcType, void *src, printf("Could read source key\n"); return PR_FALSE; } - readKey(destType, dest, destTemplate, 0, RSA_ATTRIBUTES); + rv = readKey(destType, dest, destTemplate, 0, RSA_ATTRIBUTES); if (rv != SECSuccess) { printf("Could read dest key\n"); return PR_FALSE; } for (i = 0; i < RSA_ATTRIBUTES; i++) { + if (srcTemplate[i].type == CKA_ID) { + continue; /* we purposefully make the CKA_ID different */ + } if (srcTemplate[i].ulValueLen != destTemplate[i].ulValueLen) { printf("key->%s not equal src_len = %ld, dest_len=%ld\n", ATTR_STRING(srcTemplate[i].type), @@ -204,18 +239,22 @@ rsaKeysAreEqual(PK11ObjectType srcType, void *src, } if (!areEqual) { fprintf(stderr, "original key:\n"); - dumpTemplate(srcTemplate, 0, RSA_ATTRIBUTES); + dumpTemplate(stderr, srcTemplate, 0, RSA_ATTRIBUTES); fprintf(stderr, "created key:\n"); - dumpTemplate(destTemplate, 0, RSA_ATTRIBUTES); + dumpTemplate(stderr, destTemplate, 0, RSA_ATTRIBUTES); } + resetTemplate(srcTemplate, 0, RSA_ATTRIBUTES); + resetTemplate(destTemplate, 0, RSA_ATTRIBUTES); return areEqual; } static int exp_exp_prime_fail_count = 0; +#define LEAK_ID 0xf + static int doRSAPopulateTest(unsigned int keySize, unsigned long exponent, - int mask, void *pwarg) + int mask, int round, void *pwarg) { SECKEYPrivateKey *rsaPrivKey; SECKEYPublicKey *rsaPubKey; @@ -227,7 +266,10 @@ doRSAPopulateTest(unsigned int keySize, unsigned long exponent, CK_OBJECT_CLASS obj_class = CKO_PRIVATE_KEY; CK_KEY_TYPE key_type = CKK_RSA; CK_BBOOL ck_false = CK_FALSE; + CK_BYTE cka_id[2] = { 0, 0 }; int failed = 0; + int leak_found; /* did we find the expected leak */ + int expect_leak = 0; /* are we expecting a leak? */ rsaParams.pe = exponent; rsaParams.keySizeInBits = keySize; @@ -259,11 +301,15 @@ doRSAPopulateTest(unsigned int keySize, unsigned long exponent, tstTemplate[3].ulValueLen = sizeof(ck_false); tstTemplate[4].pValue = &ck_false; tstTemplate[4].ulValueLen = sizeof(ck_false); - tstHeaderCount = 5; + tstTemplate[5].pValue = &cka_id[0]; + tstTemplate[5].ulValueLen = sizeof(cka_id); + tstHeaderCount = 6; + cka_id[0] = round; if (mask & 1) { printf("%s\n", test_array[1].description); resetTemplate(tstTemplate, tstHeaderCount, RSA_ATTRIBUTES); + cka_id[1] = 0; copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, tstHeaderCount, CKA_PUBLIC_EXPONENT); copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, @@ -271,10 +317,10 @@ doRSAPopulateTest(unsigned int keySize, unsigned long exponent, copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, tstHeaderCount + 2, CKA_PRIME_1); - tstPrivKey = PK11_CreateGenericObject(slot, tstTemplate, - tstHeaderCount + - 3, - PR_FALSE); + tstPrivKey = PK11_CreateManagedGenericObject(slot, tstTemplate, + tstHeaderCount + + 3, + PR_FALSE); if (tstPrivKey == NULL) { fprintf(stderr, "RSA Populate failed: pubExp mod p\n"); failed = 1; @@ -290,6 +336,7 @@ doRSAPopulateTest(unsigned int keySize, unsigned long exponent, printf("%s\n", test_array[2].description); /* test the basic2 case, public exponent, modulus, prime2 */ resetTemplate(tstTemplate, tstHeaderCount, RSA_ATTRIBUTES); + cka_id[1] = 1; copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, tstHeaderCount, CKA_PUBLIC_EXPONENT); copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, @@ -299,10 +346,10 @@ doRSAPopulateTest(unsigned int keySize, unsigned long exponent, /* test with q in the prime1 position */ tstTemplate[tstHeaderCount + 2].type = CKA_PRIME_1; - tstPrivKey = PK11_CreateGenericObject(slot, tstTemplate, - tstHeaderCount + - 3, - PR_FALSE); + tstPrivKey = PK11_CreateManagedGenericObject(slot, tstTemplate, + tstHeaderCount + + 3, + PR_FALSE); if (tstPrivKey == NULL) { fprintf(stderr, "RSA Populate failed: pubExp mod q\n"); failed = 1; @@ -318,6 +365,7 @@ doRSAPopulateTest(unsigned int keySize, unsigned long exponent, printf("%s\n", test_array[3].description); /* test the medium case, private exponent, prime1, prime2 */ resetTemplate(tstTemplate, tstHeaderCount, RSA_ATTRIBUTES); + cka_id[1] = 2; copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, tstHeaderCount, CKA_PRIVATE_EXPONENT); @@ -329,10 +377,10 @@ doRSAPopulateTest(unsigned int keySize, unsigned long exponent, tstTemplate[tstHeaderCount + 2].type = CKA_PRIME_1; tstTemplate[tstHeaderCount + 1].type = CKA_PRIME_2; - tstPrivKey = PK11_CreateGenericObject(slot, tstTemplate, - tstHeaderCount + - 3, - PR_FALSE); + tstPrivKey = PK11_CreateManagedGenericObject(slot, tstTemplate, + tstHeaderCount + + 3, + PR_FALSE); if (tstPrivKey == NULL) { fprintf(stderr, "RSA Populate failed: privExp p q\n"); failed = 1; @@ -348,6 +396,7 @@ doRSAPopulateTest(unsigned int keySize, unsigned long exponent, printf("%s\n", test_array[4].description); /* test the advanced case, public exponent, private exponent, prime2 */ resetTemplate(tstTemplate, tstHeaderCount, RSA_ATTRIBUTES); + cka_id[1] = 3; copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, tstHeaderCount, CKA_PRIVATE_EXPONENT); copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, @@ -355,10 +404,10 @@ doRSAPopulateTest(unsigned int keySize, unsigned long exponent, copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, tstHeaderCount + 2, CKA_PRIME_2); - tstPrivKey = PK11_CreateGenericObject(slot, tstTemplate, - tstHeaderCount + - 3, - PR_FALSE); + tstPrivKey = PK11_CreateManagedGenericObject(slot, tstTemplate, + tstHeaderCount + + 3, + PR_FALSE); if (tstPrivKey == NULL) { fprintf(stderr, "RSA Populate failed: pubExp privExp q\n"); fprintf(stderr, " this is expected periodically. It means we\n"); @@ -373,11 +422,12 @@ doRSAPopulateTest(unsigned int keySize, unsigned long exponent, if (tstPrivKey) PK11_DestroyGenericObject(tstPrivKey); } - if (mask & 16) { + if (mask & 0x10) { printf("%s\n", test_array[5].description); /* test the advanced case2, public exponent, private exponent, modulus */ resetTemplate(tstTemplate, tstHeaderCount, RSA_ATTRIBUTES); + cka_id[1] = LEAK_ID; copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, tstHeaderCount, CKA_PRIVATE_EXPONENT); @@ -386,6 +436,7 @@ doRSAPopulateTest(unsigned int keySize, unsigned long exponent, copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, tstHeaderCount + 2, CKA_MODULUS); + /* purposefully use the old version. This will create a leak */ tstPrivKey = PK11_CreateGenericObject(slot, tstTemplate, tstHeaderCount + 3, @@ -398,9 +449,59 @@ doRSAPopulateTest(unsigned int keySize, unsigned long exponent, fprintf(stderr, "RSA Populate key mismatch: pubExp privExp mod\n"); failed = 1; } + expect_leak = 1; if (tstPrivKey) PK11_DestroyGenericObject(tstPrivKey); } + resetTemplate(tstTemplate, tstHeaderCount, RSA_ATTRIBUTES); + SECKEY_DestroyPrivateKey(rsaPrivKey); + SECKEY_DestroyPublicKey(rsaPubKey); + + /* make sure we didn't leak */ + leak_found = 0; + tstPrivKey = PK11_FindGenericObjects(slot, CKO_PRIVATE_KEY); + if (tstPrivKey) { + SECStatus rv; + PK11GenericObject *thisKey; + int i; + + fprintf(stderr, "Leaking keys...\n"); + for (i = 0, thisKey = tstPrivKey; thisKey; i++, + thisKey = PK11_GetNextGenericObject(thisKey)) { + SECItem id = { 0, NULL, 0 }; + + rv = PK11_ReadRawAttribute(PK11_TypeGeneric, thisKey, + CKA_ID, &id); + if (rv != SECSuccess) { + fprintf(stderr, "Key %d: couldn't read CKA_ID: %s\n", + i, PORT_ErrorToString(PORT_GetError())); + continue; + } + fprintf(stderr, "id = { "); + dumpItem(stderr, &id); + fprintf(stderr, "};"); + if (id.data[1] == LEAK_ID) { + fprintf(stderr, " ---> leak expected\n"); + if (id.data[0] == round) + leak_found = 1; + } else { + if (id.len != sizeof(cka_id)) { + fprintf(stderr, + " ---> ERROR unexpected leak in generated key\n"); + } else { + fprintf(stderr, + " ---> ERROR unexpected leak in constructed key\n"); + } + failed = 1; + } + SECITEM_FreeItem(&id, PR_FALSE); + } + PK11_DestroyGenericObjects(tstPrivKey); + } + if (expect_leak && !leak_found) { + fprintf(stderr, "ERROR expected leak not found\n"); + failed = 1; + } PK11_FreeSlot(slot); return failed ? -1 : 0; @@ -517,7 +618,7 @@ main(int argc, char **argv) exp_exp_prime_fail_count = 0; for (i = 0; i < repeat; i++) { printf("Running RSA Populate test run %d\n", i); - ret = doRSAPopulateTest(keySize, exponent, mask, NULL); + ret = doRSAPopulateTest(keySize, exponent, mask, i, NULL); if (ret != 0) { i++; break; @@ -531,5 +632,9 @@ main(int argc, char **argv) exp_exp_prime_fail_count, i, (((double)exp_exp_prime_fail_count) * 100.0) / (double)i); } + if (NSS_Shutdown() != SECSuccess) { + fprintf(stderr, "Shutdown failed\n"); + ret = -1; + } return ret; } diff --git a/security/nss/cmd/certcgi/certcgi.gyp b/security/nss/cmd/rsapoptst/rsapoptst.gyp index 5ad2893e0..325a10909 100644 --- a/security/nss/cmd/certcgi/certcgi.gyp +++ b/security/nss/cmd/rsapoptst/rsapoptst.gyp @@ -8,26 +8,18 @@ ], 'targets': [ { - 'target_name': 'certcgi', + 'target_name': 'rsapoptst', 'type': 'executable', 'sources': [ - 'certcgi.c' + 'rsapoptst.c' ], 'dependencies': [ '<(DEPTH)/exports.gyp:dbm_exports', '<(DEPTH)/exports.gyp:nss_exports', - '<(DEPTH)/lib/sqlite/sqlite.gyp:sqlite3' ] } ], - 'target_defaults': { - 'defines': [ - 'NSPR20', - 'NSS_USE_STATIC_LIBS' - ] - }, 'variables': { 'module': 'nss', - 'use_static_libs': 1 } -}
\ No newline at end of file +} diff --git a/security/nss/cmd/selfserv/selfserv.c b/security/nss/cmd/selfserv/selfserv.c index 65b1ee304..fac428e10 100644 --- a/security/nss/cmd/selfserv/selfserv.c +++ b/security/nss/cmd/selfserv/selfserv.c @@ -38,6 +38,7 @@ #include "nss.h" #include "ssl.h" #include "sslproto.h" +#include "sslexp.h" #include "cert.h" #include "certt.h" #include "ocsp.h" @@ -165,9 +166,7 @@ PrintUsageHeader(const char *progName) " [-V [min-version]:[max-version]] [-a sni_name]\n" " [ T <good|revoked|unknown|badsig|corrupted|none|ocsp>] [-A ca]\n" " [-C SSLCacheEntries] [-S dsa_nickname] -Q [-I groups]" -#ifndef NSS_DISABLE_ECC " [-e ec_nickname]" -#endif /* NSS_DISABLE_ECC */ "\n" " -U [0|1] -H [0|1|2] -W [0|1]\n" "\n", @@ -1955,6 +1954,10 @@ server_main( if (enabledVersions.max < SSL_LIBRARY_VERSION_TLS_1_3) { errExit("You tried enabling 0RTT without enabling TLS 1.3!"); } + rv = SSL_SetupAntiReplay(10 * PR_USEC_PER_SEC, 7, 14); + if (rv != SECSuccess) { + errExit("error configuring anti-replay "); + } rv = SSL_OptionSet(model_sock, SSL_ENABLE_0RTT_DATA, PR_TRUE); if (rv != SECSuccess) { errExit("error enabling 0RTT "); @@ -2343,7 +2346,6 @@ main(int argc, char **argv) dir = optstate->value; break; -#ifndef NSS_DISABLE_ECC case 'e': if (certNicknameIndex >= MAX_CERT_NICKNAME_ARRAY_INDEX) { Usage(progName); @@ -2351,7 +2353,6 @@ main(int argc, char **argv) } certNicknameArray[certNicknameIndex++] = PORT_Strdup(optstate->value); break; -#endif /* NSS_DISABLE_ECC */ case 'f': pwdata.source = PW_FROMFILE; @@ -2553,6 +2554,14 @@ main(int argc, char **argv) tmp = PR_GetEnvSecure("TMPDIR"); if (!tmp) tmp = PR_GetEnvSecure("TEMP"); + + /* Call the NSS initialization routines */ + rv = NSS_Initialize(dir, certPrefix, certPrefix, SECMOD_DB, NSS_INIT_READONLY); + if (rv != SECSuccess) { + fputs("NSS_Init failed.\n", stderr); + exit(8); + } + if (envString) { /* we're one of the children in a multi-process server. */ listen_sock = PR_GetInheritedFD(inheritableSockName); @@ -2607,13 +2616,6 @@ main(int argc, char **argv) /* set our password function */ PK11_SetPasswordFunc(SECU_GetModulePassword); - /* Call the NSS initialization routines */ - rv = NSS_Initialize(dir, certPrefix, certPrefix, SECMOD_DB, NSS_INIT_READONLY); - if (rv != SECSuccess) { - fputs("NSS_Init failed.\n", stderr); - exit(8); - } - /* all SSL3 cipher suites are enabled by default. */ if (cipherString) { char *cstringSaved = cipherString; @@ -2681,9 +2683,7 @@ main(int argc, char **argv) certNicknameArray[i]); exit(11); } -#ifdef NSS_DISABLE_ECC if (privKey[i]->keyType != ecKey) -#endif setupCertStatus(certStatusArena, ocspStaplingMode, cert[i], i, &pwdata); } diff --git a/security/nss/cmd/signtool/javascript.c b/security/nss/cmd/signtool/javascript.c index 746f724f8..ffff2db59 100644 --- a/security/nss/cmd/signtool/javascript.c +++ b/security/nss/cmd/signtool/javascript.c @@ -1115,8 +1115,7 @@ extract_js(char *filename) textStart = 0; startLine = 0; - while (linenum = FB_GetLineNum(fb), (curchar = FB_GetChar(fb)) != - EOF) { + while (linenum = FB_GetLineNum(fb), (curchar = FB_GetChar(fb)) != EOF) { switch (state) { case TEXT_HTML_STATE: if (curchar == '<') { diff --git a/security/nss/cmd/signtool/sign.c b/security/nss/cmd/signtool/sign.c index 6e776069a..6f8e43946 100644 --- a/security/nss/cmd/signtool/sign.c +++ b/security/nss/cmd/signtool/sign.c @@ -43,6 +43,7 @@ SignArchive(char *tree, char *keyName, char *zip_file, int javascript, int status; char tempfn[FNSIZE], fullfn[FNSIZE]; int keyType = rsaKey; + int count; metafile = meta_file; optimize = _optimize; @@ -81,9 +82,18 @@ SignArchive(char *tree, char *keyName, char *zip_file, int javascript, } /* rsa/dsa to zip */ - sprintf(tempfn, "META-INF/%s.%s", base, (keyType == dsaKey ? "dsa" - : "rsa")); - sprintf(fullfn, "%s/%s", tree, tempfn); + count = snprintf(tempfn, sizeof(tempfn), "META-INF/%s.%s", base, (keyType == dsaKey ? "dsa" : "rsa")); + if (count >= sizeof(tempfn)) { + PR_fprintf(errorFD, "unable to write key metadata\n"); + errorCount++; + exit(ERRX); + } + count = snprintf(fullfn, sizeof(fullfn), "%s/%s", tree, tempfn); + if (count >= sizeof(fullfn)) { + PR_fprintf(errorFD, "unable to write key metadata\n"); + errorCount++; + exit(ERRX); + } JzipAdd(fullfn, tempfn, zipfile, compression_level); /* Loop through all files & subdirectories, add to archive */ @@ -93,20 +103,44 @@ SignArchive(char *tree, char *keyName, char *zip_file, int javascript, } /* mf to zip */ strcpy(tempfn, "META-INF/manifest.mf"); - sprintf(fullfn, "%s/%s", tree, tempfn); + count = snprintf(fullfn, sizeof(fullfn), "%s/%s", tree, tempfn); + if (count >= sizeof(fullfn)) { + PR_fprintf(errorFD, "unable to write manifest\n"); + errorCount++; + exit(ERRX); + } JzipAdd(fullfn, tempfn, zipfile, compression_level); /* sf to zip */ - sprintf(tempfn, "META-INF/%s.sf", base); - sprintf(fullfn, "%s/%s", tree, tempfn); + count = snprintf(tempfn, sizeof(tempfn), "META-INF/%s.sf", base); + if (count >= sizeof(tempfn)) { + PR_fprintf(errorFD, "unable to write sf metadata\n"); + errorCount++; + exit(ERRX); + } + count = snprintf(fullfn, sizeof(fullfn), "%s/%s", tree, tempfn); + if (count >= sizeof(fullfn)) { + PR_fprintf(errorFD, "unable to write sf metadata\n"); + errorCount++; + exit(ERRX); + } JzipAdd(fullfn, tempfn, zipfile, compression_level); /* Add the rsa/dsa file to the zip archive normally */ if (!xpi_arc) { /* rsa/dsa to zip */ - sprintf(tempfn, "META-INF/%s.%s", base, (keyType == dsaKey ? "dsa" - : "rsa")); - sprintf(fullfn, "%s/%s", tree, tempfn); + count = snprintf(tempfn, sizeof(tempfn), "META-INF/%s.%s", base, (keyType == dsaKey ? "dsa" : "rsa")); + if (count >= sizeof(tempfn)) { + PR_fprintf(errorFD, "unable to write key metadata\n"); + errorCount++; + exit(ERRX); + } + count = snprintf(fullfn, sizeof(fullfn), "%s/%s", tree, tempfn); + if (count >= sizeof(fullfn)) { + PR_fprintf(errorFD, "unable to write key metadata\n"); + errorCount++; + exit(ERRX); + } JzipAdd(fullfn, tempfn, zipfile, compression_level); } @@ -408,6 +442,7 @@ static int manifesto_xpi_fn(char *relpath, char *basedir, char *reldir, char *filename, void *arg) { char fullname[FNSIZE]; + int count; if (verbosity >= 0) { PR_fprintf(outputFD, "--> %s\n", relpath); @@ -421,7 +456,10 @@ manifesto_xpi_fn(char *relpath, char *basedir, char *reldir, char *filename, voi if (!PL_HashTableLookup(extensions, ext)) return 0; } - sprintf(fullname, "%s/%s", basedir, relpath); + count = snprintf(fullname, sizeof(fullname), "%s/%s", basedir, relpath); + if (count >= sizeof(fullname)) { + return 1; + } JzipAdd(fullname, relpath, zipfile, compression_level); return 0; diff --git a/security/nss/cmd/signtool/signtool.c b/security/nss/cmd/signtool/signtool.c index 51857d638..915a00fbc 100644 --- a/security/nss/cmd/signtool/signtool.c +++ b/security/nss/cmd/signtool/signtool.c @@ -1033,9 +1033,7 @@ main(int argc, char *argv[]) if (errorCount > 0 || warningCount > 0) { PR_fprintf(outputFD, "%d error%s, %d warning%s.\n", errorCount, - errorCount == 1 ? "" : "s", warningCount, warningCount == 1 - ? "" - : "s"); + errorCount == 1 ? "" : "s", warningCount, warningCount == 1 ? "" : "s"); } else { PR_fprintf(outputFD, "Directory %s signed successfully.\n", jartree); diff --git a/security/nss/cmd/smimetools/cmsutil.c b/security/nss/cmd/smimetools/cmsutil.c index 10e743c6b..fe17f26a4 100644 --- a/security/nss/cmd/smimetools/cmsutil.c +++ b/security/nss/cmd/smimetools/cmsutil.c @@ -1572,10 +1572,7 @@ main(int argc, char **argv) { unsigned int j; for (j = 0; j < input.len; j++) - fprintf(stderr, "%2x%c", input.data[j], (j > 0 && - j % 35 == 0) - ? '\n' - : ' '); + fprintf(stderr, "%2x%c", input.data[j], (j > 0 && j % 35 == 0) ? '\n' : ' '); } } if (input.len > 0) { /* skip if certs-only (or other zero content) */ diff --git a/security/nss/cmd/ssltap/ssltap.c b/security/nss/cmd/ssltap/ssltap.c index 197b1942d..a2471884e 100644 --- a/security/nss/cmd/ssltap/ssltap.c +++ b/security/nss/cmd/ssltap/ssltap.c @@ -1637,8 +1637,7 @@ print_ssl3_handshake(unsigned char *recordBuf, PR_snprintf(certFileName, sizeof certFileName, "cert.%03d", ++certFileNumber); cfd = - PR_Open(certFileName, PR_WRONLY | - PR_CREATE_FILE | PR_TRUNCATE, + PR_Open(certFileName, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE, 0664); if (!cfd) { PR_fprintf(PR_STDOUT, @@ -1722,8 +1721,7 @@ print_ssl3_handshake(unsigned char *recordBuf, 0 && sslhexparse) { PR_fprintf(PR_STDOUT, " = {\n"); - print_hex(dnLen, hsdata + - pos); + print_hex(dnLen, hsdata + pos); PR_fprintf(PR_STDOUT, " }\n"); } else { PR_fprintf(PR_STDOUT, "\n"); @@ -1796,8 +1794,7 @@ print_ssl3_handshake(unsigned char *recordBuf, PR_snprintf(ocspFileName, sizeof ocspFileName, "ocsp.%03d", ++ocspFileNumber); - ofd = PR_Open(ocspFileName, PR_WRONLY | - PR_CREATE_FILE | PR_TRUNCATE, + ofd = PR_Open(ocspFileName, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE, 0664); if (!ofd) { PR_fprintf(PR_STDOUT, @@ -2167,8 +2164,7 @@ print_ssl(DataBufferList *s, int length, unsigned char *buffer) break; case 22: /* handshake */ - print_ssl3_handshake(recordBuf, recordLen - - s->hMACsize, + print_ssl3_handshake(recordBuf, recordLen - s->hMACsize, &sr, s); break; diff --git a/security/nss/cmd/strsclnt/strsclnt.c b/security/nss/cmd/strsclnt/strsclnt.c index f65e31913..7d259bd0a 100644 --- a/security/nss/cmd/strsclnt/strsclnt.c +++ b/security/nss/cmd/strsclnt/strsclnt.c @@ -886,8 +886,10 @@ PRBool LoggedIn(CERTCertificate *cert, SECKEYPrivateKey *key) { if ((cert->slot) && (key->pkcs11Slot) && - (PR_TRUE == PK11_IsLoggedIn(cert->slot, NULL)) && - (PR_TRUE == PK11_IsLoggedIn(key->pkcs11Slot, NULL))) { + (!PK11_NeedLogin(cert->slot) || + PR_TRUE == PK11_IsLoggedIn(cert->slot, NULL)) && + (!PK11_NeedLogin(key->pkcs11Slot) || + PR_TRUE == PK11_IsLoggedIn(key->pkcs11Slot, NULL))) { return PR_TRUE; } diff --git a/security/nss/cmd/tstclnt/tstclnt.c b/security/nss/cmd/tstclnt/tstclnt.c index 959afec59..1ad99502b 100644 --- a/security/nss/cmd/tstclnt/tstclnt.c +++ b/security/nss/cmd/tstclnt/tstclnt.c @@ -31,6 +31,7 @@ #include "ocsp.h" #include "ssl.h" #include "sslproto.h" +#include "sslexp.h" #include "pk11func.h" #include "secmod.h" #include "plgetopt.h" @@ -95,6 +96,7 @@ PRBool verbose; int dumpServerChain = 0; int renegotiationsToDo = 0; int renegotiationsDone = 0; +PRBool initializedServerSessionCache = PR_FALSE; static char *progName; @@ -178,7 +180,7 @@ PrintUsageHeader(const char *progName) "[-n nickname] [-Bafosvx] [-c ciphers] [-Y] [-Z]\n" "[-V [min-version]:[max-version]] [-K] [-T] [-U]\n" "[-r N] [-w passwd] [-W pwfile] [-q [-t seconds]] [-I groups]\n" - "[-A requestfile] [-L totalconnections]\n" + "[-A requestfile] [-L totalconnections] [-P {client,server}] [-Q]\n" "\n", progName); } @@ -202,7 +204,7 @@ PrintParameterUsage(void) fprintf(stderr, "%-20s Print certificate chain information\n", "-C"); fprintf(stderr, "%-20s (use -C twice to print more certificate details)\n", ""); fprintf(stderr, "%-20s (use -C three times to include PEM format certificate dumps)\n", ""); - fprintf(stderr, "%-20s Nickname of key and cert for client auth\n", + fprintf(stderr, "%-20s Nickname of key and cert\n", "-n nickname"); fprintf(stderr, "%-20s Restricts the set of enabled SSL/TLS protocols versions.\n" @@ -251,6 +253,9 @@ PrintParameterUsage(void) "%-20s The following values are valid:\n" "%-20s P256, P384, P521, x25519, FF2048, FF3072, FF4096, FF6144, FF8192\n", "-I", "", ""); + fprintf(stderr, "%-20s Enable alternative TLS 1.3 handshake\n", "-X alt-server-hello"); + fprintf(stderr, "%-20s Use DTLS\n", "-P {client, server}"); + fprintf(stderr, "%-20s Exit after handshake\n", "-Q"); } static void @@ -914,6 +919,12 @@ char *requestString = NULL; PRInt32 requestStringLen = 0; PRBool requestSent = PR_FALSE; PRBool enableZeroRtt = PR_FALSE; +PRBool enableAltServerHello = PR_FALSE; +PRBool useDTLS = PR_FALSE; +PRBool actAsServer = PR_FALSE; +PRBool stopAfterHandshake = PR_FALSE; +PRBool requestToExit = PR_FALSE; +char *versionString = NULL; static int writeBytesToServer(PRFileDesc *s, const char *buf, int nb) @@ -996,12 +1007,129 @@ handshakeCallback(PRFileDesc *fd, void *client_data) writeBytesToServer(fd, requestString, requestStringLen); } } + if (stopAfterHandshake) { + requestToExit = PR_TRUE; + } } #define REQUEST_WAITING (requestString && !requestSent) +static SECStatus +installServerCertificate(PRFileDesc *s, char *nickname) +{ + CERTCertificate *cert; + SECKEYPrivateKey *privKey = NULL; + + if (!nickname) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + + cert = PK11_FindCertFromNickname(nickname, &pwdata); + if (cert == NULL) { + return SECFailure; + } + + privKey = PK11_FindKeyByAnyCert(cert, &pwdata); + if (privKey == NULL) { + return SECFailure; + } + if (SSL_ConfigServerCert(s, cert, privKey, NULL, 0) != SECSuccess) { + return SECFailure; + } + SECKEY_DestroyPrivateKey(privKey); + CERT_DestroyCertificate(cert); + + return SECSuccess; +} + +static SECStatus +bindToClient(PRFileDesc *s) +{ + PRStatus status; + status = PR_Bind(s, &addr); + if (status != PR_SUCCESS) { + return SECFailure; + } + + for (;;) { + /* Bind the remote address on first packet. This must happen + * before we SSL-ize the socket because we need to get the + * peer's address before SSLizing. Recvfrom gives us that + * while not consuming any data. */ + unsigned char tmp; + PRNetAddr remote; + int nb; + + nb = PR_RecvFrom(s, &tmp, 1, PR_MSG_PEEK, + &remote, PR_INTERVAL_NO_TIMEOUT); + if (nb != 1) + continue; + + status = PR_Connect(s, &remote, PR_INTERVAL_NO_TIMEOUT); + if (status != PR_SUCCESS) { + SECU_PrintError(progName, "server bind to remote end failed"); + return SECFailure; + } + return SECSuccess; + } + + /* Unreachable. */ +} + +static SECStatus +connectToServer(PRFileDesc *s, PRPollDesc *pollset) +{ + PRStatus status; + PRInt32 filesReady; + + status = PR_Connect(s, &addr, PR_INTERVAL_NO_TIMEOUT); + if (status != PR_SUCCESS) { + if (PR_GetError() == PR_IN_PROGRESS_ERROR) { + if (verbose) + SECU_PrintError(progName, "connect"); + milliPause(50 * multiplier); + pollset[SSOCK_FD].in_flags = PR_POLL_WRITE | PR_POLL_EXCEPT; + pollset[SSOCK_FD].out_flags = 0; + pollset[SSOCK_FD].fd = s; + while (1) { + FPRINTF(stderr, + "%s: about to call PR_Poll for connect completion!\n", + progName); + filesReady = PR_Poll(pollset, 1, PR_INTERVAL_NO_TIMEOUT); + if (filesReady < 0) { + SECU_PrintError(progName, "unable to connect (poll)"); + return SECFailure; + } + FPRINTF(stderr, + "%s: PR_Poll returned 0x%02x for socket out_flags.\n", + progName, pollset[SSOCK_FD].out_flags); + if (filesReady == 0) { /* shouldn't happen! */ + SECU_PrintError(progName, "%s: PR_Poll returned zero!\n"); + return SECFailure; + } + status = PR_GetConnectStatus(pollset); + if (status == PR_SUCCESS) { + break; + } + if (PR_GetError() != PR_IN_PROGRESS_ERROR) { + SECU_PrintError(progName, "unable to connect (poll)"); + return SECFailure; + } + SECU_PrintError(progName, "poll"); + milliPause(50 * multiplier); + } + } else { + SECU_PrintError(progName, "unable to connect"); + return SECFailure; + } + } + + return SECSuccess; +} + static int -run_client(void) +run(void) { int headerSeparatorPtrnId = 0; int error = 0; @@ -1017,13 +1145,23 @@ run_client(void) requestSent = PR_FALSE; /* Create socket */ - s = PR_OpenTCPSocket(addr.raw.family); + if (useDTLS) { + s = PR_OpenUDPSocket(addr.raw.family); + } else { + s = PR_OpenTCPSocket(addr.raw.family); + } + if (s == NULL) { SECU_PrintError(progName, "error creating socket"); error = 1; goto done; } + if (actAsServer) { + if (bindToClient(s) != SECSuccess) { + return 1; + } + } opt.option = PR_SockOpt_Nonblocking; opt.value.non_blocking = PR_TRUE; /* default */ if (serverCertAuth.testFreshStatusFromSideChannel) { @@ -1036,13 +1174,16 @@ run_client(void) goto done; } - s = SSL_ImportFD(NULL, s); + if (useDTLS) { + s = DTLS_ImportFD(NULL, s); + } else { + s = SSL_ImportFD(NULL, s); + } if (s == NULL) { SECU_PrintError(progName, "error importing socket"); error = 1; goto done; } - SSL_SetPKCS11PinArg(s, &pwdata); rv = SSL_OptionSet(s, SSL_SECURITY, 1); @@ -1052,7 +1193,7 @@ run_client(void) goto done; } - rv = SSL_OptionSet(s, SSL_HANDSHAKE_AS_CLIENT, 1); + rv = SSL_OptionSet(s, actAsServer ? SSL_HANDSHAKE_AS_SERVER : SSL_HANDSHAKE_AS_CLIENT, 1); if (rv != SECSuccess) { SECU_PrintError(progName, "error enabling client handshake"); error = 1; @@ -1178,6 +1319,16 @@ run_client(void) } } + /* Alternate ServerHello content type (TLS 1.3 only) */ + if (enableAltServerHello) { + rv = SSL_UseAltServerHelloType(s, PR_TRUE); + if (rv != SECSuccess) { + SECU_PrintError(progName, "error enabling alternate ServerHello type"); + error = 1; + goto done; + } + } + /* require the use of fixed finite-field DH groups */ if (requireDHNamedGroups) { rv = SSL_OptionSet(s, SSL_REQUIRE_DH_NAMED_GROUPS, PR_TRUE); @@ -1212,7 +1363,21 @@ run_client(void) if (override) { SSL_BadCertHook(s, ownBadCertHandler, NULL); } - SSL_GetClientAuthDataHook(s, own_GetClientAuthData, (void *)nickname); + if (actAsServer) { + rv = installServerCertificate(s, nickname); + if (rv != SECSuccess) { + SECU_PrintError(progName, "error installing server cert"); + return 1; + } + rv = SSL_ConfigServerSessionIDCache(1024, 0, 0, "."); + if (rv != SECSuccess) { + SECU_PrintError(progName, "error configuring session cache"); + return 1; + } + initializedServerSessionCache = PR_TRUE; + } else { + SSL_GetClientAuthDataHook(s, own_GetClientAuthData, (void *)nickname); + } SSL_HandshakeCallback(s, handshakeCallback, hs2SniHostName); if (hs1SniHostName) { SSL_SetURL(s, hs1SniHostName); @@ -1220,56 +1385,27 @@ run_client(void) SSL_SetURL(s, host); } - /* Try to connect to the server */ - status = PR_Connect(s, &addr, PR_INTERVAL_NO_TIMEOUT); - if (status != PR_SUCCESS) { - if (PR_GetError() == PR_IN_PROGRESS_ERROR) { - if (verbose) - SECU_PrintError(progName, "connect"); - milliPause(50 * multiplier); - pollset[SSOCK_FD].in_flags = PR_POLL_WRITE | PR_POLL_EXCEPT; - pollset[SSOCK_FD].out_flags = 0; - pollset[SSOCK_FD].fd = s; - while (1) { - FPRINTF(stderr, - "%s: about to call PR_Poll for connect completion!\n", - progName); - filesReady = PR_Poll(pollset, 1, PR_INTERVAL_NO_TIMEOUT); - if (filesReady < 0) { - SECU_PrintError(progName, "unable to connect (poll)"); - error = 1; - goto done; - } - FPRINTF(stderr, - "%s: PR_Poll returned 0x%02x for socket out_flags.\n", - progName, pollset[SSOCK_FD].out_flags); - if (filesReady == 0) { /* shouldn't happen! */ - FPRINTF(stderr, "%s: PR_Poll returned zero!\n", progName); - error = 1; - goto done; - } - status = PR_GetConnectStatus(pollset); - if (status == PR_SUCCESS) { - break; - } - if (PR_GetError() != PR_IN_PROGRESS_ERROR) { - SECU_PrintError(progName, "unable to connect (poll)"); - error = 1; - goto done; - } - SECU_PrintError(progName, "poll"); - milliPause(50 * multiplier); - } - } else { - SECU_PrintError(progName, "unable to connect"); + if (actAsServer) { + rv = SSL_ResetHandshake(s, PR_TRUE /* server */); + if (rv != SECSuccess) { + return 1; + } + } else { + /* Try to connect to the server */ + rv = connectToServer(s, pollset); + if (rv != SECSuccess) { + ; error = 1; goto done; } } pollset[SSOCK_FD].fd = s; - pollset[SSOCK_FD].in_flags = PR_POLL_EXCEPT | - (clientSpeaksFirst ? 0 : PR_POLL_READ); + pollset[SSOCK_FD].in_flags = PR_POLL_EXCEPT; + if (!actAsServer) + 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; @@ -1319,9 +1455,11 @@ run_client(void) ** Select on stdin and on the socket. Write data from stdin to ** socket, read data from socket and write to stdout. */ + requestToExit = PR_FALSE; FPRINTF(stderr, "%s: ready...\n", progName); - while ((pollset[SSOCK_FD].in_flags | pollset[STDIN_FD].in_flags) || - REQUEST_WAITING) { + 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. */ @@ -1507,12 +1645,10 @@ main(int argc, char **argv) } } - SSL_VersionRangeGetSupported(ssl_variant_stream, &enabledVersions); - /* XXX: 'B' was used in the past but removed in 3.28, * please leave some time before resuing it. */ optstate = PL_CreateOptState(argc, argv, - "46A:CDFGHI:KL:M:OR:STUV:W:YZa:bc:d:fgh:m:n:op:qr:st:uvw:z"); + "46A:CDFGHI:KL:M:OP:QR:STUV:W:X:YZa:bc:d:fgh:m:n:op:qr:st:uvw:z"); while ((optstatus = PL_GetNextOpt(optstate)) == PL_OPT_OK) { switch (optstate->option) { case '?': @@ -1593,6 +1729,21 @@ main(int argc, char **argv) }; break; + case 'P': + useDTLS = PR_TRUE; + if (!strcmp(optstate->value, "server")) { + actAsServer = 1; + } else { + if (strcmp(optstate->value, "client")) { + Usage(progName); + } + } + break; + + case 'Q': + stopAfterHandshake = PR_TRUE; + break; + case 'R': rootModule = PORT_Strdup(optstate->value); break; @@ -1610,14 +1761,16 @@ main(int argc, char **argv) break; case 'V': - if (SECU_ParseSSLVersionRangeString(optstate->value, - enabledVersions, &enabledVersions) != - SECSuccess) { - fprintf(stderr, "Bad version specified.\n"); + versionString = PORT_Strdup(optstate->value); + break; + + case 'X': + if (!strcmp(optstate->value, "alt-server-hello")) { + enableAltServerHello = PR_TRUE; + } else { Usage(progName); } break; - case 'Y': PrintCipherUsage(progName); exit(0); @@ -1727,9 +1880,20 @@ main(int argc, char **argv) break; } } - PL_DestroyOptState(optstate); + SSL_VersionRangeGetSupported(useDTLS ? ssl_variant_datagram : ssl_variant_stream, &enabledVersions); + + if (versionString) { + if (SECU_ParseSSLVersionRangeString(versionString, + enabledVersions, &enabledVersions) != + SECSuccess) { + fprintf(stderr, "Bad version specified.\n"); + Usage(progName); + } + PORT_Free(versionString); + } + if (optstatus == PL_OPT_BAD) { Usage(progName); } @@ -1758,7 +1922,7 @@ main(int argc, char **argv) PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1); PK11_SetPasswordFunc(SECU_GetModulePassword); - + memset(&addr, 0, sizeof(addr)); status = PR_StringToNetAddr(host, &addr); if (status == PR_SUCCESS) { addr.inet.port = PR_htons(portno); @@ -1770,6 +1934,7 @@ main(int argc, char **argv) addrInfo = PR_GetAddrInfoByName(host, PR_AF_UNSPEC, PR_AI_ADDRCONFIG | PR_AI_NOCANONNAME); if (!addrInfo) { + fprintf(stderr, "HOSTNAME=%s\n", host); SECU_PrintError(progName, "error looking up host"); error = 1; goto done; @@ -1884,7 +2049,7 @@ main(int argc, char **argv) } while (numConnections--) { - error = run_client(); + error = run(); if (error) { goto done; } @@ -1915,6 +2080,12 @@ done: } if (NSS_IsInitialized()) { SSL_ClearSessionCache(); + if (initializedServerSessionCache) { + if (SSL_ShutdownServerSessionIDCache() != SECSuccess) { + error = 1; + } + } + if (NSS_Shutdown() != SECSuccess) { error = 1; } diff --git a/security/nss/coreconf/config.gypi b/security/nss/coreconf/config.gypi index 9ea528ae4..58137872c 100644 --- a/security/nss/coreconf/config.gypi +++ b/security/nss/coreconf/config.gypi @@ -96,7 +96,6 @@ 'mozilla_client%': 0, 'moz_fold_libs%': 0, 'moz_folded_library_name%': '', - 'ssl_enable_zlib%': 1, 'sanitizer_flags%': 0, 'test_build%': 0, 'no_zdefs%': 0, @@ -106,9 +105,11 @@ 'sign_libs%': 1, 'use_pprof%': 0, 'ct_verif%': 0, + 'emit_llvm%': 0, 'nss_public_dist_dir%': '<(nss_dist_dir)/public', 'nss_private_dist_dir%': '<(nss_dist_dir)/private', 'only_dev_random%': 1, + 'disable_fips%': 1, }, 'target_defaults': { # Settings specific to targets should go here. @@ -125,6 +126,12 @@ '<(nss_dist_dir)/private/<(module)', ], 'conditions': [ + [ 'disable_fips==1', { + 'defines': [ + 'NSS_FIPS_DISABLED', + 'NSS_NO_INIT_SUPPORT', + ], + }], [ 'OS!="android" and OS!="mac" and OS!="win"', { 'libraries': [ '-lpthread', @@ -167,7 +174,7 @@ }, }, }], - [ 'target_arch=="arm64" or target_arch=="aarch64"', { + [ 'target_arch=="arm64" or target_arch=="aarch64" or target_arch=="sparc64" or target_arch=="ppc64" or target_arch=="ppc64le" or target_arch=="s390x" or target_arch=="mips64"', { 'defines': [ 'NSS_USE_64', ], @@ -294,7 +301,6 @@ 'Common': { 'abstract': 1, 'defines': [ - 'NSS_NO_INIT_SUPPORT', 'USE_UTIL_DIRECTLY', 'NO_NSPR_10_SUPPORT', 'SSL_DISABLE_DEPRECATED_CIPHER_SUITE_NAMES', @@ -426,6 +432,10 @@ 'LIBRARY_SEARCH_PATHS': ['/usr/lib <(sanitizer_flags)'], }, }], + [ 'emit_llvm==1', { + 'cflags': ['-flto'], + 'ldflags': ['-flto', '-fuse-ld=gold', '-Wl,-plugin-opt=save-temps'], + }], [ 'OS=="android" and mozilla_client==0', { 'defines': [ 'NO_SYSINFO', diff --git a/security/nss/coreconf/config.mk b/security/nss/coreconf/config.mk index 09b733d5c..55d95c30e 100644 --- a/security/nss/coreconf/config.mk +++ b/security/nss/coreconf/config.mk @@ -146,10 +146,6 @@ endif # [16.0] Global environ ment defines ####################################################################### -ifdef NSS_DISABLE_ECC -DEFINES += -DNSS_DISABLE_ECC -endif - ifdef NSS_ALLOW_UNSUPPORTED_CRITICAL DEFINES += -DNSS_ALLOW_UNSUPPORTED_CRITICAL endif @@ -176,7 +172,7 @@ endif # FIPS support requires startup tests to be executed at load time of shared modules. # For performance reasons, these tests are disabled by default. -# When compiling binaries that must support FIPS mode, +# When compiling binaries that must support FIPS mode, # you should define NSS_FORCE_FIPS # # NSS_NO_INIT_SUPPORT is always defined on platforms that don't support @@ -203,8 +199,3 @@ DEFINES += -DNO_NSPR_10_SUPPORT # Hide old, deprecated, TLS cipher suite names when building NSS DEFINES += -DSSL_DISABLE_DEPRECATED_CIPHER_SUITE_NAMES - -# Mozilla's mozilla/modules/zlib/src/zconf.h adds the MOZ_Z_ prefix to zlib -# exported symbols, which causes problem when NSS is built as part of Mozilla. -# So we add a NSS_SSL_ENABLE_ZLIB variable to allow Mozilla to turn this off. -NSS_SSL_ENABLE_ZLIB = 1 diff --git a/security/nss/coreconf/coreconf.dep b/security/nss/coreconf/coreconf.dep index 590d1bfae..5182f7555 100644 --- a/security/nss/coreconf/coreconf.dep +++ b/security/nss/coreconf/coreconf.dep @@ -10,4 +10,3 @@ */ #error "Do not include this header file." - diff --git a/security/nss/coreconf/werror.py b/security/nss/coreconf/werror.py index 0d3843f64..c469c4002 100644 --- a/security/nss/coreconf/werror.py +++ b/security/nss/coreconf/werror.py @@ -24,7 +24,7 @@ def main(): # If we aren't clang, make sure we have gcc 4.8 at least if not cc_is_clang: try: - v = subprocess.check_output([cc, '-dumpversion'], stderr=sink) + v = subprocess.check_output([cc, '-dumpversion'], stderr=sink).decode("utf-8") v = v.strip(' \r\n').split('.') v = list(map(int, v)) if v[0] < 4 or (v[0] == 4 and v[1] < 8): diff --git a/security/nss/cpputil/.clang-format b/security/nss/cpputil/.clang-format new file mode 100644 index 000000000..06e3c5115 --- /dev/null +++ b/security/nss/cpputil/.clang-format @@ -0,0 +1,4 @@ +--- +Language: Cpp +BasedOnStyle: Google +... diff --git a/security/nss/cpputil/Makefile b/security/nss/cpputil/Makefile new file mode 100644 index 000000000..7adfc6117 --- /dev/null +++ b/security/nss/cpputil/Makefile @@ -0,0 +1,49 @@ +#! gmake +# +# 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/. + +####################################################################### +# (1) Include initial platform-independent assignments (MANDATORY). # +####################################################################### + +include manifest.mn + +####################################################################### +# (2) Include "global" configuration information. (OPTIONAL) # +####################################################################### + +include $(CORE_DEPTH)/coreconf/config.mk + +####################################################################### +# (3) Include "component" configuration information. (OPTIONAL) # +####################################################################### + +ifeq (WINNT,$(OS_ARCH)) +OS_CFLAGS += -EHsc +else +CXXFLAGS += -std=c++0x +endif + +####################################################################### +# (4) Include "local" platform-dependent assignments (OPTIONAL). # +####################################################################### + +include config.mk + +####################################################################### +# (5) Execute "global" rules. (OPTIONAL) # +####################################################################### + +include $(CORE_DEPTH)/coreconf/rules.mk + +####################################################################### +# (6) Execute "component" rules. (OPTIONAL) # +####################################################################### + + + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### diff --git a/security/nss/cpputil/README b/security/nss/cpputil/README new file mode 100644 index 000000000..22297dd33 --- /dev/null +++ b/security/nss/cpputil/README @@ -0,0 +1,11 @@ +###################################### +## PLEASE READ BEFORE USING CPPUTIL ## +###################################### + +This is a static library supposed to be mainly used by NSS internally. We use +it for testing, fuzzing, and a few new tools written in C++ that we're +experimenting with. + +You might find it handy to use for your own projects but please be aware that +we will make no promises your application won't break in the future. We will +provide no support if you decide to link against it. diff --git a/security/nss/cpputil/config.mk b/security/nss/cpputil/config.mk new file mode 100644 index 000000000..b8c03de79 --- /dev/null +++ b/security/nss/cpputil/config.mk @@ -0,0 +1,15 @@ +# +# 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/. + +# +# 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/cpputil/cpputil.gyp b/security/nss/cpputil/cpputil.gyp new file mode 100644 index 000000000..5042acf5c --- /dev/null +++ b/security/nss/cpputil/cpputil.gyp @@ -0,0 +1,29 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +{ + 'includes': [ + '../coreconf/config.gypi', + ], + 'targets': [ + { + 'target_name': 'cpputil', + 'type': 'static_library', + 'sources': [ + 'databuffer.cc', + 'dummy_io.cc', + 'dummy_io_fwd.cc', + 'tls_parser.cc', + ], + 'dependencies': [ + '<(DEPTH)/exports.gyp:nss_exports', + ], + 'direct_dependent_settings': { + 'include_dirs': [ + '<(DEPTH)/cpputil', + ], + }, + }, + ], +} + diff --git a/security/nss/cpputil/cpputil.h b/security/nss/cpputil/cpputil.h new file mode 100644 index 000000000..017ce9bfc --- /dev/null +++ b/security/nss/cpputil/cpputil.h @@ -0,0 +1,12 @@ +/* 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 cpputil_h__ +#define cpputil_h__ + +static unsigned char* toUcharPtr(const uint8_t* v) { + return const_cast<unsigned char*>(static_cast<const unsigned char*>(v)); +} + +#endif // cpputil_h__ diff --git a/security/nss/cpputil/databuffer.cc b/security/nss/cpputil/databuffer.cc new file mode 100644 index 000000000..d60ebccb3 --- /dev/null +++ b/security/nss/cpputil/databuffer.cc @@ -0,0 +1,127 @@ +/* -*- 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 "databuffer.h" +#include <algorithm> +#include <cassert> +#include <cstring> +#include <iomanip> +#include <iostream> +#if defined(WIN32) || defined(WIN64) +#include <winsock2.h> +#else +#include <arpa/inet.h> +#endif + +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); + } else { + assert(len == 0); + data_ = nullptr; + len_ = 0; + } +} + +// Write will do a new allocation and expand the size of the buffer if needed. +// Returns the offset of the end of the write. +size_t DataBuffer::Write(size_t index, const uint8_t* val, size_t count) { + assert(val); + if (index + count > len_) { + size_t newlen = index + count; + uint8_t* tmp = new uint8_t[newlen]; // Always > 0. + if (data_) { + memcpy(static_cast<void*>(tmp), static_cast<const void*>(data_), len_); + } + if (index > len_) { + memset(static_cast<void*>(tmp + len_), 0, index - len_); + } + delete[] data_; + data_ = tmp; + len_ = newlen; + } + if (data_) { + memcpy(static_cast<void*>(data_ + index), static_cast<const void*>(val), + count); + } + return index + count; +} + +// Write an integer, also performing host-to-network order conversion. +// Returns the offset of the end of the write. +size_t DataBuffer::Write(size_t index, uint32_t val, size_t count) { + assert(count <= sizeof(uint32_t)); + uint32_t nvalue = htonl(val); + auto* addr = reinterpret_cast<const uint8_t*>(&nvalue); + return Write(index, addr + sizeof(uint32_t) - count, count); +} + +void DataBuffer::Splice(const uint8_t* ins, size_t ins_len, size_t index, + size_t remove) { + assert(ins); + uint8_t* old_value = data_; + size_t old_len = len_; + + // The amount of stuff remaining from the tail of the old. + size_t tail_len = old_len - (std::min)(old_len, index + remove); + // The new length: the head of the old, the new, and the tail of the old. + len_ = index + ins_len + tail_len; + data_ = new uint8_t[len_ ? len_ : 1]; + + // The head of the old. + if (old_value) { + Write(0, old_value, (std::min)(old_len, index)); + } + // Maybe a gap. + if (old_value && index > old_len) { + memset(old_value + index, 0, index - old_len); + } + // The new. + Write(index, ins, ins_len); + // The tail of the old. + if (tail_len > 0) { + Write(index + ins_len, old_value + index + remove, tail_len); + } + + delete[] old_value; +} + +// This can't use the same trick as Write(), since we might be reading from a +// smaller data source. +bool DataBuffer::Read(size_t index, size_t count, uint64_t* val) const { + assert(count <= sizeof(uint64_t)); + assert(val); + if ((index > len()) || (count > (len() - index))) { + return false; + } + *val = 0; + for (size_t i = 0; i < count; ++i) { + *val = (*val << 8) | data()[index + i]; + } + return true; +} + +bool DataBuffer::Read(size_t index, size_t count, uint32_t* val) const { + assert(count <= sizeof(uint32_t)); + uint64_t tmp; + + if (!Read(index, count, &tmp)) { + return false; + } + *val = tmp & 0xffffffff; + return true; +} + +size_t DataBuffer::logging_limit = 32; + +/* static */ void DataBuffer::SetLogLimit(size_t limit) { + DataBuffer::logging_limit = limit; +} + +} // namespace nss_test diff --git a/security/nss/cpputil/databuffer.h b/security/nss/cpputil/databuffer.h new file mode 100644 index 000000000..58e07efe1 --- /dev/null +++ b/security/nss/cpputil/databuffer.h @@ -0,0 +1,110 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef databuffer_h__ +#define databuffer_h__ + +#include <algorithm> +#include <cstring> +#include <iomanip> +#include <iostream> + +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 DataBuffer& other) : data_(nullptr), len_(0) { + Assign(other); + } + ~DataBuffer() { delete[] data_; } + + DataBuffer& operator=(const DataBuffer& other) { + if (&other != this) { + Assign(other); + } + return *this; + } + + void Allocate(size_t len) { + delete[] data_; + data_ = new uint8_t[len ? len : 1]; // Don't depend on new [0]. + len_ = len; + } + + void Truncate(size_t len) { len_ = (std::min)(len_, len); } + + void Assign(const DataBuffer& other) { Assign(other.data(), other.len()); } + + void Assign(const uint8_t* data, size_t len); + + // Write will do a new allocation and expand the size of the buffer if needed. + // Returns the offset of the end of the write. + size_t Write(size_t index, const uint8_t* val, size_t count); + size_t Write(size_t index, const DataBuffer& buf) { + return Write(index, buf.data(), buf.len()); + } + + // Write an integer, also performing host-to-network order conversion. + // Returns the offset of the end of the write. + size_t Write(size_t index, uint32_t val, size_t count); + + // Starting at |index|, remove |remove| bytes and replace them with the + // contents of |buf|. + void Splice(const DataBuffer& buf, size_t index, size_t remove = 0) { + Splice(buf.data(), buf.len(), index, remove); + } + + void Splice(const uint8_t* ins, size_t ins_len, size_t index, + size_t remove = 0); + void Append(const DataBuffer& buf) { Splice(buf, len_); } + + bool Read(size_t index, size_t count, uint64_t* val) const; + bool Read(size_t index, size_t count, uint32_t* val) const; + + const uint8_t* data() const { return data_; } + uint8_t* data() { return data_; } + size_t len() const { return len_; } + bool empty() const { return len_ == 0; } + + static void SetLogLimit(size_t limit); + friend std::ostream& operator<<(std::ostream& stream, const DataBuffer& buf); + + private: + static size_t logging_limit; + uint8_t* data_; + size_t len_; +}; + +inline std::ostream& operator<<(std::ostream& stream, const DataBuffer& buf) { + stream << "[" << buf.len() << "] "; + for (size_t i = 0; i < buf.len(); ++i) { + if (i >= DataBuffer::logging_limit) { + stream << "..."; + break; + } + stream << std::hex << std::setfill('0') << std::setw(2) + << static_cast<unsigned>(buf.data()[i]); + } + stream << std::dec; + return stream; +} + +inline bool operator==(const DataBuffer& a, const DataBuffer& b) { + return (a.empty() && b.empty()) || + (a.len() == b.len() && 0 == memcmp(a.data(), b.data(), a.len())); +} + +inline bool operator!=(const DataBuffer& a, const DataBuffer& b) { + return !(a == b); +} + +} // namespace nss_test + +#endif diff --git a/security/nss/cpputil/dummy_io.cc b/security/nss/cpputil/dummy_io.cc new file mode 100644 index 000000000..ef45db833 --- /dev/null +++ b/security/nss/cpputil/dummy_io.cc @@ -0,0 +1,225 @@ +/* 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 <assert.h> +#include <iostream> + +#include "prerror.h" +#include "prio.h" + +#include "dummy_io.h" + +#define UNIMPLEMENTED() \ + std::cerr << "Unimplemented: " << __FUNCTION__ << std::endl; \ + assert(false); + +extern const struct PRIOMethods DummyMethodsForward; + +ScopedPRFileDesc DummyIOLayerMethods::CreateFD(PRDescIdentity id, + DummyIOLayerMethods *methods) { + ScopedPRFileDesc fd(PR_CreateIOLayerStub(id, &DummyMethodsForward)); + assert(fd); + if (!fd) { + return nullptr; + } + fd->secret = reinterpret_cast<PRFilePrivate *>(methods); + return fd; +} + +PRStatus DummyIOLayerMethods::Close(PRFileDesc *f) { + f->secret = nullptr; + f->dtor(f); + return PR_SUCCESS; +} + +int32_t DummyIOLayerMethods::Read(PRFileDesc *f, void *buf, int32_t length) { + UNIMPLEMENTED(); + return -1; +} + +int32_t DummyIOLayerMethods::Write(PRFileDesc *f, const void *buf, + int32_t length) { + UNIMPLEMENTED(); + return -1; +} + +int32_t DummyIOLayerMethods::Available(PRFileDesc *f) { + UNIMPLEMENTED(); + return -1; +} + +int64_t DummyIOLayerMethods::Available64(PRFileDesc *f) { + UNIMPLEMENTED(); + return -1; +} + +PRStatus DummyIOLayerMethods::Sync(PRFileDesc *f) { + UNIMPLEMENTED(); + return PR_FAILURE; +} + +int32_t DummyIOLayerMethods::Seek(PRFileDesc *f, int32_t offset, + PRSeekWhence how) { + UNIMPLEMENTED(); + return -1; +} + +int64_t DummyIOLayerMethods::Seek64(PRFileDesc *f, int64_t offset, + PRSeekWhence how) { + UNIMPLEMENTED(); + return -1; +} + +PRStatus DummyIOLayerMethods::FileInfo(PRFileDesc *f, PRFileInfo *info) { + UNIMPLEMENTED(); + return PR_FAILURE; +} + +PRStatus DummyIOLayerMethods::FileInfo64(PRFileDesc *f, PRFileInfo64 *info) { + UNIMPLEMENTED(); + return PR_FAILURE; +} + +int32_t DummyIOLayerMethods::Writev(PRFileDesc *f, const PRIOVec *iov, + int32_t iov_size, PRIntervalTime to) { + UNIMPLEMENTED(); + return -1; +} + +PRStatus DummyIOLayerMethods::Connect(PRFileDesc *f, const PRNetAddr *addr, + PRIntervalTime to) { + UNIMPLEMENTED(); + return PR_FAILURE; +} + +PRFileDesc *DummyIOLayerMethods::Accept(PRFileDesc *sd, PRNetAddr *addr, + PRIntervalTime to) { + UNIMPLEMENTED(); + return nullptr; +} + +PRStatus DummyIOLayerMethods::Bind(PRFileDesc *f, const PRNetAddr *addr) { + UNIMPLEMENTED(); + return PR_FAILURE; +} + +PRStatus DummyIOLayerMethods::Listen(PRFileDesc *f, int32_t depth) { + UNIMPLEMENTED(); + return PR_FAILURE; +} + +PRStatus DummyIOLayerMethods::Shutdown(PRFileDesc *f, int32_t how) { + return PR_SUCCESS; +} + +int32_t DummyIOLayerMethods::Recv(PRFileDesc *f, void *buf, int32_t buflen, + int32_t flags, PRIntervalTime to) { + UNIMPLEMENTED(); + return -1; +} + +// Note: this is always nonblocking and assumes a zero timeout. +int32_t DummyIOLayerMethods::Send(PRFileDesc *f, const void *buf, + int32_t amount, int32_t flags, + PRIntervalTime to) { + return Write(f, buf, amount); +} + +int32_t DummyIOLayerMethods::Recvfrom(PRFileDesc *f, void *buf, int32_t amount, + int32_t flags, PRNetAddr *addr, + PRIntervalTime to) { + UNIMPLEMENTED(); + return -1; +} + +int32_t DummyIOLayerMethods::Sendto(PRFileDesc *f, const void *buf, + int32_t amount, int32_t flags, + const PRNetAddr *addr, PRIntervalTime to) { + UNIMPLEMENTED(); + return -1; +} + +int16_t DummyIOLayerMethods::Poll(PRFileDesc *f, int16_t in_flags, + int16_t *out_flags) { + UNIMPLEMENTED(); + return -1; +} + +int32_t DummyIOLayerMethods::AcceptRead(PRFileDesc *sd, PRFileDesc **nd, + PRNetAddr **raddr, void *buf, + int32_t amount, PRIntervalTime t) { + UNIMPLEMENTED(); + return -1; +} + +int32_t DummyIOLayerMethods::TransmitFile(PRFileDesc *sd, PRFileDesc *f, + const void *headers, int32_t hlen, + PRTransmitFileFlags flags, + PRIntervalTime t) { + UNIMPLEMENTED(); + return -1; +} + +// TODO: Modify to return unique names for each channel +// somehow, as opposed to always the same static address. The current +// implementation messes up the session cache, which is why it's off +// elsewhere +PRStatus DummyIOLayerMethods::Getpeername(PRFileDesc *f, PRNetAddr *addr) { + addr->inet.family = PR_AF_INET; + addr->inet.port = 0; + addr->inet.ip = 0; + + return PR_SUCCESS; +} + +PRStatus DummyIOLayerMethods::Getsockname(PRFileDesc *f, PRNetAddr *addr) { + UNIMPLEMENTED(); + return PR_FAILURE; +} + +PRStatus DummyIOLayerMethods::Getsockoption(PRFileDesc *f, + PRSocketOptionData *opt) { + switch (opt->option) { + case PR_SockOpt_Nonblocking: + opt->value.non_blocking = PR_TRUE; + return PR_SUCCESS; + default: + UNIMPLEMENTED(); + break; + } + + return PR_FAILURE; +} + +PRStatus DummyIOLayerMethods::Setsockoption(PRFileDesc *f, + const PRSocketOptionData *opt) { + switch (opt->option) { + case PR_SockOpt_Nonblocking: + return PR_SUCCESS; + case PR_SockOpt_NoDelay: + return PR_SUCCESS; + default: + UNIMPLEMENTED(); + break; + } + + return PR_FAILURE; +} + +int32_t DummyIOLayerMethods::Sendfile(PRFileDesc *out, PRSendFileData *in, + PRTransmitFileFlags flags, + PRIntervalTime to) { + UNIMPLEMENTED(); + return -1; +} + +PRStatus DummyIOLayerMethods::ConnectContinue(PRFileDesc *f, int16_t flags) { + UNIMPLEMENTED(); + return PR_FAILURE; +} + +int32_t DummyIOLayerMethods::Reserved(PRFileDesc *f) { + UNIMPLEMENTED(); + return -1; +} diff --git a/security/nss/cpputil/dummy_io.h b/security/nss/cpputil/dummy_io.h new file mode 100644 index 000000000..797ac6113 --- /dev/null +++ b/security/nss/cpputil/dummy_io.h @@ -0,0 +1,62 @@ +/* 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 dummy_io_h__ +#define dummy_io_h__ + +#include "prerror.h" +#include "prio.h" + +#include "scoped_ptrs.h" + +class DummyIOLayerMethods { + public: + static ScopedPRFileDesc CreateFD(PRDescIdentity id, + DummyIOLayerMethods *methods); + + virtual PRStatus Close(PRFileDesc *f); + virtual int32_t Read(PRFileDesc *f, void *buf, int32_t length); + virtual int32_t Write(PRFileDesc *f, const void *buf, int32_t length); + virtual int32_t Available(PRFileDesc *f); + virtual int64_t Available64(PRFileDesc *f); + virtual PRStatus Sync(PRFileDesc *f); + virtual int32_t Seek(PRFileDesc *f, int32_t offset, PRSeekWhence how); + virtual int64_t Seek64(PRFileDesc *f, int64_t offset, PRSeekWhence how); + virtual PRStatus FileInfo(PRFileDesc *f, PRFileInfo *info); + virtual PRStatus FileInfo64(PRFileDesc *f, PRFileInfo64 *info); + virtual int32_t Writev(PRFileDesc *f, const PRIOVec *iov, int32_t iov_size, + PRIntervalTime to); + virtual PRStatus Connect(PRFileDesc *f, const PRNetAddr *addr, + PRIntervalTime to); + virtual PRFileDesc *Accept(PRFileDesc *sd, PRNetAddr *addr, + PRIntervalTime to); + virtual PRStatus Bind(PRFileDesc *f, const PRNetAddr *addr); + virtual PRStatus Listen(PRFileDesc *f, int32_t depth); + virtual PRStatus Shutdown(PRFileDesc *f, int32_t how); + virtual int32_t Recv(PRFileDesc *f, void *buf, int32_t buflen, int32_t flags, + PRIntervalTime to); + virtual int32_t Send(PRFileDesc *f, const void *buf, int32_t amount, + int32_t flags, PRIntervalTime to); + virtual int32_t Recvfrom(PRFileDesc *f, void *buf, int32_t amount, + int32_t flags, PRNetAddr *addr, PRIntervalTime to); + virtual int32_t Sendto(PRFileDesc *f, const void *buf, int32_t amount, + int32_t flags, const PRNetAddr *addr, + PRIntervalTime to); + virtual int16_t Poll(PRFileDesc *f, int16_t in_flags, int16_t *out_flags); + virtual int32_t AcceptRead(PRFileDesc *sd, PRFileDesc **nd, PRNetAddr **raddr, + void *buf, int32_t amount, PRIntervalTime t); + virtual int32_t TransmitFile(PRFileDesc *sd, PRFileDesc *f, + const void *headers, int32_t hlen, + PRTransmitFileFlags flags, PRIntervalTime t); + virtual PRStatus Getpeername(PRFileDesc *f, PRNetAddr *addr); + virtual PRStatus Getsockname(PRFileDesc *f, PRNetAddr *addr); + virtual PRStatus Getsockoption(PRFileDesc *f, PRSocketOptionData *opt); + virtual PRStatus Setsockoption(PRFileDesc *f, const PRSocketOptionData *opt); + virtual int32_t Sendfile(PRFileDesc *out, PRSendFileData *in, + PRTransmitFileFlags flags, PRIntervalTime to); + virtual PRStatus ConnectContinue(PRFileDesc *f, int16_t flags); + virtual int32_t Reserved(PRFileDesc *f); +}; + +#endif // dummy_io_h__ diff --git a/security/nss/cpputil/dummy_io_fwd.cc b/security/nss/cpputil/dummy_io_fwd.cc new file mode 100644 index 000000000..5e53d9e1b --- /dev/null +++ b/security/nss/cpputil/dummy_io_fwd.cc @@ -0,0 +1,162 @@ +/* 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 "prio.h" + +#include "dummy_io.h" + +static DummyIOLayerMethods *ToMethods(PRFileDesc *f) { + return reinterpret_cast<DummyIOLayerMethods *>(f->secret); +} + +static PRStatus DummyClose(PRFileDesc *f) { return ToMethods(f)->Close(f); } + +static int32_t DummyRead(PRFileDesc *f, void *buf, int32_t length) { + return ToMethods(f)->Read(f, buf, length); +} + +static int32_t DummyWrite(PRFileDesc *f, const void *buf, int32_t length) { + return ToMethods(f)->Write(f, buf, length); +} + +static int32_t DummyAvailable(PRFileDesc *f) { + return ToMethods(f)->Available(f); +} + +static int64_t DummyAvailable64(PRFileDesc *f) { + return ToMethods(f)->Available64(f); +} + +static PRStatus DummySync(PRFileDesc *f) { return ToMethods(f)->Sync(f); } + +static int32_t DummySeek(PRFileDesc *f, int32_t offset, PRSeekWhence how) { + return ToMethods(f)->Seek(f, offset, how); +} + +static int64_t DummySeek64(PRFileDesc *f, int64_t offset, PRSeekWhence how) { + return ToMethods(f)->Seek64(f, offset, how); +} + +static PRStatus DummyFileInfo(PRFileDesc *f, PRFileInfo *info) { + return ToMethods(f)->FileInfo(f, info); +} + +static PRStatus DummyFileInfo64(PRFileDesc *f, PRFileInfo64 *info) { + return ToMethods(f)->FileInfo64(f, info); +} + +static int32_t DummyWritev(PRFileDesc *f, const PRIOVec *iov, int32_t iov_size, + PRIntervalTime to) { + return ToMethods(f)->Writev(f, iov, iov_size, to); +} + +static PRStatus DummyConnect(PRFileDesc *f, const PRNetAddr *addr, + PRIntervalTime to) { + return ToMethods(f)->Connect(f, addr, to); +} + +static PRFileDesc *DummyAccept(PRFileDesc *f, PRNetAddr *addr, + PRIntervalTime to) { + return ToMethods(f)->Accept(f, addr, to); +} + +static PRStatus DummyBind(PRFileDesc *f, const PRNetAddr *addr) { + return ToMethods(f)->Bind(f, addr); +} + +static PRStatus DummyListen(PRFileDesc *f, int32_t depth) { + return ToMethods(f)->Listen(f, depth); +} + +static PRStatus DummyShutdown(PRFileDesc *f, int32_t how) { + return ToMethods(f)->Shutdown(f, how); +} + +static int32_t DummyRecv(PRFileDesc *f, void *buf, int32_t buflen, + int32_t flags, PRIntervalTime to) { + return ToMethods(f)->Recv(f, buf, buflen, flags, to); +} + +static int32_t DummySend(PRFileDesc *f, const void *buf, int32_t amount, + int32_t flags, PRIntervalTime to) { + return ToMethods(f)->Send(f, buf, amount, flags, to); +} + +static int32_t DummyRecvfrom(PRFileDesc *f, void *buf, int32_t amount, + int32_t flags, PRNetAddr *addr, + PRIntervalTime to) { + return ToMethods(f)->Recvfrom(f, buf, amount, flags, addr, to); +} + +static int32_t DummySendto(PRFileDesc *f, const void *buf, int32_t amount, + int32_t flags, const PRNetAddr *addr, + PRIntervalTime to) { + return ToMethods(f)->Sendto(f, buf, amount, flags, addr, to); +} + +static int16_t DummyPoll(PRFileDesc *f, int16_t in_flags, int16_t *out_flags) { + return ToMethods(f)->Poll(f, in_flags, out_flags); +} + +static int32_t DummyAcceptRead(PRFileDesc *f, PRFileDesc **nd, + PRNetAddr **raddr, void *buf, int32_t amount, + PRIntervalTime t) { + return ToMethods(f)->AcceptRead(f, nd, raddr, buf, amount, t); +} + +static int32_t DummyTransmitFile(PRFileDesc *sd, PRFileDesc *f, + const void *headers, int32_t hlen, + PRTransmitFileFlags flags, PRIntervalTime t) { + return ToMethods(f)->TransmitFile(sd, f, headers, hlen, flags, t); +} + +static PRStatus DummyGetpeername(PRFileDesc *f, PRNetAddr *addr) { + return ToMethods(f)->Getpeername(f, addr); +} + +static PRStatus DummyGetsockname(PRFileDesc *f, PRNetAddr *addr) { + return ToMethods(f)->Getsockname(f, addr); +} + +static PRStatus DummyGetsockoption(PRFileDesc *f, PRSocketOptionData *opt) { + return ToMethods(f)->Getsockoption(f, opt); +} + +static PRStatus DummySetsockoption(PRFileDesc *f, + const PRSocketOptionData *opt) { + return ToMethods(f)->Setsockoption(f, opt); +} + +static int32_t DummySendfile(PRFileDesc *f, PRSendFileData *in, + PRTransmitFileFlags flags, PRIntervalTime to) { + return ToMethods(f)->Sendfile(f, in, flags, to); +} + +static PRStatus DummyConnectContinue(PRFileDesc *f, int16_t flags) { + return ToMethods(f)->ConnectContinue(f, flags); +} + +static int32_t DummyReserved(PRFileDesc *f) { + return ToMethods(f)->Reserved(f); +} + +extern const struct PRIOMethods DummyMethodsForward = { + PR_DESC_LAYERED, DummyClose, + DummyRead, DummyWrite, + DummyAvailable, DummyAvailable64, + DummySync, DummySeek, + DummySeek64, DummyFileInfo, + DummyFileInfo64, DummyWritev, + DummyConnect, DummyAccept, + DummyBind, DummyListen, + DummyShutdown, DummyRecv, + DummySend, DummyRecvfrom, + DummySendto, DummyPoll, + DummyAcceptRead, DummyTransmitFile, + DummyGetsockname, DummyGetpeername, + DummyReserved, DummyReserved, + DummyGetsockoption, DummySetsockoption, + DummySendfile, DummyConnectContinue, + DummyReserved, DummyReserved, + DummyReserved, DummyReserved}; diff --git a/security/nss/cpputil/manifest.mn b/security/nss/cpputil/manifest.mn new file mode 100644 index 000000000..b3ccad8b5 --- /dev/null +++ b/security/nss/cpputil/manifest.mn @@ -0,0 +1,24 @@ +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +CORE_DEPTH = .. +DEPTH = .. + +MODULE = nss +LIBRARY_NAME = cpputil + +ifeq ($(NSS_BUILD_UTIL_ONLY),1) +CPPSRCS = \ + $(NULL) +else +CPPSRCS = \ + databuffer.cc \ + dummy_io.cc \ + dummy_io_fwd.cc \ + tls_parser.cc \ + $(NULL) +endif + +EXPORTS = \ + $(NULL) diff --git a/security/nss/cpputil/scoped_ptrs.h b/security/nss/cpputil/scoped_ptrs.h new file mode 100644 index 000000000..8a0b4f5ab --- /dev/null +++ b/security/nss/cpputil/scoped_ptrs.h @@ -0,0 +1,84 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef scoped_ptrs_h__ +#define scoped_ptrs_h__ + +#include <memory> +#include "cert.h" +#include "keyhi.h" +#include "p12.h" +#include "pk11pub.h" +#include "pkcs11uri.h" +#include "sslexp.h" + +struct ScopedDelete { + void operator()(CERTCertificate* cert) { CERT_DestroyCertificate(cert); } + void operator()(CERTCertificateList* list) { + CERT_DestroyCertificateList(list); + } + void operator()(CERTName* name) { CERT_DestroyName(name); } + void operator()(CERTCertList* list) { CERT_DestroyCertList(list); } + void operator()(CERTSubjectPublicKeyInfo* spki) { + SECKEY_DestroySubjectPublicKeyInfo(spki); + } + void operator()(PK11SlotInfo* slot) { PK11_FreeSlot(slot); } + void operator()(PK11SymKey* key) { PK11_FreeSymKey(key); } + void operator()(PRFileDesc* fd) { PR_Close(fd); } + void operator()(SECAlgorithmID* id) { SECOID_DestroyAlgorithmID(id, true); } + void operator()(SECItem* item) { SECITEM_FreeItem(item, true); } + void operator()(SECKEYPublicKey* key) { SECKEY_DestroyPublicKey(key); } + void operator()(SECKEYPrivateKey* key) { SECKEY_DestroyPrivateKey(key); } + void operator()(SECKEYPrivateKeyList* list) { + SECKEY_DestroyPrivateKeyList(list); + } + void operator()(PK11URI* uri) { PK11URI_DestroyURI(uri); } + void operator()(PLArenaPool* arena) { PORT_FreeArena(arena, PR_FALSE); } + void operator()(PK11Context* context) { PK11_DestroyContext(context, true); } + void operator()(PK11GenericObject* obj) { PK11_DestroyGenericObject(obj); } + void operator()(SSLResumptionTokenInfo* token) { + SSL_DestroyResumptionTokenInfo(token); + } + void operator()(SEC_PKCS12DecoderContext* dcx) { + SEC_PKCS12DecoderFinish(dcx); + } +}; + +template <class T> +struct ScopedMaybeDelete { + void operator()(T* ptr) { + if (ptr) { + ScopedDelete del; + del(ptr); + } + } +}; + +#define SCOPED(x) typedef std::unique_ptr<x, ScopedMaybeDelete<x> > Scoped##x + +SCOPED(CERTCertificate); +SCOPED(CERTCertificateList); +SCOPED(CERTCertList); +SCOPED(CERTName); +SCOPED(CERTSubjectPublicKeyInfo); +SCOPED(PK11SlotInfo); +SCOPED(PK11SymKey); +SCOPED(PRFileDesc); +SCOPED(SECAlgorithmID); +SCOPED(SECItem); +SCOPED(SECKEYPublicKey); +SCOPED(SECKEYPrivateKey); +SCOPED(SECKEYPrivateKeyList); +SCOPED(PK11URI); +SCOPED(PLArenaPool); +SCOPED(PK11Context); +SCOPED(PK11GenericObject); +SCOPED(SSLResumptionTokenInfo); +SCOPED(SEC_PKCS12DecoderContext); + +#undef SCOPED + +#endif // scoped_ptrs_h__ diff --git a/security/nss/cpputil/scoped_ptrs_util.h b/security/nss/cpputil/scoped_ptrs_util.h new file mode 100644 index 000000000..2dbf34e1d --- /dev/null +++ b/security/nss/cpputil/scoped_ptrs_util.h @@ -0,0 +1,39 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef scoped_ptrs_util_h__ +#define scoped_ptrs_util_h__ + +#include <memory> +#include "pkcs11uri.h" +#include "secoid.h" + +struct ScopedDelete { + void operator()(SECAlgorithmID* id) { SECOID_DestroyAlgorithmID(id, true); } + void operator()(SECItem* item) { SECITEM_FreeItem(item, true); } + void operator()(PK11URI* uri) { PK11URI_DestroyURI(uri); } + void operator()(PLArenaPool* arena) { PORT_FreeArena(arena, PR_FALSE); } +}; + +template <class T> +struct ScopedMaybeDelete { + void operator()(T* ptr) { + if (ptr) { + ScopedDelete del; + del(ptr); + } + } +}; + +#define SCOPED(x) typedef std::unique_ptr<x, ScopedMaybeDelete<x> > Scoped##x + +SCOPED(SECAlgorithmID); +SCOPED(SECItem); +SCOPED(PK11URI); + +#undef SCOPED + +#endif // scoped_ptrs_util_h__ diff --git a/security/nss/cpputil/tls_parser.cc b/security/nss/cpputil/tls_parser.cc new file mode 100644 index 000000000..e4c06aa91 --- /dev/null +++ b/security/nss/cpputil/tls_parser.cc @@ -0,0 +1,73 @@ +/* -*- 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 "tls_parser.h" + +namespace nss_test { + +bool TlsParser::Read(uint8_t* val) { + if (remaining() < 1) { + return false; + } + *val = *ptr(); + consume(1); + return true; +} + +bool TlsParser::Read(uint32_t* val, size_t size) { + if (size > sizeof(uint32_t)) { + return false; + } + + uint32_t v = 0; + for (size_t i = 0; i < size; ++i) { + uint8_t tmp; + if (!Read(&tmp)) { + return false; + } + + v = (v << 8) | tmp; + } + + *val = v; + return true; +} + +bool TlsParser::Read(DataBuffer* val, size_t len) { + if (remaining() < len) { + return false; + } + + val->Assign(ptr(), len); + consume(len); + return true; +} + +bool TlsParser::ReadVariable(DataBuffer* val, size_t len_size) { + uint32_t len; + if (!Read(&len, len_size)) { + return false; + } + return Read(val, len); +} + +bool TlsParser::Skip(size_t len) { + if (len > remaining()) { + return false; + } + consume(len); + return true; +} + +bool TlsParser::SkipVariable(size_t len_size) { + uint32_t len; + if (!Read(&len, len_size)) { + return false; + } + return Skip(len); +} + +} // namespace nss_test diff --git a/security/nss/cpputil/tls_parser.h b/security/nss/cpputil/tls_parser.h new file mode 100644 index 000000000..436c11e76 --- /dev/null +++ b/security/nss/cpputil/tls_parser.h @@ -0,0 +1,146 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef tls_parser_h_ +#define tls_parser_h_ + +#include <cstdint> +#include <cstring> +#include <memory> +#if defined(WIN32) || defined(WIN64) +#include <winsock2.h> +#else +#include <arpa/inet.h> +#endif +#include "databuffer.h" +#include "sslt.h" + +namespace nss_test { + +const uint8_t kTlsChangeCipherSpecType = 20; +const uint8_t kTlsAlertType = 21; +const uint8_t kTlsHandshakeType = 22; +const uint8_t kTlsApplicationDataType = 23; +const uint8_t kTlsAltHandshakeType = 24; +const uint8_t kTlsAckType = 25; + +const uint8_t kTlsHandshakeClientHello = 1; +const uint8_t kTlsHandshakeServerHello = 2; +const uint8_t kTlsHandshakeNewSessionTicket = 4; +const uint8_t kTlsHandshakeHelloRetryRequest = 6; +const uint8_t kTlsHandshakeEncryptedExtensions = 8; +const uint8_t kTlsHandshakeCertificate = 11; +const uint8_t kTlsHandshakeServerKeyExchange = 12; +const uint8_t kTlsHandshakeCertificateRequest = 13; +const uint8_t kTlsHandshakeCertificateVerify = 15; +const uint8_t kTlsHandshakeClientKeyExchange = 16; +const uint8_t kTlsHandshakeFinished = 20; + +const uint8_t kTlsAlertWarning = 1; +const uint8_t kTlsAlertFatal = 2; + +const uint8_t kTlsAlertCloseNotify = 0; +const uint8_t kTlsAlertUnexpectedMessage = 10; +const uint8_t kTlsAlertBadRecordMac = 20; +const uint8_t kTlsAlertRecordOverflow = 22; +const uint8_t kTlsAlertHandshakeFailure = 40; +const uint8_t kTlsAlertBadCertificate = 42; +const uint8_t kTlsAlertIllegalParameter = 47; +const uint8_t kTlsAlertDecodeError = 50; +const uint8_t kTlsAlertDecryptError = 51; +const uint8_t kTlsAlertProtocolVersion = 70; +const uint8_t kTlsAlertInternalError = 80; +const uint8_t kTlsAlertInappropriateFallback = 86; +const uint8_t kTlsAlertMissingExtension = 109; +const uint8_t kTlsAlertUnsupportedExtension = 110; +const uint8_t kTlsAlertUnrecognizedName = 112; +const uint8_t kTlsAlertNoApplicationProtocol = 120; + +const uint8_t kTlsFakeChangeCipherSpec[] = { + kTlsChangeCipherSpecType, // Type + 0xfe, + 0xff, // Version + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x10, // Fictitious sequence # + 0x00, + 0x01, // Length + 0x01 // Value +}; + +static const uint8_t kTls13PskKe = 0; +static const uint8_t kTls13PskDhKe = 1; +static const uint8_t kTls13PskAuth = 0; +static const uint8_t kTls13PskSignAuth = 1; + +inline std::ostream& operator<<(std::ostream& os, SSLProtocolVariant v) { + return os << ((v == ssl_variant_stream) ? "TLS" : "DTLS"); +} + +inline bool IsDtls(uint16_t version) { return (version & 0x8000) == 0x8000; } + +inline uint16_t NormalizeTlsVersion(uint16_t version) { + if (version == 0xfeff) { + return 0x0302; // special: DTLS 1.0 == TLS 1.1 + } + if (IsDtls(version)) { + return (version ^ 0xffff) + 0x0201; + } + return version; +} + +inline uint16_t TlsVersionToDtlsVersion(uint16_t version) { + if (version == 0x0302) { + return 0xfeff; + } + if (version == 0x0304) { + return version; + } + return 0xffff - version + 0x0201; +} + +inline size_t WriteVariable(DataBuffer* target, size_t index, + const DataBuffer& buf, size_t len_size) { + index = target->Write(index, static_cast<uint32_t>(buf.len()), len_size); + return target->Write(index, buf.data(), buf.len()); +} + +class TlsParser { + public: + TlsParser(const uint8_t* data, size_t len) : buffer_(data, len), offset_(0) {} + explicit TlsParser(const DataBuffer& buf) : buffer_(buf), offset_(0) {} + + bool Read(uint8_t* val); + // Read an integral type of specified width. + bool Read(uint32_t* val, size_t size); + // Reads len bytes into dest buffer, overwriting it. + bool Read(DataBuffer* dest, size_t len); + // 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); + + bool Skip(size_t len); + bool SkipVariable(size_t len_size); + + size_t consumed() const { return offset_; } + size_t remaining() const { return buffer_.len() - offset_; } + + private: + void consume(size_t len) { offset_ += len; } + const uint8_t* ptr() const { return buffer_.data() + offset_; } + + DataBuffer buffer_; + size_t offset_; +}; + +} // namespace nss_test + +#endif diff --git a/security/nss/doc/certutil.xml b/security/nss/doc/certutil.xml index 461b21389..4622c75e4 100644 --- a/security/nss/doc/certutil.xml +++ b/security/nss/doc/certutil.xml @@ -84,11 +84,11 @@ <varlistentry> <term>-F</term> - <listitem><para>Delete a private key from a key database. Specify the key to delete with the -n argument. Specify the database from which to delete the key with the -<option>-d</option> argument. Use the <option>-k</option> argument to specify explicitly whether to delete a DSA, RSA, or ECC key. If you don't use the <option>-k</option> argument, the option looks for an RSA key matching the specified nickname. + <listitem><para>Delete a private key and the associated certificate from a database. Specify the key to delete with the -n argument. Specify the database from which to delete the key with the +<option>-d</option> argument. </para> <para> -When you delete keys, be sure to also remove any certificates associated with those keys from the certificate database, by using -D. Some smart cards do not let you remove a public key you have generated. In such a case, only the private key is deleted from the key pair. You can display the public key with the command certutil -K -h tokenname. </para></listitem> +Some smart cards do not let you remove a public key you have generated. In such a case, only the private key is deleted from the key pair.</para></listitem> </varlistentry> <varlistentry> @@ -456,6 +456,16 @@ of the attribute codes: </varlistentry> <varlistentry> + <term>--pss</term> + <listitem><para>Restrict the generated certificate (with the <option>-S</option> option) or certificate request (with the <option>-R</option> option) to be used with the RSA-PSS signature scheme. This only works when the private key of the certificate or certificate request is RSA.</para></listitem> + </varlistentry> + + <varlistentry> + <term>--pss-sign</term> + <listitem><para>Sign the generated certificate with the RSA-PSS signature scheme (with the <option>-C</option> or <option>-S</option> option). This only works when the private key of the signer's certificate is RSA. If the signer's certificate is restricted to RSA-PSS, it is not necessary to specify this option.</para></listitem> + </varlistentry> + + <varlistentry> <term>-z noise-file</term> <listitem><para>Read a seed value from the specified file to generate a new private and public key pair. This argument makes it possible to use hardware-generated seed values or manually create a value from the keyboard. The minimum file size is 20 bytes.</para></listitem> </varlistentry> diff --git a/security/nss/doc/html/certutil.html b/security/nss/doc/html/certutil.html index eb2e94322..902d1309a 100644 --- a/security/nss/doc/html/certutil.html +++ b/security/nss/doc/html/certutil.html @@ -1,4 +1,4 @@ -<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>CERTUTIL</title><meta name="generator" content="DocBook XSL Stylesheets V1.78.1"><link rel="home" href="index.html" title="CERTUTIL"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">CERTUTIL</th></tr></table><hr></div><div class="refentry"><a name="certutil"></a><div class="titlepage"></div><div class="refnamediv"><h2>Name</h2><p>certutil — Manage keys and certificate in both NSS databases and other NSS tokens</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p><code class="command">certutil</code> [<em class="replaceable"><code>options</code></em>] [[<em class="replaceable"><code>arguments</code></em>]]</p></div></div><div class="refsection"><a name="idm139774553663312"></a><h2>STATUS</h2><p>This documentation is still work in progress. Please contribute to the initial review in <a class="ulink" href="https://bugzilla.mozilla.org/show_bug.cgi?id=836477" target="_top">Mozilla NSS bug 836477</a> +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>CERTUTIL</title><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot"><link rel="home" href="index.html" title="CERTUTIL"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">CERTUTIL</th></tr></table><hr></div><div class="refentry"><a name="certutil"></a><div class="titlepage"></div><div class="refnamediv"><h2>Name</h2><p>certutil — Manage keys and certificate in both NSS databases and other NSS tokens</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p><code class="command">certutil</code> [<em class="replaceable"><code>options</code></em>] [[<em class="replaceable"><code>arguments</code></em>]]</p></div></div><div class="refsection"><a name="idm140440587239488"></a><h2>STATUS</h2><p>This documentation is still work in progress. Please contribute to the initial review in <a class="ulink" href="https://bugzilla.mozilla.org/show_bug.cgi?id=836477" target="_top">Mozilla NSS bug 836477</a> </p></div><div class="refsection"><a name="description"></a><h2>Description</h2><p>The Certificate Database Tool, <span class="command"><strong>certutil</strong></span>, is a command-line utility that can create and modify certificate and key databases. It can specifically list, generate, modify, or delete certificates, create or change the password, generate new public and private key pairs, display the contents of the key database, or delete key pairs within the key database.</p><p>Certificate issuance, part of the key and certificate management process, requires that keys and certificates be created in the key database. This document discusses certificate and key database management. For information on the security module database management, see the <span class="command"><strong>modutil</strong></span> manpage.</p></div><div class="refsection"><a name="options"></a><h2>Command Options and Arguments</h2><p>Running <span class="command"><strong>certutil</strong></span> always requires one and only one command option to specify the type of certificate operation. Each command option may take zero or more arguments. The command option <code class="option">-H</code> will list all the command options and their relevant arguments.</p><p><span class="command"><strong>Command Options</strong></span></p><div class="variablelist"><dl class="variablelist"><dt><span class="term">-A </span></dt><dd><p>Add an existing certificate to a certificate database. The certificate database should already exist; if one is not present, this command option will initialize one by default.</p></dd><dt><span class="term">-B</span></dt><dd><p>Run a series of commands from the specified batch file. This requires the <code class="option">-i</code> argument.</p></dd><dt><span class="term">-C </span></dt><dd><p>Create a new binary certificate file from a binary certificate request file. Use the <code class="option">-i</code> argument to specify the certificate request file. If this argument is not used, <span class="command"><strong>certutil</strong></span> prompts for a filename. </p></dd><dt><span class="term">-D </span></dt><dd><p>Delete a certificate from the certificate database.</p></dd><dt><span class="term">--rename </span></dt><dd><p>Change the database nickname of a certificate.</p></dd><dt><span class="term">-E </span></dt><dd><p>Add an email certificate to the certificate database.</p></dd><dt><span class="term">-F</span></dt><dd><p>Delete a private key from a key database. Specify the key to delete with the -n argument. Specify the database from which to delete the key with the <code class="option">-d</code> argument. Use the <code class="option">-k</code> argument to specify explicitly whether to delete a DSA, RSA, or ECC key. If you don't use the <code class="option">-k</code> argument, the option looks for an RSA key matching the specified nickname. </p><p> @@ -20,25 +20,26 @@ Add one or multiple extensions that certutil cannot encode yet, by loading their duplicate nicknames. Giving a key type generates a new key pair; giving the ID of an existing key reuses that key pair (which is required to renew certificates). - </p></dd><dt><span class="term">-l </span></dt><dd><p>Display detailed information when validating a certificate with the -V option.</p></dd><dt><span class="term">-m serial-number</span></dt><dd><p>Assign a unique serial number to a certificate being created. This operation should be performed by a CA. If no serial number is provided a default serial number is made from the current time. Serial numbers are limited to integers </p></dd><dt><span class="term">-n nickname</span></dt><dd><p>Specify the nickname of a certificate or key to list, create, add to a database, modify, or validate. Bracket the nickname string with quotation marks if it contains spaces.</p></dd><dt><span class="term">-o output-file</span></dt><dd><p>Specify the output file name for new certificates or binary certificate requests. Bracket the output-file string with quotation marks if it contains spaces. If this argument is not used the output destination defaults to standard output.</p></dd><dt><span class="term">-P dbPrefix</span></dt><dd><p>Specify the prefix used on the certificate and key database file. This argument is provided to support legacy servers. Most applications do not use a database prefix.</p></dd><dt><span class="term">-p phone</span></dt><dd><p>Specify a contact telephone number to include in new certificates or certificate requests. Bracket this string with quotation marks if it contains spaces.</p></dd><dt><span class="term">-q pqgfile or curve-name</span></dt><dd><p>Read an alternate PQG value from the specified file when generating DSA key pairs. If this argument is not used, <span class="command"><strong>certutil</strong></span> generates its own PQG value. PQG files are created with a separate DSA utility.</p><p>Elliptic curve name is one of the ones from nistp256, nistp384, nistp521, curve25519.</p><p>If a token is available that supports more curves, the foolowing curves are supported as well: - sect163k1, nistk163, sect163r1, sect163r2, - nistb163, sect193r1, sect193r2, sect233k1, nistk233, - sect233r1, nistb233, sect239k1, sect283k1, nistk283, - sect283r1, nistb283, sect409k1, nistk409, sect409r1, - nistb409, sect571k1, nistk571, sect571r1, nistb571, - secp160k1, secp160r1, secp160r2, secp192k1, secp192r1, - nistp192, secp224k1, secp224r1, nistp224, secp256k1, - secp256r1, secp384r1, secp521r1, - prime192v1, prime192v2, prime192v3, - prime239v1, prime239v2, prime239v3, c2pnb163v1, - c2pnb163v2, c2pnb163v3, c2pnb176v1, c2tnb191v1, - c2tnb191v2, c2tnb191v3, - c2pnb208w1, c2tnb239v1, c2tnb239v2, c2tnb239v3, - c2pnb272w1, c2pnb304w1, - c2tnb359w1, c2pnb368w1, c2tnb431r1, secp112r1, - secp112r2, secp128r1, secp128r2, sect113r1, sect113r2, - sect131r1, sect131r2</p> - </dd><dt><span class="term">-r </span></dt><dd><p>Display a certificate's binary DER encoding when listing information about that certificate with the -L option.</p></dd><dt><span class="term">-s subject</span></dt><dd><p>Identify a particular certificate owner for new certificates or certificate requests. Bracket this string with quotation marks if it contains spaces. The subject identification format follows RFC #1485.</p></dd><dt><span class="term">-t trustargs</span></dt><dd><p>Specify the trust attributes to modify in an existing certificate or to apply to a certificate when creating it or adding it to a database. There are three available trust categories for each certificate, expressed in the order <span class="emphasis"><em>SSL, email, object signing</em></span> for each trust setting. In each category position, use none, any, or all + </p></dd><dt><span class="term">-l </span></dt><dd><p>Display detailed information when validating a certificate with the -V option.</p></dd><dt><span class="term">-m serial-number</span></dt><dd><p>Assign a unique serial number to a certificate being created. This operation should be performed by a CA. If no serial number is provided a default serial number is made from the current time. Serial numbers are limited to integers </p></dd><dt><span class="term">-n nickname</span></dt><dd><p>Specify the nickname of a certificate or key to list, create, add to a database, modify, or validate. Bracket the nickname string with quotation marks if it contains spaces.</p></dd><dt><span class="term">-o output-file</span></dt><dd><p>Specify the output file name for new certificates or binary certificate requests. Bracket the output-file string with quotation marks if it contains spaces. If this argument is not used the output destination defaults to standard output.</p></dd><dt><span class="term">-P dbPrefix</span></dt><dd><p>Specify the prefix used on the certificate and key database file. This argument is provided to support legacy servers. Most applications do not use a database prefix.</p></dd><dt><span class="term">-p phone</span></dt><dd><p>Specify a contact telephone number to include in new certificates or certificate requests. Bracket this string with quotation marks if it contains spaces.</p></dd><dt><span class="term">-q pqgfile or curve-name</span></dt><dd><p>Read an alternate PQG value from the specified file when generating DSA key pairs. If this argument is not used, <span class="command"><strong>certutil</strong></span> generates its own PQG value. PQG files are created with a separate DSA utility.</p><p>Elliptic curve name is one of the ones from nistp256, nistp384, nistp521, curve25519.</p><p> + If a token is available that supports more curves, the foolowing curves are supported as well: + sect163k1, nistk163, sect163r1, sect163r2, + nistb163, sect193r1, sect193r2, sect233k1, nistk233, + sect233r1, nistb233, sect239k1, sect283k1, nistk283, + sect283r1, nistb283, sect409k1, nistk409, sect409r1, + nistb409, sect571k1, nistk571, sect571r1, nistb571, + secp160k1, secp160r1, secp160r2, secp192k1, secp192r1, + nistp192, secp224k1, secp224r1, nistp224, secp256k1, + secp256r1, secp384r1, secp521r1, + prime192v1, prime192v2, prime192v3, + prime239v1, prime239v2, prime239v3, c2pnb163v1, + c2pnb163v2, c2pnb163v3, c2pnb176v1, c2tnb191v1, + c2tnb191v2, c2tnb191v3, + c2pnb208w1, c2tnb239v1, c2tnb239v2, c2tnb239v3, + c2pnb272w1, c2pnb304w1, + c2tnb359w1, c2pnb368w1, c2tnb431r1, secp112r1, + secp112r2, secp128r1, secp128r2, sect113r1, sect113r2, + sect131r1, sect131r2 + </p></dd><dt><span class="term">-r </span></dt><dd><p>Display a certificate's binary DER encoding when listing information about that certificate with the -L option.</p></dd><dt><span class="term">-s subject</span></dt><dd><p>Identify a particular certificate owner for new certificates or certificate requests. Bracket this string with quotation marks if it contains spaces. The subject identification format follows RFC #1485.</p></dd><dt><span class="term">-t trustargs</span></dt><dd><p>Specify the trust attributes to modify in an existing certificate or to apply to a certificate when creating it or adding it to a database. There are three available trust categories for each certificate, expressed in the order <span class="emphasis"><em>SSL, email, object signing</em></span> for each trust setting. In each category position, use none, any, or all of the attribute codes: </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p> <span class="command"><strong>p</strong></span> - Valid peer @@ -59,7 +60,7 @@ of the attribute codes: the certificate or adding it to a database. Express the offset in integers, using a minus sign (-) to indicate a negative offset. If this argument is not used, the validity period begins at the current system time. The length - of the validity period is set with the -v argument. </p></dd><dt><span class="term">-X </span></dt><dd><p>Force the key and certificate database to open in read-write mode. This is used with the <code class="option">-U</code> and <code class="option">-L</code> command options.</p></dd><dt><span class="term">-x </span></dt><dd><p>Use <span class="command"><strong>certutil</strong></span> to generate the signature for a certificate being created or added to a database, rather than obtaining a signature from a separate CA.</p></dd><dt><span class="term">-y exp</span></dt><dd><p>Set an alternate exponent value to use in generating a new RSA public key for the database, instead of the default value of 65537. The available alternate values are 3 and 17.</p></dd><dt><span class="term">-z noise-file</span></dt><dd><p>Read a seed value from the specified file to generate a new private and public key pair. This argument makes it possible to use hardware-generated seed values or manually create a value from the keyboard. The minimum file size is 20 bytes.</p></dd><dt><span class="term">-Z hashAlg</span></dt><dd><p>Specify the hash algorithm to use with the -C, -S or -R command options. Possible keywords:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>MD2</p></li><li class="listitem"><p>MD4</p></li><li class="listitem"><p>MD5</p></li><li class="listitem"><p>SHA1</p></li><li class="listitem"><p>SHA224</p></li><li class="listitem"><p>SHA256</p></li><li class="listitem"><p>SHA384</p></li><li class="listitem"><p>SHA512</p></li></ul></div></dd><dt><span class="term">-0 SSO_password</span></dt><dd><p>Set a site security officer password on a token.</p></dd><dt><span class="term">-1 | --keyUsage keyword,keyword</span></dt><dd><p>Set an X.509 V3 Certificate Type Extension in the certificate. There are several available keywords:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p> + of the validity period is set with the -v argument. </p></dd><dt><span class="term">-X </span></dt><dd><p>Force the key and certificate database to open in read-write mode. This is used with the <code class="option">-U</code> and <code class="option">-L</code> command options.</p></dd><dt><span class="term">-x </span></dt><dd><p>Use <span class="command"><strong>certutil</strong></span> to generate the signature for a certificate being created or added to a database, rather than obtaining a signature from a separate CA.</p></dd><dt><span class="term">-y exp</span></dt><dd><p>Set an alternate exponent value to use in generating a new RSA public key for the database, instead of the default value of 65537. The available alternate values are 3 and 17.</p></dd><dt><span class="term">--pss</span></dt><dd><p>Restrict the generated certificate (with the <code class="option">-S</code> option) or certificate request (with the <code class="option">-R</code> option) to be used with the RSA-PSS signature scheme. This only works when the private key of the certificate or certificate request is RSA.</p></dd><dt><span class="term">--pss-sign</span></dt><dd><p>Sign the generated certificate with the RSA-PSS signature scheme (with the <code class="option">-C</code> or <code class="option">-S</code> option). This only works when the private key of the signer's certificate is RSA. If the signer's certificate is restricted to RSA-PSS, it is not necessary to specify this option.</p></dd><dt><span class="term">-z noise-file</span></dt><dd><p>Read a seed value from the specified file to generate a new private and public key pair. This argument makes it possible to use hardware-generated seed values or manually create a value from the keyboard. The minimum file size is 20 bytes.</p></dd><dt><span class="term">-Z hashAlg</span></dt><dd><p>Specify the hash algorithm to use with the -C, -S or -R command options. Possible keywords:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>MD2</p></li><li class="listitem"><p>MD4</p></li><li class="listitem"><p>MD5</p></li><li class="listitem"><p>SHA1</p></li><li class="listitem"><p>SHA224</p></li><li class="listitem"><p>SHA256</p></li><li class="listitem"><p>SHA384</p></li><li class="listitem"><p>SHA512</p></li></ul></div></dd><dt><span class="term">-0 SSO_password</span></dt><dd><p>Set a site security officer password on a token.</p></dd><dt><span class="term">-1 | --keyUsage keyword,keyword</span></dt><dd><p>Set an X.509 V3 Certificate Type Extension in the certificate. There are several available keywords:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p> digitalSignature </p></li><li class="listitem"><p> nonRepudiation diff --git a/security/nss/doc/html/pk12util.html b/security/nss/doc/html/pk12util.html index fe516dd83..94dbf51e9 100644 --- a/security/nss/doc/html/pk12util.html +++ b/security/nss/doc/html/pk12util.html @@ -1,6 +1,6 @@ -<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>PK12UTIL</title><meta name="generator" content="DocBook XSL Stylesheets V1.78.1"><link rel="home" href="index.html" title="PK12UTIL"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">PK12UTIL</th></tr></table><hr></div><div class="refentry"><a name="pk12util"></a><div class="titlepage"></div><div class="refnamediv"><h2>Name</h2><p>pk12util — Export and import keys and certificate to or from a PKCS #12 file and the NSS database</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p><code class="command">pk12util</code> [-i p12File|-l p12File|-o p12File] [-d [sql:]directory] [-h tokenname] [-P dbprefix] [-r] [-v] [-k slotPasswordFile|-K slotPassword] [-w p12filePasswordFile|-W p12filePassword]</p></div></div><div class="refsection"><a name="idm233250345408"></a><h2>STATUS</h2><p>This documentation is still work in progress. Please contribute to the initial review in <a class="ulink" href="https://bugzilla.mozilla.org/show_bug.cgi?id=836477" target="_top">Mozilla NSS bug 836477</a> - </p></div><div class="refsection"><a name="description"></a><h2>Description</h2><p>The PKCS #12 utility, <span class="command"><strong>pk12util</strong></span>, enables sharing certificates among any server that supports PKCS#12. The tool can import certificates and keys from PKCS#12 files into security databases, export certificates, and list certificates and keys.</p></div><div class="refsection"><a name="options"></a><h2>Options and Arguments</h2><p><span class="command"><strong>Options</strong></span></p><div class="variablelist"><dl class="variablelist"><dt><span class="term">-i p12file</span></dt><dd><p>Import keys and certificates from a PKCS#12 file into a security database.</p></dd><dt><span class="term">-l p12file</span></dt><dd><p>List the keys and certificates in PKCS#12 file.</p></dd><dt><span class="term">-o p12file</span></dt><dd><p>Export keys and certificates from the security database to a PKCS#12 file.</p></dd></dl></div><p><span class="command"><strong>Arguments</strong></span></p><div class="variablelist"><dl class="variablelist"><dt><span class="term">-c keyCipher</span></dt><dd><p>Specify the key encryption algorithm.</p></dd><dt><span class="term">-C certCipher</span></dt><dd><p>Specify the key cert (overall package) encryption algorithm.</p></dd><dt><span class="term">-d [sql:]directory</span></dt><dd><p>Specify the database directory into which to import to or export from certificates and keys.</p><p><span class="command"><strong>pk12util</strong></span> supports two types of databases: the legacy security databases (<code class="filename">cert8.db</code>, <code class="filename">key3.db</code>, and <code class="filename">secmod.db</code>) and new SQLite databases (<code class="filename">cert9.db</code>, <code class="filename">key4.db</code>, and <code class="filename">pkcs11.txt</code>). If the prefix <span class="command"><strong>sql:</strong></span> is not used, then the tool assumes that the given databases are in the old format.</p></dd><dt><span class="term">-h tokenname</span></dt><dd><p>Specify the name of the token to import into or export from.</p></dd><dt><span class="term">-k slotPasswordFile</span></dt><dd><p>Specify the text file containing the slot's password.</p></dd><dt><span class="term">-K slotPassword</span></dt><dd><p>Specify the slot's password.</p></dd><dt><span class="term">-m | --key-len keyLength</span></dt><dd><p>Specify the desired length of the symmetric key to be used to encrypt the private key.</p></dd><dt><span class="term">-n | --cert-key-len certKeyLength</span></dt><dd><p>Specify the desired length of the symmetric key to be used to encrypt the certificates and other meta-data.</p></dd><dt><span class="term">-n certname</span></dt><dd><p>Specify the nickname of the cert and private key to export.</p></dd><dt><span class="term">-P prefix</span></dt><dd><p>Specify the prefix used on the certificate and key databases. This option is provided as a special case. - Changing the names of the certificate and key databases is not recommended.</p></dd><dt><span class="term">-r</span></dt><dd><p>Dumps all of the data in raw (binary) form. This must be saved as a DER file. The default is to return information in a pretty-print ASCII format, which displays the information about the certificates and public keys in the p12 file.</p></dd><dt><span class="term">-v </span></dt><dd><p>Enable debug logging when importing.</p></dd><dt><span class="term">-w p12filePasswordFile</span></dt><dd><p>Specify the text file containing the pkcs #12 file password.</p></dd><dt><span class="term">-W p12filePassword</span></dt><dd><p>Specify the pkcs #12 file password.</p></dd></dl></div></div><div class="refsection"><a name="return-codes"></a><h2>Return Codes</h2><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p> 0 - No error</p></li><li class="listitem"><p> 1 - User Cancelled</p></li><li class="listitem"><p> 2 - Usage error</p></li><li class="listitem"><p> 6 - NLS init error</p></li><li class="listitem"><p> 8 - Certificate DB open error</p></li><li class="listitem"><p> 9 - Key DB open error</p></li><li class="listitem"><p> 10 - File initialization error</p></li><li class="listitem"><p> 11 - Unicode conversion error</p></li><li class="listitem"><p> 12 - Temporary file creation error</p></li><li class="listitem"><p> 13 - PKCS11 get slot error</p></li><li class="listitem"><p> 14 - PKCS12 decoder start error</p></li><li class="listitem"><p> 15 - error read from import file</p></li><li class="listitem"><p> 16 - pkcs12 decode error</p></li><li class="listitem"><p> 17 - pkcs12 decoder verify error</p></li><li class="listitem"><p> 18 - pkcs12 decoder validate bags error</p></li><li class="listitem"><p> 19 - pkcs12 decoder import bags error</p></li><li class="listitem"><p> 20 - key db conversion version 3 to version 2 error</p></li><li class="listitem"><p> 21 - cert db conversion version 7 to version 5 error</p></li><li class="listitem"><p> 22 - cert and key dbs patch error</p></li><li class="listitem"><p> 23 - get default cert db error</p></li><li class="listitem"><p> 24 - find cert by nickname error</p></li><li class="listitem"><p> 25 - create export context error</p></li><li class="listitem"><p> 26 - PKCS12 add password itegrity error</p></li><li class="listitem"><p> 27 - cert and key Safes creation error</p></li><li class="listitem"><p> 28 - PKCS12 add cert and key error</p></li><li class="listitem"><p> 29 - PKCS12 encode error</p></li></ul></div></div><div class="refsection"><a name="examples"></a><h2>Examples</h2><p><span class="command"><strong>Importing Keys and Certificates</strong></span></p><p>The most basic usage of <span class="command"><strong>pk12util</strong></span> for importing a certificate or key is the PKCS#12 input file (<code class="option">-i</code>) and some way to specify the security database being accessed (either <code class="option">-d</code> for a directory or <code class="option">-h</code> for a token). +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>PK12UTIL</title><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot"><link rel="home" href="index.html" title="PK12UTIL"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">PK12UTIL</th></tr></table><hr></div><div class="refentry"><a name="pk12util"></a><div class="titlepage"></div><div class="refnamediv"><h2>Name</h2><p>pk12util — Export and import keys and certificate to or from a PKCS #12 file and the NSS database</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p><code class="command">pk12util</code> [-i p12File|-l p12File|-o p12File] [-d [sql:]directory] [-h tokenname] [-P dbprefix] [-r] [-v] [-k slotPasswordFile|-K slotPassword] [-w p12filePasswordFile|-W p12filePassword]</p></div></div><div class="refsection"><a name="idm139975398059856"></a><h2>STATUS</h2><p>This documentation is still work in progress. Please contribute to the initial review in <a class="ulink" href="https://bugzilla.mozilla.org/show_bug.cgi?id=836477" target="_top">Mozilla NSS bug 836477</a> + </p></div><div class="refsection"><a name="description"></a><h2>Description</h2><p>The PKCS #12 utility, <span class="command"><strong>pk12util</strong></span>, enables sharing certificates among any server that supports PKCS #12. The tool can import certificates and keys from PKCS #12 files into security databases, export certificates, and list certificates and keys.</p></div><div class="refsection"><a name="options"></a><h2>Options and Arguments</h2><p><span class="command"><strong>Options</strong></span></p><div class="variablelist"><dl class="variablelist"><dt><span class="term">-i p12file</span></dt><dd><p>Import keys and certificates from a PKCS #12 file into a security database.</p></dd><dt><span class="term">-l p12file</span></dt><dd><p>List the keys and certificates in PKCS #12 file.</p></dd><dt><span class="term">-o p12file</span></dt><dd><p>Export keys and certificates from the security database to a PKCS #12 file.</p></dd></dl></div><p><span class="command"><strong>Arguments</strong></span></p><div class="variablelist"><dl class="variablelist"><dt><span class="term">-c keyCipher</span></dt><dd><p>Specify the key encryption algorithm.</p></dd><dt><span class="term">-C certCipher</span></dt><dd><p>Specify the certiticate encryption algorithm.</p></dd><dt><span class="term">-d [sql:]directory</span></dt><dd><p>Specify the database directory into which to import to or export from certificates and keys.</p><p><span class="command"><strong>pk12util</strong></span> supports two types of databases: the legacy security databases (<code class="filename">cert8.db</code>, <code class="filename">key3.db</code>, and <code class="filename">secmod.db</code>) and new SQLite databases (<code class="filename">cert9.db</code>, <code class="filename">key4.db</code>, and <code class="filename">pkcs11.txt</code>). If the prefix <span class="command"><strong>sql:</strong></span> is not used, then the tool assumes that the given databases are in the old format.</p></dd><dt><span class="term">-h tokenname</span></dt><dd><p>Specify the name of the token to import into or export from.</p></dd><dt><span class="term">-k slotPasswordFile</span></dt><dd><p>Specify the text file containing the slot's password.</p></dd><dt><span class="term">-K slotPassword</span></dt><dd><p>Specify the slot's password.</p></dd><dt><span class="term">-m | --key-len keyLength</span></dt><dd><p>Specify the desired length of the symmetric key to be used to encrypt the private key.</p></dd><dt><span class="term">-n | --cert-key-len certKeyLength</span></dt><dd><p>Specify the desired length of the symmetric key to be used to encrypt the certificates and other meta-data.</p></dd><dt><span class="term">-n certname</span></dt><dd><p>Specify the nickname of the cert and private key to export.</p></dd><dt><span class="term">-P prefix</span></dt><dd><p>Specify the prefix used on the certificate and key databases. This option is provided as a special case. + Changing the names of the certificate and key databases is not recommended.</p></dd><dt><span class="term">-r</span></dt><dd><p>Dumps all of the data in raw (binary) form. This must be saved as a DER file. The default is to return information in a pretty-print ASCII format, which displays the information about the certificates and public keys in the p12 file.</p></dd><dt><span class="term">-v </span></dt><dd><p>Enable debug logging when importing.</p></dd><dt><span class="term">-w p12filePasswordFile</span></dt><dd><p>Specify the text file containing the pkcs #12 file password.</p></dd><dt><span class="term">-W p12filePassword</span></dt><dd><p>Specify the pkcs #12 file password.</p></dd></dl></div></div><div class="refsection"><a name="return-codes"></a><h2>Return Codes</h2><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p> 0 - No error</p></li><li class="listitem"><p> 1 - User Cancelled</p></li><li class="listitem"><p> 2 - Usage error</p></li><li class="listitem"><p> 6 - NLS init error</p></li><li class="listitem"><p> 8 - Certificate DB open error</p></li><li class="listitem"><p> 9 - Key DB open error</p></li><li class="listitem"><p> 10 - File initialization error</p></li><li class="listitem"><p> 11 - Unicode conversion error</p></li><li class="listitem"><p> 12 - Temporary file creation error</p></li><li class="listitem"><p> 13 - PKCS11 get slot error</p></li><li class="listitem"><p> 14 - PKCS12 decoder start error</p></li><li class="listitem"><p> 15 - error read from import file</p></li><li class="listitem"><p> 16 - pkcs12 decode error</p></li><li class="listitem"><p> 17 - pkcs12 decoder verify error</p></li><li class="listitem"><p> 18 - pkcs12 decoder validate bags error</p></li><li class="listitem"><p> 19 - pkcs12 decoder import bags error</p></li><li class="listitem"><p> 20 - key db conversion version 3 to version 2 error</p></li><li class="listitem"><p> 21 - cert db conversion version 7 to version 5 error</p></li><li class="listitem"><p> 22 - cert and key dbs patch error</p></li><li class="listitem"><p> 23 - get default cert db error</p></li><li class="listitem"><p> 24 - find cert by nickname error</p></li><li class="listitem"><p> 25 - create export context error</p></li><li class="listitem"><p> 26 - PKCS12 add password itegrity error</p></li><li class="listitem"><p> 27 - cert and key Safes creation error</p></li><li class="listitem"><p> 28 - PKCS12 add cert and key error</p></li><li class="listitem"><p> 29 - PKCS12 encode error</p></li></ul></div></div><div class="refsection"><a name="examples"></a><h2>Examples</h2><p><span class="command"><strong>Importing Keys and Certificates</strong></span></p><p>The most basic usage of <span class="command"><strong>pk12util</strong></span> for importing a certificate or key is the PKCS #12 input file (<code class="option">-i</code>) and some way to specify the security database being accessed (either <code class="option">-d</code> for a directory or <code class="option">-h</code> for a token). </p><p> pk12util -i p12File [-h tokenname] [-v] [-d [sql:]directory] [-P dbprefix] [-k slotPasswordFile|-K slotPassword] [-w p12filePasswordFile|-W p12filePassword] </p><p>For example:</p><p> </p><pre class="programlisting"># pk12util -i /tmp/cert-files/users.p12 -d sql:/home/my/sharednssdb @@ -12,7 +12,7 @@ and should contain at least one non-alphabetic character. Enter new password: Re-enter password: Enter password for PKCS12 file: -pk12util: PKCS12 IMPORT SUCCESSFUL</pre><p><span class="command"><strong>Exporting Keys and Certificates</strong></span></p><p>Using the <span class="command"><strong>pk12util</strong></span> command to export certificates and keys requires both the name of the certificate to extract from the database (<code class="option">-n</code>) and the PKCS#12-formatted output file to write to. There are optional parameters that can be used to encrypt the file to protect the certificate material. +pk12util: PKCS12 IMPORT SUCCESSFUL</pre><p><span class="command"><strong>Exporting Keys and Certificates</strong></span></p><p>Using the <span class="command"><strong>pk12util</strong></span> command to export certificates and keys requires both the name of the certificate to extract from the database (<code class="option">-n</code>) and the PKCS #12-formatted output file to write to. There are optional parameters that can be used to encrypt the file to protect the certificate material. </p><p>pk12util -o p12File -n certname [-c keyCipher] [-C certCipher] [-m|--key_len keyLen] [-n|--cert_key_len certKeyLen] [-d [sql:]directory] [-P dbprefix] [-k slotPasswordFile|-K slotPassword] [-w p12filePasswordFile|-W p12filePassword]</p><p>For example:</p><pre class="programlisting"># pk12util -o certs.p12 -n Server-Cert -d sql:/home/my/sharednssdb Enter password for PKCS12 file: Re-enter password: </pre><p><span class="command"><strong>Listing Keys and Certificates</strong></span></p><p>The information in a <code class="filename">.p12</code> file are not human-readable. The certificates and keys in the file can be printed (listed) in a human-readable pretty-print format that shows information for every certificate and any public keys in the <code class="filename">.p12</code> file. @@ -48,7 +48,7 @@ Key(shrouded): Certificate Friendly Name: Thawte Personal Freemail Issuing CA - Thawte Consulting Certificate Friendly Name: Thawte Freemail Member's Thawte Consulting (Pty) Ltd. ID - </pre></div><div class="refsection"><a name="encryption"></a><h2>Password Encryption</h2><p>PKCS#12 provides for not only the protection of the private keys but also the certificate and meta-data associated with the keys. Password-based encryption is used to protect private keys on export to a PKCS#12 file and, optionally, the entire package. If no algorithm is specified, the tool defaults to using <span class="command"><strong>PKCS12 V2 PBE with SHA1 and 3KEY Triple DES-cbc</strong></span> for private key encryption. <span class="command"><strong>PKCS12 V2 PBE with SHA1 and 40 Bit RC4</strong></span> is the default for the overall package encryption when not in FIPS mode. When in FIPS mode, there is no package encryption.</p><p>The private key is always protected with strong encryption by default.</p><p>Several types of ciphers are supported.</p><div class="variablelist"><dl class="variablelist"><dt><span class="term">Symmetric CBC ciphers for PKCS#5 V2</span></dt><dd><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>DES-CBC</p></li><li class="listitem"><p>RC2-CBC</p></li><li class="listitem"><p>RC5-CBCPad</p></li><li class="listitem"><p>DES-EDE3-CBC (the default for key encryption)</p></li><li class="listitem"><p>AES-128-CBC</p></li><li class="listitem"><p>AES-192-CBC</p></li><li class="listitem"><p>AES-256-CBC</p></li><li class="listitem"><p>CAMELLIA-128-CBC</p></li><li class="listitem"><p>CAMELLIA-192-CBC</p></li><li class="listitem"><p>CAMELLIA-256-CBC</p></li></ul></div></dd><dt><span class="term">PKCS#12 PBE ciphers</span></dt><dd><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>PKCS #12 PBE with Sha1 and 128 Bit RC4</p></li><li class="listitem"><p>PKCS #12 PBE with Sha1 and 40 Bit RC4</p></li><li class="listitem"><p>PKCS #12 PBE with Sha1 and Triple DES CBC</p></li><li class="listitem"><p>PKCS #12 PBE with Sha1 and 128 Bit RC2 CBC</p></li><li class="listitem"><p>PKCS #12 PBE with Sha1 and 40 Bit RC2 CBC</p></li><li class="listitem"><p>PKCS12 V2 PBE with SHA1 and 128 Bit RC4</p></li><li class="listitem"><p>PKCS12 V2 PBE with SHA1 and 40 Bit RC4 (the default for non-FIPS mode)</p></li><li class="listitem"><p>PKCS12 V2 PBE with SHA1 and 3KEY Triple DES-cbc</p></li><li class="listitem"><p>PKCS12 V2 PBE with SHA1 and 2KEY Triple DES-cbc</p></li><li class="listitem"><p>PKCS12 V2 PBE with SHA1 and 128 Bit RC2 CBC</p></li><li class="listitem"><p>PKCS12 V2 PBE with SHA1 and 40 Bit RC2 CBC</p></li></ul></div></dd><dt><span class="term">PKCS#5 PBE ciphers</span></dt><dd><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>PKCS #5 Password Based Encryption with MD2 and DES CBC</p></li><li class="listitem"><p>PKCS #5 Password Based Encryption with MD5 and DES CBC</p></li><li class="listitem"><p>PKCS #5 Password Based Encryption with SHA1 and DES CBC</p></li></ul></div></dd></dl></div><p>With PKCS#12, the crypto provider may be the soft token module or an external hardware module. If the cryptographic module does not support the requested algorithm, then the next best fit will be selected (usually the default). If no suitable replacement for the desired algorithm can be found, the tool returns the error <span class="emphasis"><em>no security module can perform the requested operation</em></span>.</p></div><div class="refsection"><a name="databases"></a><h2>NSS Database Types</h2><p>NSS originally used BerkeleyDB databases to store security information. + </pre></div><div class="refsection"><a name="encryption"></a><h2>Password Encryption</h2><p>PKCS #12 provides for not only the protection of the private keys but also the certificate and meta-data associated with the keys. Password-based encryption is used to protect private keys on export to a PKCS #12 file and, optionally, the associated certificates. If no algorithm is specified, the tool defaults to using PKCS #12 SHA-1 and 3-key triple DES for private key encryption. When not in FIPS mode, PKCS #12 SHA-1 and 40-bit RC4 is used for certificate encryption. When in FIPS mode, there is no certificate encryption. If certificate encryption is not wanted, specify <strong class="userinput"><code>"NONE"</code></strong> as the argument of the <code class="option">-C</code> option.</p><p>The private key is always protected with strong encryption by default.</p><p>Several types of ciphers are supported.</p><div class="variablelist"><dl class="variablelist"><dt><span class="term">PKCS #5 password-based encryption</span></dt><dd><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>PBES2 with AES-CBC-Pad as underlying encryption scheme (<strong class="userinput"><code>"AES-128-CBC"</code></strong>, <strong class="userinput"><code>"AES-192-CBC"</code></strong>, and <strong class="userinput"><code>"AES-256-CBC"</code></strong>)</p></li></ul></div></dd><dt><span class="term">PKCS #12 password-based encryption</span></dt><dd><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>SHA-1 and 128-bit RC4 (<strong class="userinput"><code>"PKCS #12 V2 PBE With SHA-1 And 128 Bit RC4"</code></strong> or <strong class="userinput"><code>"RC4"</code></strong>)</p></li><li class="listitem"><p>SHA-1 and 40-bit RC4 (<strong class="userinput"><code>"PKCS #12 V2 PBE With SHA-1 And 40 Bit RC4"</code></strong>) (used by default for certificate encryption in non-FIPS mode)</p></li><li class="listitem"><p>SHA-1 and 3-key triple-DES (<strong class="userinput"><code>"PKCS #12 V2 PBE With SHA-1 And 3KEY Triple DES-CBC"</code></strong> or <strong class="userinput"><code>"DES-EDE3-CBC"</code></strong>)</p></li><li class="listitem"><p>SHA-1 and 128-bit RC2 (<strong class="userinput"><code>"PKCS #12 V2 PBE With SHA-1 And 128 Bit RC2 CBC"</code></strong> or <strong class="userinput"><code>"RC2-CBC"</code></strong>)</p></li><li class="listitem"><p>SHA-1 and 40-bit RC2 (<strong class="userinput"><code>"PKCS #12 V2 PBE With SHA-1 And 40 Bit RC2 CBC"</code></strong>)</p></li></ul></div></dd></dl></div><p>With PKCS #12, the crypto provider may be the soft token module or an external hardware module. If the cryptographic module does not support the requested algorithm, then the next best fit will be selected (usually the default). If no suitable replacement for the desired algorithm can be found, the tool returns the error <span class="emphasis"><em>no security module can perform the requested operation</em></span>.</p></div><div class="refsection"><a name="databases"></a><h2>NSS Database Types</h2><p>NSS originally used BerkeleyDB databases to store security information. The last versions of these <span class="emphasis"><em>legacy</em></span> databases are:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p> cert8.db for certificates </p></li><li class="listitem"><p> @@ -68,7 +68,7 @@ BerkleyDB. These new databases provide more accessibility and performance:</p><d Using the SQLite databases must be manually specified by using the <span class="command"><strong>sql:</strong></span> prefix with the given security directory. For example:</p><pre class="programlisting"># pk12util -i /tmp/cert-files/users.p12 -d sql:/home/my/sharednssdb</pre><p>To set the shared database type as the default type for the tools, set the <code class="envar">NSS_DEFAULT_DB_TYPE</code> environment variable to <code class="envar">sql</code>:</p><pre class="programlisting">export NSS_DEFAULT_DB_TYPE="sql"</pre><p>This line can be set added to the <code class="filename">~/.bashrc</code> file to make the change permanent.</p><p>Most applications do not use the shared database by default, but they can be configured to use them. For example, this how-to article covers how to configure Firefox and Thunderbird to use the new shared NSS databases:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p> https://wiki.mozilla.org/NSS_Shared_DB_Howto</p></li></ul></div><p>For an engineering draft on the changes in the shared NSS databases, see the NSS project wiki:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p> https://wiki.mozilla.org/NSS_Shared_DB - </p></li></ul></div></div><div class="refsection"><a name="seealso"></a><h2>See Also</h2><p>certutil (1)</p><p>modutil (1)</p><p>The NSS wiki has information on the new database design and how to configure applications to use it.</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p> + </p></li></ul></div></div><div class="refsection"><a name="compatibility"></a><h2>Compatibility Notes</h2><p>The exporting behavior of <span class="command"><strong>pk12util</strong></span> has changed over time, while importing files exported with older versions of NSS is still supported.</p><p>Until the 3.30 release, <span class="command"><strong>pk12util</strong></span> used the UTF-16 encoding for the PKCS #5 password-based encryption schemes, while the recommendation is to encode passwords in UTF-8 if the used encryption scheme is defined outside of the PKCS #12 standard.</p><p>Until the 3.31 release, even when <strong class="userinput"><code>"AES-128-CBC"</code></strong> or <strong class="userinput"><code>"AES-192-CBC"</code></strong> is given from the command line, <span class="command"><strong>pk12util</strong></span> always used 256-bit AES as the underlying encryption scheme.</p><p>For historical reasons, <span class="command"><strong>pk12util</strong></span> accepts password-based encryption schemes not listed in this document. However, those schemes are not officially supported and may have issues in interoperability with other tools.</p></div><div class="refsection"><a name="seealso"></a><h2>See Also</h2><p>certutil (1)</p><p>modutil (1)</p><p>The NSS wiki has information on the new database design and how to configure applications to use it.</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p> https://wiki.mozilla.org/NSS_Shared_DB_Howto</p></li><li class="listitem"><p> https://wiki.mozilla.org/NSS_Shared_DB </p></li></ul></div></div><div class="refsection"><a name="resources"></a><h2>Additional Resources</h2><p>For information about NSS and other tools related to NSS (like JSS), check out the NSS project wiki at <a class="ulink" href="http://www.mozilla.org/projects/security/pki/nss/" target="_top">http://www.mozilla.org/projects/security/pki/nss/</a>. The NSS site relates directly to NSS code changes and releases.</p><p>Mailing lists: https://lists.mozilla.org/listinfo/dev-tech-crypto</p><p>IRC: Freenode at #dogtag-pki</p></div><div class="refsection"><a name="authors"></a><h2>Authors</h2><p>The NSS tools were written and maintained by developers with Netscape, Red Hat, Sun, Oracle, Mozilla, and Google.</p><p> diff --git a/security/nss/doc/nroff/certutil.1 b/security/nss/doc/nroff/certutil.1 index b2a8bd2bb..80a02fc27 100644 --- a/security/nss/doc/nroff/certutil.1 +++ b/security/nss/doc/nroff/certutil.1 @@ -1,13 +1,13 @@ '\" t .\" Title: CERTUTIL .\" Author: [see the "Authors" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/> -.\" Date: 8 September 2016 +.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/> +.\" Date: 27 October 2017 .\" Manual: NSS Security Tools .\" Source: nss-tools .\" Language: English .\" -.TH "CERTUTIL" "1" "8 September 2016" "nss-tools" "NSS Security Tools" +.TH "CERTUTIL" "1" "27 October 2017" "nss-tools" "NSS Security Tools" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -371,9 +371,9 @@ Read an alternate PQG value from the specified file when generating DSA key pair \fBcertutil\fR generates its own PQG value\&. PQG files are created with a separate DSA utility\&. .sp -Elliptic curve name is one of the ones from nistp256, nistp384, nistp521, curve25519. +Elliptic curve name is one of the ones from nistp256, nistp384, nistp521, curve25519\&. .sp -If a token is available that supports more curves, the foolowing curves are supported as well: sect163k1, nistk163, sect163r1, sect163r2, nistb163, sect193r1, sect193r2, sect233k1, nistk233, sect233r1, nistb233, sect239k1, sect283k1, nistk283, sect283r1, nistb283, sect409k1, nistk409, sect409r1, nistb409, sect571k1, nistk571, sect571r1, nistb571, secp160k1, secp160r1, secp160r2, secp192k1, secp192r1, nistp192, secp224k1, secp224r1, nistp224, secp256k1, secp256r1, secp384r1, secp521r1, prime192v1, prime192v2, prime192v3, prime239v1, prime239v2, prime239v3, c2pnb163v1, c2pnb163v2, c2pnb163v3, c2pnb176v1, c2tnb191v1, c2tnb191v2, c2tnb191v3, c2pnb208w1, c2tnb239v1, c2tnb239v2, c2tnb239v3, c2pnb272w1, c2pnb304w1, c2tnb359w1, c2pnb368w1, c2tnb431r1, secp112r1, secp112r2, secp128r1, secp128r2, sect113r1, sect113r2, sect131r1, sect131r2 +If a token is available that supports more curves, the foolowing curves are supported as well: sect163k1, nistk163, sect163r1, sect163r2, nistb163, sect193r1, sect193r2, sect233k1, nistk233, sect233r1, nistb233, sect239k1, sect283k1, nistk283, sect283r1, nistb283, sect409k1, nistk409, sect409r1, nistb409, sect571k1, nistk571, sect571r1, nistb571, secp160k1, secp160r1, secp160r2, secp192k1, secp192r1, nistp192, secp224k1, secp224r1, nistp224, secp256k1, secp256r1, secp384r1, secp521r1, prime192v1, prime192v2, prime192v3, prime239v1, prime239v2, prime239v3, c2pnb163v1, c2pnb163v2, c2pnb163v3, c2pnb176v1, c2tnb191v1, c2tnb191v2, c2tnb191v3, c2pnb208w1, c2tnb239v1, c2tnb239v2, c2tnb239v3, c2pnb272w1, c2pnb304w1, c2tnb359w1, c2pnb368w1, c2tnb431r1, secp112r1, secp112r2, secp128r1, secp128r2, sect113r1, sect113r2, sect131r1, sect131r2 .RE .PP \-r @@ -609,6 +609,24 @@ to generate the signature for a certificate being created or added to a database Set an alternate exponent value to use in generating a new RSA public key for the database, instead of the default value of 65537\&. The available alternate values are 3 and 17\&. .RE .PP +\-\-pss +.RS 4 +Restrict the generated certificate (with the +\fB\-S\fR +option) or certificate request (with the +\fB\-R\fR +option) to be used with the RSA\-PSS signature scheme\&. This only works when the private key of the certificate or certificate request is RSA\&. +.RE +.PP +\-\-pss\-sign +.RS 4 +Sign the generated certificate with the RSA\-PSS signature scheme (with the +\fB\-C\fR +or +\fB\-S\fR +option)\&. This only works when the private key of the signer\*(Aqs certificate is RSA\&. If the signer\*(Aqs certificate is restricted to RSA\-PSS, it is not necessary to specify this option\&. +.RE +.PP \-z noise\-file .RS 4 Read a seed value from the specified file to generate a new private and public key pair\&. This argument makes it possible to use hardware\-generated seed values or manually create a value from the keyboard\&. The minimum file size is 20 bytes\&. @@ -1512,7 +1530,8 @@ There are ways to narrow the keys listed in the search results: .IP \(bu 2.3 .\} To return a specific key, use the -\fB\-n\fR\fIname\fR +\fB\-n\fR +\fIname\fR argument with the name of the key\&. .RE .sp @@ -1525,7 +1544,8 @@ argument with the name of the key\&. .IP \(bu 2.3 .\} If there are multiple security devices loaded, then the -\fB\-h\fR\fItokenname\fR +\fB\-h\fR +\fItokenname\fR argument can search a specific token or all tokens\&. .RE .sp @@ -1538,7 +1558,8 @@ argument can search a specific token or all tokens\&. .IP \(bu 2.3 .\} If there are multiple key types available, then the -\fB\-k\fR\fIkey\-type\fR +\fB\-k\fR +\fIkey\-type\fR argument can search a specific type of key, like RSA, DSA, or ECC\&. .RE .PP diff --git a/security/nss/doc/nroff/pk12util.1 b/security/nss/doc/nroff/pk12util.1 index c4fa972c0..e0a8da833 100644 --- a/security/nss/doc/nroff/pk12util.1 +++ b/security/nss/doc/nroff/pk12util.1 @@ -1,13 +1,13 @@ '\" t .\" Title: PK12UTIL .\" Author: [see the "Authors" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/> -.\" Date: 5 June 2014 +.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/> +.\" Date: 27 October 2017 .\" Manual: NSS Security Tools .\" Source: nss-tools .\" Language: English .\" -.TH "PK12UTIL" "1" "5 June 2014" "nss-tools" "NSS Security Tools" +.TH "PK12UTIL" "1" "27 October 2017" "nss-tools" "NSS Security Tools" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -39,24 +39,24 @@ This documentation is still work in progress\&. Please contribute to the initial .SH "DESCRIPTION" .PP The PKCS #12 utility, -\fBpk12util\fR, enables sharing certificates among any server that supports PKCS#12\&. The tool can import certificates and keys from PKCS#12 files into security databases, export certificates, and list certificates and keys\&. +\fBpk12util\fR, enables sharing certificates among any server that supports PKCS #12\&. The tool can import certificates and keys from PKCS #12 files into security databases, export certificates, and list certificates and keys\&. .SH "OPTIONS AND ARGUMENTS" .PP \fBOptions\fR .PP \-i p12file .RS 4 -Import keys and certificates from a PKCS#12 file into a security database\&. +Import keys and certificates from a PKCS #12 file into a security database\&. .RE .PP \-l p12file .RS 4 -List the keys and certificates in PKCS#12 file\&. +List the keys and certificates in PKCS #12 file\&. .RE .PP \-o p12file .RS 4 -Export keys and certificates from the security database to a PKCS#12 file\&. +Export keys and certificates from the security database to a PKCS #12 file\&. .RE .PP \fBArguments\fR @@ -68,7 +68,7 @@ Specify the key encryption algorithm\&. .PP \-C certCipher .RS 4 -Specify the key cert (overall package) encryption algorithm\&. +Specify the certiticate encryption algorithm\&. .RE .PP \-d [sql:]directory @@ -432,7 +432,7 @@ Specify the pkcs #12 file password\&. .PP The most basic usage of \fBpk12util\fR -for importing a certificate or key is the PKCS#12 input file (\fB\-i\fR) and some way to specify the security database being accessed (either +for importing a certificate or key is the PKCS #12 input file (\fB\-i\fR) and some way to specify the security database being accessed (either \fB\-d\fR for a directory or \fB\-h\fR @@ -467,7 +467,7 @@ pk12util: PKCS12 IMPORT SUCCESSFUL .PP Using the \fBpk12util\fR -command to export certificates and keys requires both the name of the certificate to extract from the database (\fB\-n\fR) and the PKCS#12\-formatted output file to write to\&. There are optional parameters that can be used to encrypt the file to protect the certificate material\&. +command to export certificates and keys requires both the name of the certificate to extract from the database (\fB\-n\fR) and the PKCS #12\-formatted output file to write to\&. There are optional parameters that can be used to encrypt the file to protect the certificate material\&. .PP pk12util \-o p12File \-n certname [\-c keyCipher] [\-C certCipher] [\-m|\-\-key_len keyLen] [\-n|\-\-cert_key_len certKeyLen] [\-d [sql:]directory] [\-P dbprefix] [\-k slotPasswordFile|\-K slotPassword] [\-w p12filePasswordFile|\-W p12filePassword] .PP @@ -559,17 +559,17 @@ Certificate Friendly Name: Thawte Freemail Member\*(Aqs Thawte Consulting (Pt .\} .SH "PASSWORD ENCRYPTION" .PP -PKCS#12 provides for not only the protection of the private keys but also the certificate and meta\-data associated with the keys\&. Password\-based encryption is used to protect private keys on export to a PKCS#12 file and, optionally, the entire package\&. If no algorithm is specified, the tool defaults to using -\fBPKCS12 V2 PBE with SHA1 and 3KEY Triple DES\-cbc\fR -for private key encryption\&. -\fBPKCS12 V2 PBE with SHA1 and 40 Bit RC4\fR -is the default for the overall package encryption when not in FIPS mode\&. When in FIPS mode, there is no package encryption\&. +PKCS #12 provides for not only the protection of the private keys but also the certificate and meta\-data associated with the keys\&. Password\-based encryption is used to protect private keys on export to a PKCS #12 file and, optionally, the associated certificates\&. If no algorithm is specified, the tool defaults to using PKCS #12 SHA\-1 and 3\-key triple DES for private key encryption\&. When not in FIPS mode, PKCS #12 SHA\-1 and 40\-bit RC4 is used for certificate encryption\&. When in FIPS mode, there is no certificate encryption\&. If certificate encryption is not wanted, specify +\fB"NONE"\fR +as the argument of the +\fB\-C\fR +option\&. .PP The private key is always protected with strong encryption by default\&. .PP Several types of ciphers are supported\&. .PP -Symmetric CBC ciphers for PKCS#5 V2 +PKCS #5 password\-based encryption .RS 4 .sp .RS 4 @@ -580,110 +580,13 @@ Symmetric CBC ciphers for PKCS#5 V2 .sp -1 .IP \(bu 2.3 .\} -DES\-CBC -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -RC2\-CBC -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -RC5\-CBCPad -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -DES\-EDE3\-CBC (the default for key encryption) -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -AES\-128\-CBC -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -AES\-192\-CBC -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -AES\-256\-CBC -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -CAMELLIA\-128\-CBC -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -CAMELLIA\-192\-CBC -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -CAMELLIA\-256\-CBC +PBES2 with AES\-CBC\-Pad as underlying encryption scheme (\fB"AES\-128\-CBC"\fR, +\fB"AES\-192\-CBC"\fR, and +\fB"AES\-256\-CBC"\fR) .RE .RE .PP -PKCS#12 PBE ciphers +PKCS #12 password\-based encryption .RS 4 .sp .RS 4 @@ -694,7 +597,9 @@ PKCS#12 PBE ciphers .sp -1 .IP \(bu 2.3 .\} -PKCS #12 PBE with Sha1 and 128 Bit RC4 +SHA\-1 and 128\-bit RC4 (\fB"PKCS #12 V2 PBE With SHA\-1 And 128 Bit RC4"\fR +or +\fB"RC4"\fR) .RE .sp .RS 4 @@ -705,7 +610,7 @@ PKCS #12 PBE with Sha1 and 128 Bit RC4 .sp -1 .IP \(bu 2.3 .\} -PKCS #12 PBE with Sha1 and 40 Bit RC4 +SHA\-1 and 40\-bit RC4 (\fB"PKCS #12 V2 PBE With SHA\-1 And 40 Bit RC4"\fR) (used by default for certificate encryption in non\-FIPS mode) .RE .sp .RS 4 @@ -716,7 +621,9 @@ PKCS #12 PBE with Sha1 and 40 Bit RC4 .sp -1 .IP \(bu 2.3 .\} -PKCS #12 PBE with Sha1 and Triple DES CBC +SHA\-1 and 3\-key triple\-DES (\fB"PKCS #12 V2 PBE With SHA\-1 And 3KEY Triple DES\-CBC"\fR +or +\fB"DES\-EDE3\-CBC"\fR) .RE .sp .RS 4 @@ -727,7 +634,9 @@ PKCS #12 PBE with Sha1 and Triple DES CBC .sp -1 .IP \(bu 2.3 .\} -PKCS #12 PBE with Sha1 and 128 Bit RC2 CBC +SHA\-1 and 128\-bit RC2 (\fB"PKCS #12 V2 PBE With SHA\-1 And 128 Bit RC2 CBC"\fR +or +\fB"RC2\-CBC"\fR) .RE .sp .RS 4 @@ -738,114 +647,11 @@ PKCS #12 PBE with Sha1 and 128 Bit RC2 CBC .sp -1 .IP \(bu 2.3 .\} -PKCS #12 PBE with Sha1 and 40 Bit RC2 CBC -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -PKCS12 V2 PBE with SHA1 and 128 Bit RC4 -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -PKCS12 V2 PBE with SHA1 and 40 Bit RC4 (the default for non\-FIPS mode) -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -PKCS12 V2 PBE with SHA1 and 3KEY Triple DES\-cbc -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -PKCS12 V2 PBE with SHA1 and 2KEY Triple DES\-cbc -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -PKCS12 V2 PBE with SHA1 and 128 Bit RC2 CBC -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -PKCS12 V2 PBE with SHA1 and 40 Bit RC2 CBC +SHA\-1 and 40\-bit RC2 (\fB"PKCS #12 V2 PBE With SHA\-1 And 40 Bit RC2 CBC"\fR) .RE .RE .PP -PKCS#5 PBE ciphers -.RS 4 -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -PKCS #5 Password Based Encryption with MD2 and DES CBC -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -PKCS #5 Password Based Encryption with MD5 and DES CBC -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -PKCS #5 Password Based Encryption with SHA1 and DES CBC -.RE -.RE -.PP -With PKCS#12, the crypto provider may be the soft token module or an external hardware module\&. If the cryptographic module does not support the requested algorithm, then the next best fit will be selected (usually the default)\&. If no suitable replacement for the desired algorithm can be found, the tool returns the error +With PKCS #12, the crypto provider may be the soft token module or an external hardware module\&. If the cryptographic module does not support the requested algorithm, then the next best fit will be selected (usually the default)\&. If no suitable replacement for the desired algorithm can be found, the tool returns the error \fIno security module can perform the requested operation\fR\&. .SH "NSS DATABASE TYPES" .PP @@ -987,6 +793,27 @@ For an engineering draft on the changes in the shared NSS databases, see the NSS .\} https://wiki\&.mozilla\&.org/NSS_Shared_DB .RE +.SH "COMPATIBILITY NOTES" +.PP +The exporting behavior of +\fBpk12util\fR +has changed over time, while importing files exported with older versions of NSS is still supported\&. +.PP +Until the 3\&.30 release, +\fBpk12util\fR +used the UTF\-16 encoding for the PKCS #5 password\-based encryption schemes, while the recommendation is to encode passwords in UTF\-8 if the used encryption scheme is defined outside of the PKCS #12 standard\&. +.PP +Until the 3\&.31 release, even when +\fB"AES\-128\-CBC"\fR +or +\fB"AES\-192\-CBC"\fR +is given from the command line, +\fBpk12util\fR +always used 256\-bit AES as the underlying encryption scheme\&. +.PP +For historical reasons, +\fBpk12util\fR +accepts password\-based encryption schemes not listed in this document\&. However, those schemes are not officially supported and may have issues in interoperability with other tools\&. .SH "SEE ALSO" .PP certutil (1) diff --git a/security/nss/doc/pk12util.xml b/security/nss/doc/pk12util.xml index 03ee356e6..c26794965 100644 --- a/security/nss/doc/pk12util.xml +++ b/security/nss/doc/pk12util.xml @@ -46,7 +46,7 @@ <refsection id="description"> <title>Description</title> - <para>The PKCS #12 utility, <command>pk12util</command>, enables sharing certificates among any server that supports PKCS#12. The tool can import certificates and keys from PKCS#12 files into security databases, export certificates, and list certificates and keys.</para> + <para>The PKCS #12 utility, <command>pk12util</command>, enables sharing certificates among any server that supports PKCS #12. The tool can import certificates and keys from PKCS #12 files into security databases, export certificates, and list certificates and keys.</para> </refsection> <refsection id="options"> @@ -55,17 +55,17 @@ <variablelist> <varlistentry> <term>-i p12file</term> - <listitem><para>Import keys and certificates from a PKCS#12 file into a security database.</para></listitem> + <listitem><para>Import keys and certificates from a PKCS #12 file into a security database.</para></listitem> </varlistentry> <varlistentry> <term>-l p12file</term> - <listitem><para>List the keys and certificates in PKCS#12 file.</para></listitem> + <listitem><para>List the keys and certificates in PKCS #12 file.</para></listitem> </varlistentry> <varlistentry> <term>-o p12file</term> - <listitem><para>Export keys and certificates from the security database to a PKCS#12 file.</para></listitem> + <listitem><para>Export keys and certificates from the security database to a PKCS #12 file.</para></listitem> </varlistentry> </variablelist> @@ -78,7 +78,7 @@ <varlistentry> <term>-C certCipher</term> - <listitem><para>Specify the key cert (overall package) encryption algorithm.</para></listitem> + <listitem><para>Specify the certiticate encryption algorithm.</para></listitem> </varlistentry> <varlistentry> @@ -233,7 +233,7 @@ <refsection id="examples"> <title>Examples</title> <para><command>Importing Keys and Certificates</command></para> - <para>The most basic usage of <command>pk12util</command> for importing a certificate or key is the PKCS#12 input file (<option>-i</option>) and some way to specify the security database being accessed (either <option>-d</option> for a directory or <option>-h</option> for a token). + <para>The most basic usage of <command>pk12util</command> for importing a certificate or key is the PKCS #12 input file (<option>-i</option>) and some way to specify the security database being accessed (either <option>-d</option> for a directory or <option>-h</option> for a token). </para> <para> pk12util -i p12File [-h tokenname] [-v] [-d [sql:]directory] [-P dbprefix] [-k slotPasswordFile|-K slotPassword] [-w p12filePasswordFile|-W p12filePassword] @@ -252,7 +252,7 @@ Enter password for PKCS12 file: pk12util: PKCS12 IMPORT SUCCESSFUL</programlisting> <para><command>Exporting Keys and Certificates</command></para> - <para>Using the <command>pk12util</command> command to export certificates and keys requires both the name of the certificate to extract from the database (<option>-n</option>) and the PKCS#12-formatted output file to write to. There are optional parameters that can be used to encrypt the file to protect the certificate material. + <para>Using the <command>pk12util</command> command to export certificates and keys requires both the name of the certificate to extract from the database (<option>-n</option>) and the PKCS #12-formatted output file to write to. There are optional parameters that can be used to encrypt the file to protect the certificate material. </para> <para>pk12util -o p12File -n certname [-c keyCipher] [-C certCipher] [-m|--key_len keyLen] [-n|--cert_key_len certKeyLen] [-d [sql:]directory] [-P dbprefix] [-k slotPasswordFile|-K slotPassword] [-w p12filePasswordFile|-W p12filePassword]</para> <para>For example:</para> @@ -304,58 +304,34 @@ Certificate Friendly Name: Thawte Freemail Member's Thawte Consulting (Pty) L <refsection id="encryption"> <title>Password Encryption</title> - <para>PKCS#12 provides for not only the protection of the private keys but also the certificate and meta-data associated with the keys. Password-based encryption is used to protect private keys on export to a PKCS#12 file and, optionally, the entire package. If no algorithm is specified, the tool defaults to using <command>PKCS12 V2 PBE with SHA1 and 3KEY Triple DES-cbc</command> for private key encryption. <command>PKCS12 V2 PBE with SHA1 and 40 Bit RC4</command> is the default for the overall package encryption when not in FIPS mode. When in FIPS mode, there is no package encryption.</para> + <para>PKCS #12 provides for not only the protection of the private keys but also the certificate and meta-data associated with the keys. Password-based encryption is used to protect private keys on export to a PKCS #12 file and, optionally, the associated certificates. If no algorithm is specified, the tool defaults to using PKCS #12 SHA-1 and 3-key triple DES for private key encryption. When not in FIPS mode, PKCS #12 SHA-1 and 40-bit RC4 is used for certificate encryption. When in FIPS mode, there is no certificate encryption. If certificate encryption is not wanted, specify <userinput>"NONE"</userinput> as the argument of the <option>-C</option> option.</para> <para>The private key is always protected with strong encryption by default.</para> <para>Several types of ciphers are supported.</para> <variablelist> <varlistentry> - <term>Symmetric CBC ciphers for PKCS#5 V2</term> + <term>PKCS #5 password-based encryption</term> <listitem> - <itemizedlist> - <listitem><para>DES-CBC</para></listitem> - <listitem><para>RC2-CBC</para></listitem> - <listitem><para>RC5-CBCPad</para></listitem> - <listitem><para>DES-EDE3-CBC (the default for key encryption)</para></listitem> - <listitem><para>AES-128-CBC</para></listitem> - <listitem><para>AES-192-CBC</para></listitem> - <listitem><para>AES-256-CBC</para></listitem> - <listitem><para>CAMELLIA-128-CBC</para></listitem> - <listitem><para>CAMELLIA-192-CBC</para></listitem> - <listitem><para>CAMELLIA-256-CBC</para></listitem> - </itemizedlist> + <itemizedlist> + <listitem><para>PBES2 with AES-CBC-Pad as underlying encryption scheme (<userinput>"AES-128-CBC"</userinput>, <userinput>"AES-192-CBC"</userinput>, and <userinput>"AES-256-CBC"</userinput>)</para></listitem> + </itemizedlist> </listitem> </varlistentry> <varlistentry> - <term>PKCS#12 PBE ciphers</term> + <term>PKCS #12 password-based encryption</term> <listitem> - <itemizedlist> - <listitem><para>PKCS #12 PBE with Sha1 and 128 Bit RC4</para></listitem> - <listitem><para>PKCS #12 PBE with Sha1 and 40 Bit RC4</para></listitem> - <listitem><para>PKCS #12 PBE with Sha1 and Triple DES CBC</para></listitem> - <listitem><para>PKCS #12 PBE with Sha1 and 128 Bit RC2 CBC</para></listitem> - <listitem><para>PKCS #12 PBE with Sha1 and 40 Bit RC2 CBC</para></listitem> - <listitem><para>PKCS12 V2 PBE with SHA1 and 128 Bit RC4</para></listitem> - <listitem><para>PKCS12 V2 PBE with SHA1 and 40 Bit RC4 (the default for non-FIPS mode)</para></listitem> - <listitem><para>PKCS12 V2 PBE with SHA1 and 3KEY Triple DES-cbc</para></listitem> - <listitem><para>PKCS12 V2 PBE with SHA1 and 2KEY Triple DES-cbc</para></listitem> - <listitem><para>PKCS12 V2 PBE with SHA1 and 128 Bit RC2 CBC</para></listitem> - <listitem><para>PKCS12 V2 PBE with SHA1 and 40 Bit RC2 CBC</para></listitem> - </itemizedlist> - </listitem> - </varlistentry> - <varlistentry><term>PKCS#5 PBE ciphers</term> - <listitem> - <itemizedlist> - <listitem><para>PKCS #5 Password Based Encryption with MD2 and DES CBC</para></listitem> - <listitem><para>PKCS #5 Password Based Encryption with MD5 and DES CBC</para></listitem> - <listitem><para>PKCS #5 Password Based Encryption with SHA1 and DES CBC</para></listitem> - </itemizedlist> + <itemizedlist> + <listitem><para>SHA-1 and 128-bit RC4 (<userinput>"PKCS #12 V2 PBE With SHA-1 And 128 Bit RC4"</userinput> or <userinput>"RC4"</userinput>)</para></listitem> + <listitem><para>SHA-1 and 40-bit RC4 (<userinput>"PKCS #12 V2 PBE With SHA-1 And 40 Bit RC4"</userinput>) (used by default for certificate encryption in non-FIPS mode)</para></listitem> + <listitem><para>SHA-1 and 3-key triple-DES (<userinput>"PKCS #12 V2 PBE With SHA-1 And 3KEY Triple DES-CBC"</userinput> or <userinput>"DES-EDE3-CBC"</userinput>)</para></listitem> + <listitem><para>SHA-1 and 128-bit RC2 (<userinput>"PKCS #12 V2 PBE With SHA-1 And 128 Bit RC2 CBC"</userinput> or <userinput>"RC2-CBC"</userinput>)</para></listitem> + <listitem><para>SHA-1 and 40-bit RC2 (<userinput>"PKCS #12 V2 PBE With SHA-1 And 40 Bit RC2 CBC"</userinput>)</para></listitem> + </itemizedlist> </listitem> </varlistentry> </variablelist> - <para>With PKCS#12, the crypto provider may be the soft token module or an external hardware module. If the cryptographic module does not support the requested algorithm, then the next best fit will be selected (usually the default). If no suitable replacement for the desired algorithm can be found, the tool returns the error <emphasis>no security module can perform the requested operation</emphasis>.</para> + <para>With PKCS #12, the crypto provider may be the soft token module or an external hardware module. If the cryptographic module does not support the requested algorithm, then the next best fit will be selected (usually the default). If no suitable replacement for the desired algorithm can be found, the tool returns the error <emphasis>no security module can perform the requested operation</emphasis>.</para> </refsection> <refsection id="databases"><title>NSS Database Types</title> @@ -432,6 +408,14 @@ Using the SQLite databases must be manually specified by using the <command>sql: </itemizedlist> </refsection> + <refsection id="compatibility"> + <title>Compatibility Notes</title> + <para>The exporting behavior of <command>pk12util</command> has changed over time, while importing files exported with older versions of NSS is still supported.</para> + <para>Until the 3.30 release, <command>pk12util</command> used the UTF-16 encoding for the PKCS #5 password-based encryption schemes, while the recommendation is to encode passwords in UTF-8 if the used encryption scheme is defined outside of the PKCS #12 standard.</para> + <para>Until the 3.31 release, even when <userinput>"AES-128-CBC"</userinput> or <userinput>"AES-192-CBC"</userinput> is given from the command line, <command>pk12util</command> always used 256-bit AES as the underlying encryption scheme.</para> + <para>For historical reasons, <command>pk12util</command> accepts password-based encryption schemes not listed in this document. However, those schemes are not officially supported and may have issues in interoperability with other tools.</para> + </refsection> + <refsection id="seealso"> <title>See Also</title> <para>certutil (1)</para> diff --git a/security/nss/fuzz/config/clone_libfuzzer.sh b/security/nss/fuzz/config/clone_libfuzzer.sh index f1dc2e14b..c516057d7 100644 --- a/security/nss/fuzz/config/clone_libfuzzer.sh +++ b/security/nss/fuzz/config/clone_libfuzzer.sh @@ -1,6 +1,6 @@ #!/bin/sh -LIBFUZZER_REVISION=56bd1d43451cca4b6a11d3be316bb77ab159b09d +LIBFUZZER_REVISION=6937e68f927b6aefe526fcb9db8953f497e6e74d d=$(dirname $0) $d/git-copy.sh https://chromium.googlesource.com/chromium/llvm-project/llvm/lib/Fuzzer $LIBFUZZER_REVISION $d/../libFuzzer diff --git a/security/nss/fuzz/config/git-copy.sh b/security/nss/fuzz/config/git-copy.sh index a5c7d371d..a9e817e2a 100644 --- a/security/nss/fuzz/config/git-copy.sh +++ b/security/nss/fuzz/config/git-copy.sh @@ -7,18 +7,18 @@ if [ $# -lt 3 ]; then exit 2 fi -REPO=$1 -COMMIT=$2 -DIR=$3 +REPO="$1" +COMMIT="$2" +DIR="$3" echo "Copy '$COMMIT' from '$REPO' to '$DIR'" -if [ -f $DIR/.git-copy ]; then - CURRENT=$(cat $DIR/.git-copy) - if [ $(echo -n $COMMIT | wc -c) != "40" ]; then +if [ -f "$DIR"/.git-copy ]; then + CURRENT=$(cat "$DIR"/.git-copy) + if [ $(echo -n "$COMMIT" | wc -c) != "40" ]; then # On the off chance that $COMMIT is a remote head. - ACTUAL=$(git ls-remote $REPO $COMMIT | cut -c 1-40 -) + ACTUAL=$(git ls-remote "$REPO" "$COMMIT" | cut -c 1-40 -) else - ACTUAL=$COMMIT + ACTUAL="$COMMIT" fi if [ "$CURRENT" = "$ACTUAL" ]; then echo "Up to date." @@ -26,8 +26,9 @@ if [ -f $DIR/.git-copy ]; then fi fi -git init -q $DIR -git -C $DIR fetch -q --depth=1 $REPO $COMMIT:git-copy-tmp -git -C $DIR reset --hard git-copy-tmp -git -C $DIR rev-parse --verify HEAD > $DIR/.git-copy -rm -rf $DIR/.git +rm -rf "$DIR" +git init -q "$DIR" +git -C "$DIR" fetch -q --depth=1 "$REPO" "$COMMIT":git-copy-tmp +git -C "$DIR" reset --hard git-copy-tmp +git -C "$DIR" rev-parse --verify HEAD > "$DIR"/.git-copy +rm -rf "$DIR"/.git diff --git a/security/nss/fuzz/mpi_expmod_target.cc b/security/nss/fuzz/mpi_expmod_target.cc index ed31da354..b9be5854f 100644 --- a/security/nss/fuzz/mpi_expmod_target.cc +++ b/security/nss/fuzz/mpi_expmod_target.cc @@ -19,6 +19,15 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { auto modulus = get_modulus(data, size, ctx); // Compare with OpenSSL exp mod m1 = &std::get<1>(modulus); + // The exponent b (B) can get really big. Make it smaller if necessary. + if (MP_USED(&b) > 100) { + size_t shift = (MP_USED(&b) - 100) * MP_DIGIT_BIT; + mp_div_2d(&b, shift, &b, nullptr); + BN_rshift(B, B, shift); + } + check_equal(A, &a, max_size); + check_equal(B, &b, max_size); + check_equal(std::get<0>(modulus), m1, 3 * max_size); assert(mp_exptmod(&a, &b, m1, &c) == MP_OKAY); (void)BN_mod_exp(C, A, B, std::get<0>(modulus), ctx); check_equal(C, &c, 2 * max_size); diff --git a/security/nss/fuzz/mpi_helper.cc b/security/nss/fuzz/mpi_helper.cc index 65cf4b9cd..d092fdb11 100644 --- a/security/nss/fuzz/mpi_helper.cc +++ b/security/nss/fuzz/mpi_helper.cc @@ -12,6 +12,12 @@ char *to_char(const uint8_t *x) { return reinterpret_cast<char *>(const_cast<unsigned char *>(x)); } +void print_bn(std::string label, BIGNUM *x) { + char *xc = BN_bn2hex(x); + std::cout << label << ": " << std::hex << xc << std::endl; + OPENSSL_free(xc); +} + // Check that the two numbers are equal. void check_equal(BIGNUM *b, mp_int *m, size_t max_size) { char *bnBc = BN_bn2hex(b); diff --git a/security/nss/fuzz/mpi_helper.h b/security/nss/fuzz/mpi_helper.h index 17383744b..ef7041b25 100644 --- a/security/nss/fuzz/mpi_helper.h +++ b/security/nss/fuzz/mpi_helper.h @@ -23,6 +23,7 @@ void parse_input(const uint8_t *data, size_t size, BIGNUM *A, BIGNUM *B, void parse_input(const uint8_t *data, size_t size, BIGNUM *A, mp_int *a); std::tuple<BIGNUM *, mp_int> get_modulus(const uint8_t *data, size_t size, BN_CTX *ctx); +void print_bn(std::string label, BIGNUM *x); // Initialise MPI and BN variables // XXX: Also silence unused variable warnings for R. diff --git a/security/nss/fuzz/tls_mutators.cc b/security/nss/fuzz/tls_mutators.cc index e9770cb39..228bd0bb7 100644 --- a/security/nss/fuzz/tls_mutators.cc +++ b/security/nss/fuzz/tls_mutators.cc @@ -2,11 +2,14 @@ * 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 <algorithm> #include "shared.h" #include "tls_parser.h" #include "ssl.h" +extern "C" { #include "sslimpl.h" +} using namespace nss_test; @@ -39,7 +42,9 @@ class Record { void truncate(size_t length) { assert(length >= 5 + gExtraHeaderBytes); uint8_t *dest = const_cast<uint8_t *>(data_); - (void)ssl_EncodeUintX(length - 5 - gExtraHeaderBytes, 2, &dest[3]); + size_t l = length - (5 + gExtraHeaderBytes); + dest[3] = (l >> 8) & 0xff; + dest[4] = l & 0xff; memmove(dest + length, data_ + size_, remaining_); } @@ -222,8 +227,8 @@ size_t FragmentRecord(uint8_t *data, size_t size, size_t max_size, } // Pick a record to fragment at random. - std::uniform_int_distribution<size_t> dist(0, records.size() - 1); - auto &rec = records.at(dist(rng)); + std::uniform_int_distribution<size_t> rand_record(0, records.size() - 1); + auto &rec = records.at(rand_record(rng)); uint8_t *rdata = const_cast<uint8_t *>(rec->data()); size_t length = rec->size(); size_t content_length = length - 5; @@ -233,17 +238,21 @@ size_t FragmentRecord(uint8_t *data, size_t size, size_t max_size, } // Assign a new length to the first fragment. - size_t new_length = content_length / 2; - uint8_t *content = ssl_EncodeUintX(new_length, 2, &rdata[3]); + std::uniform_int_distribution<size_t> rand_size(1, content_length - 1); + size_t first_length = rand_size(rng); + size_t second_length = content_length - first_length; + rdata[3] = (first_length >> 8) & 0xff; + rdata[4] = first_length & 0xff; + uint8_t *second_record = rdata + 5 + first_length; - // Make room for one more header. - memmove(content + new_length + 5, content + new_length, - rec->remaining() + content_length - new_length); + // Make room for the header of the second record. + memmove(second_record + 5, second_record, + rec->remaining() + content_length - first_length); // Write second header. - memcpy(content + new_length, rdata, 3); - (void)ssl_EncodeUintX(content_length - new_length, 2, - &content[new_length + 3]); + memcpy(second_record, rdata, 3); + second_record[3] = (second_length >> 8) & 0xff; + second_record[4] = second_length & 0xff; return size + 5; } diff --git a/security/nss/fuzz/tls_socket.h b/security/nss/fuzz/tls_socket.h index 61fa4b3a8..e30f6fa3c 100644 --- a/security/nss/fuzz/tls_socket.h +++ b/security/nss/fuzz/tls_socket.h @@ -10,6 +10,7 @@ class DummyPrSocket : public DummyIOLayerMethods { public: DummyPrSocket(const uint8_t *buf, size_t len) : buf_(buf), len_(len) {} + virtual ~DummyPrSocket() {} int32_t Read(PRFileDesc *f, void *data, int32_t len) override; int32_t Write(PRFileDesc *f, const void *buf, int32_t length) override; diff --git a/security/nss/gtests/certdb_gtest/alg1485_unittest.cc b/security/nss/gtests/certdb_gtest/alg1485_unittest.cc index b7c659414..ef6733092 100644 --- a/security/nss/gtests/certdb_gtest/alg1485_unittest.cc +++ b/security/nss/gtests/certdb_gtest/alg1485_unittest.cc @@ -10,6 +10,7 @@ #include "nss.h" #include "scoped_ptrs.h" +#include "prprf.h" namespace nss_test { @@ -89,4 +90,23 @@ INSTANTIATE_TEST_CASE_P(ParseAVAStrings, Alg1485ParseTest, ::testing::ValuesIn(kAVATestStrings)); INSTANTIATE_TEST_CASE_P(CompareAVAStrings, Alg1485CompareTest, ::testing::ValuesIn(kAVACompareStrings)); + +TEST_F(Alg1485Test, ShortOIDTest) { + // This is not a valid OID (too short). CERT_GetOidString should return 0. + unsigned char data[] = {0x05}; + const SECItem oid = {siBuffer, data, sizeof(data)}; + char* result = CERT_GetOidString(&oid); + EXPECT_EQ(result, nullptr); +} + +TEST_F(Alg1485Test, BrokenOIDTest) { + // This is not a valid OID (first bit of last byte is not set). + // CERT_GetOidString should return 0. + unsigned char data[] = {0x81, 0x82, 0x83, 0x84}; + const SECItem oid = {siBuffer, data, sizeof(data)}; + char* result = CERT_GetOidString(&oid); + EXPECT_EQ(15U, strlen(result)); + EXPECT_EQ(0, strncmp("OID.UNSUPPORTED", result, 15)); + PR_smprintf_free(result); +} } diff --git a/security/nss/gtests/common/util.h b/security/nss/gtests/common/util.h index ccab5604e..7ed1fd799 100644 --- a/security/nss/gtests/common/util.h +++ b/security/nss/gtests/common/util.h @@ -10,7 +10,7 @@ #include <cassert> #include <vector> -std::vector<uint8_t> hex_string_to_bytes(std::string s) { +static inline std::vector<uint8_t> hex_string_to_bytes(std::string s) { std::vector<uint8_t> bytes; for (size_t i = 0; i < s.length(); i += 2) { bytes.push_back(std::stoul(s.substr(i, 2), nullptr, 16)); diff --git a/security/nss/cmd/certcgi/Makefile b/security/nss/gtests/cryptohi_gtest/Makefile index c2039d82b..0d547e080 100644 --- a/security/nss/cmd/certcgi/Makefile +++ b/security/nss/gtests/cryptohi_gtest/Makefile @@ -1,5 +1,5 @@ #! gmake -# +# # 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/. @@ -20,11 +20,12 @@ include $(CORE_DEPTH)/coreconf/config.mk # (3) Include "component" configuration information. (OPTIONAL) # ####################################################################### + ####################################################################### # (4) Include "local" platform-dependent assignments (OPTIONAL). # ####################################################################### -include ../platlibs.mk +include ../common/gtest.mk ####################################################################### # (5) Execute "global" rules. (OPTIONAL) # @@ -37,12 +38,6 @@ include $(CORE_DEPTH)/coreconf/rules.mk ####################################################################### - ####################################################################### # (7) Execute "local" rules. (OPTIONAL). # ####################################################################### - - - -include ../platrules.mk - diff --git a/security/nss/gtests/cryptohi_gtest/cryptohi_gtest.gyp b/security/nss/gtests/cryptohi_gtest/cryptohi_gtest.gyp new file mode 100644 index 000000000..72c815eca --- /dev/null +++ b/security/nss/gtests/cryptohi_gtest/cryptohi_gtest.gyp @@ -0,0 +1,29 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +{ + 'includes': [ + '../../coreconf/config.gypi', + '../common/gtest.gypi', + ], + 'targets': [ + { + 'target_name': 'cryptohi_gtest', + 'type': 'executable', + 'sources': [ + 'cryptohi_unittest.cc', + '<(DEPTH)/gtests/common/gtests.cc' + ], + 'dependencies': [ + '<(DEPTH)/exports.gyp:nss_exports', + '<(DEPTH)/gtests/google_test/google_test.gyp:gtest', + '<(DEPTH)/lib/util/util.gyp:nssutil3', + '<(DEPTH)/lib/ssl/ssl.gyp:ssl3', + '<(DEPTH)/lib/nss/nss.gyp:nss3', + ] + } + ], + 'variables': { + 'module': 'nss' + } +} diff --git a/security/nss/gtests/cryptohi_gtest/cryptohi_unittest.cc b/security/nss/gtests/cryptohi_gtest/cryptohi_unittest.cc new file mode 100644 index 000000000..ab553ee01 --- /dev/null +++ b/security/nss/gtests/cryptohi_gtest/cryptohi_unittest.cc @@ -0,0 +1,373 @@ +/* -*- 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 <string> + +#include "gtest/gtest.h" + +#include "scoped_ptrs.h" +#include "cryptohi.h" +#include "secitem.h" +#include "secerr.h" + +namespace nss_test { + +class SignParamsTestF : public ::testing::Test { + protected: + ScopedPLArenaPool arena_; + ScopedSECKEYPrivateKey privk_; + ScopedSECKEYPublicKey pubk_; + ScopedSECKEYPrivateKey ecPrivk_; + ScopedSECKEYPublicKey ecPubk_; + + void SetUp() { + arena_.reset(PORT_NewArena(2048)); + + SECKEYPublicKey *pubk; + SECKEYPrivateKey *privk = SECKEY_CreateRSAPrivateKey(1024, &pubk, NULL); + ASSERT_NE(nullptr, pubk); + pubk_.reset(pubk); + ASSERT_NE(nullptr, privk); + privk_.reset(privk); + + SECKEYECParams ecParams = {siBuffer, NULL, 0}; + SECOidData *oidData; + oidData = SECOID_FindOIDByTag(SEC_OID_CURVE25519); + ASSERT_NE(nullptr, oidData); + ASSERT_NE(nullptr, + SECITEM_AllocItem(NULL, &ecParams, (2 + oidData->oid.len))) + << "Couldn't allocate memory for OID."; + ecParams.data[0] = SEC_ASN1_OBJECT_ID; /* we have to prepend 0x06 */ + ecParams.data[1] = oidData->oid.len; + memcpy(ecParams.data + 2, oidData->oid.data, oidData->oid.len); + SECKEYPublicKey *ecPubk; + SECKEYPrivateKey *ecPrivk = + SECKEY_CreateECPrivateKey(&ecParams, &ecPubk, NULL); + ASSERT_NE(nullptr, ecPubk); + ecPubk_.reset(ecPubk); + ASSERT_NE(nullptr, ecPrivk); + ecPrivk_.reset(ecPrivk); + } + + void CreatePssParams(SECKEYRSAPSSParams *params, SECOidTag hashAlgTag) { + PORT_Memset(params, 0, sizeof(SECKEYRSAPSSParams)); + + params->hashAlg = (SECAlgorithmID *)PORT_ArenaZAlloc( + arena_.get(), sizeof(SECAlgorithmID)); + ASSERT_NE(nullptr, params->hashAlg); + SECStatus rv = + SECOID_SetAlgorithmID(arena_.get(), params->hashAlg, hashAlgTag, NULL); + ASSERT_EQ(SECSuccess, rv); + } + + void CreatePssParams(SECKEYRSAPSSParams *params, SECOidTag hashAlgTag, + SECOidTag maskHashAlgTag) { + CreatePssParams(params, hashAlgTag); + + SECAlgorithmID maskHashAlg; + PORT_Memset(&maskHashAlg, 0, sizeof(maskHashAlg)); + SECStatus rv = + SECOID_SetAlgorithmID(arena_.get(), &maskHashAlg, maskHashAlgTag, NULL); + ASSERT_EQ(SECSuccess, rv); + + SECItem *maskHashAlgItem = + SEC_ASN1EncodeItem(arena_.get(), NULL, &maskHashAlg, + SEC_ASN1_GET(SECOID_AlgorithmIDTemplate)); + + params->maskAlg = (SECAlgorithmID *)PORT_ArenaZAlloc( + arena_.get(), sizeof(SECAlgorithmID)); + ASSERT_NE(nullptr, params->maskAlg); + + rv = SECOID_SetAlgorithmID(arena_.get(), params->maskAlg, + SEC_OID_PKCS1_MGF1, maskHashAlgItem); + ASSERT_EQ(SECSuccess, rv); + } + + void CreatePssParams(SECKEYRSAPSSParams *params, SECOidTag hashAlgTag, + SECOidTag maskHashAlgTag, unsigned long saltLength) { + CreatePssParams(params, hashAlgTag, maskHashAlgTag); + + SECItem *saltLengthItem = + SEC_ASN1EncodeInteger(arena_.get(), ¶ms->saltLength, saltLength); + ASSERT_EQ(¶ms->saltLength, saltLengthItem); + } + + void CheckHashAlg(SECKEYRSAPSSParams *params, SECOidTag hashAlgTag) { + // If hash algorithm is SHA-1, it must be omitted in the parameters + if (hashAlgTag == SEC_OID_SHA1) { + EXPECT_EQ(nullptr, params->hashAlg); + } else { + EXPECT_NE(nullptr, params->hashAlg); + EXPECT_EQ(hashAlgTag, SECOID_GetAlgorithmTag(params->hashAlg)); + } + } + + void CheckMaskAlg(SECKEYRSAPSSParams *params, SECOidTag hashAlgTag) { + SECStatus rv; + + // If hash algorithm is SHA-1, it must be omitted in the parameters + if (hashAlgTag == SEC_OID_SHA1) + EXPECT_EQ(nullptr, params->hashAlg); + else { + EXPECT_NE(nullptr, params->maskAlg); + EXPECT_EQ(SEC_OID_PKCS1_MGF1, SECOID_GetAlgorithmTag(params->maskAlg)); + + SECAlgorithmID hashAlg; + rv = SEC_QuickDERDecodeItem(arena_.get(), &hashAlg, + SEC_ASN1_GET(SECOID_AlgorithmIDTemplate), + ¶ms->maskAlg->parameters); + ASSERT_EQ(SECSuccess, rv); + + EXPECT_EQ(hashAlgTag, SECOID_GetAlgorithmTag(&hashAlg)); + } + } + + void CheckSaltLength(SECKEYRSAPSSParams *params, SECOidTag hashAlg) { + // If the salt length parameter is missing, that means it is 20 (default) + if (!params->saltLength.data) { + return; + } + + unsigned long value; + SECStatus rv = SEC_ASN1DecodeInteger(¶ms->saltLength, &value); + ASSERT_EQ(SECSuccess, rv); + + // The salt length are usually the same as the hash length, + // except for the case where the hash length exceeds the limit + // set by the key length + switch (hashAlg) { + case SEC_OID_SHA1: + EXPECT_EQ(20UL, value); + break; + case SEC_OID_SHA224: + EXPECT_EQ(28UL, value); + break; + case SEC_OID_SHA256: + EXPECT_EQ(32UL, value); + break; + case SEC_OID_SHA384: + EXPECT_EQ(48UL, value); + break; + case SEC_OID_SHA512: + // Truncated from 64, because our private key is 1024-bit + EXPECT_EQ(62UL, value); + break; + default: + FAIL(); + } + } +}; + +class SignParamsTest + : public SignParamsTestF, + public ::testing::WithParamInterface<std::tuple<SECOidTag, SECOidTag>> {}; + +class SignParamsSourceTest : public SignParamsTestF, + public ::testing::WithParamInterface<SECOidTag> {}; + +TEST_P(SignParamsTest, CreateRsa) { + SECOidTag hashAlg = std::get<0>(GetParam()); + SECOidTag srcHashAlg = std::get<1>(GetParam()); + + SECItem *srcParams; + if (srcHashAlg != SEC_OID_UNKNOWN) { + SECKEYRSAPSSParams pssParams; + ASSERT_NO_FATAL_FAILURE( + CreatePssParams(&pssParams, srcHashAlg, srcHashAlg)); + srcParams = SEC_ASN1EncodeItem(arena_.get(), nullptr, &pssParams, + SEC_ASN1_GET(SECKEY_RSAPSSParamsTemplate)); + ASSERT_NE(nullptr, srcParams); + } else { + srcParams = NULL; + } + + SECItem *params = SEC_CreateSignatureAlgorithmParameters( + arena_.get(), nullptr, SEC_OID_PKCS1_RSA_ENCRYPTION, hashAlg, srcParams, + privk_.get()); + + // PKCS#1 RSA actually doesn't take any parameters, but if it is + // given, return a copy of it + if (srcHashAlg != SEC_OID_UNKNOWN) { + EXPECT_EQ(srcParams->len, params->len); + EXPECT_EQ(0, memcmp(params->data, srcParams->data, srcParams->len)); + } else { + EXPECT_EQ(nullptr, params); + } +} + +TEST_P(SignParamsTest, CreateRsaPss) { + SECOidTag hashAlg = std::get<0>(GetParam()); + SECOidTag srcHashAlg = std::get<1>(GetParam()); + + SECItem *srcParams; + if (srcHashAlg != SEC_OID_UNKNOWN) { + SECKEYRSAPSSParams pssParams; + ASSERT_NO_FATAL_FAILURE( + CreatePssParams(&pssParams, srcHashAlg, srcHashAlg)); + srcParams = SEC_ASN1EncodeItem(arena_.get(), nullptr, &pssParams, + SEC_ASN1_GET(SECKEY_RSAPSSParamsTemplate)); + ASSERT_NE(nullptr, srcParams); + } else { + srcParams = NULL; + } + + SECItem *params = SEC_CreateSignatureAlgorithmParameters( + arena_.get(), nullptr, SEC_OID_PKCS1_RSA_PSS_SIGNATURE, hashAlg, + srcParams, privk_.get()); + + if (hashAlg != SEC_OID_UNKNOWN && srcHashAlg != SEC_OID_UNKNOWN && + hashAlg != srcHashAlg) { + EXPECT_EQ(nullptr, params); + return; + } + + EXPECT_NE(nullptr, params); + + SECKEYRSAPSSParams pssParams; + PORT_Memset(&pssParams, 0, sizeof(pssParams)); + SECStatus rv = + SEC_QuickDERDecodeItem(arena_.get(), &pssParams, + SEC_ASN1_GET(SECKEY_RSAPSSParamsTemplate), params); + ASSERT_EQ(SECSuccess, rv); + + if (hashAlg == SEC_OID_UNKNOWN) { + if (!pssParams.hashAlg) { + hashAlg = SEC_OID_SHA1; + } else { + hashAlg = SECOID_GetAlgorithmTag(pssParams.hashAlg); + } + + if (srcHashAlg == SEC_OID_UNKNOWN) { + // If both hashAlg and srcHashAlg is unset, NSS will decide the hash + // algorithm based on the key length; in this case it's SHA256 + EXPECT_EQ(SEC_OID_SHA256, hashAlg); + } else { + EXPECT_EQ(srcHashAlg, hashAlg); + } + } + + ASSERT_NO_FATAL_FAILURE(CheckHashAlg(&pssParams, hashAlg)); + ASSERT_NO_FATAL_FAILURE(CheckMaskAlg(&pssParams, hashAlg)); + ASSERT_NO_FATAL_FAILURE(CheckSaltLength(&pssParams, hashAlg)); + + // The default trailer field (1) must be omitted + EXPECT_EQ(nullptr, pssParams.trailerField.data); +} + +TEST_P(SignParamsTest, CreateRsaPssWithECPrivateKey) { + SECOidTag hashAlg = std::get<0>(GetParam()); + SECOidTag srcHashAlg = std::get<1>(GetParam()); + + SECItem *srcParams; + if (srcHashAlg != SEC_OID_UNKNOWN) { + SECKEYRSAPSSParams pssParams; + ASSERT_NO_FATAL_FAILURE( + CreatePssParams(&pssParams, srcHashAlg, srcHashAlg)); + srcParams = SEC_ASN1EncodeItem(arena_.get(), nullptr, &pssParams, + SEC_ASN1_GET(SECKEY_RSAPSSParamsTemplate)); + ASSERT_NE(nullptr, srcParams); + } else { + srcParams = NULL; + } + + SECItem *params = SEC_CreateSignatureAlgorithmParameters( + arena_.get(), nullptr, SEC_OID_PKCS1_RSA_PSS_SIGNATURE, hashAlg, + srcParams, ecPrivk_.get()); + + EXPECT_EQ(nullptr, params); +} + +TEST_P(SignParamsTest, CreateRsaPssWithInvalidHashAlg) { + SECOidTag srcHashAlg = std::get<1>(GetParam()); + + SECItem *srcParams; + if (srcHashAlg != SEC_OID_UNKNOWN) { + SECKEYRSAPSSParams pssParams; + ASSERT_NO_FATAL_FAILURE( + CreatePssParams(&pssParams, srcHashAlg, srcHashAlg)); + srcParams = SEC_ASN1EncodeItem(arena_.get(), nullptr, &pssParams, + SEC_ASN1_GET(SECKEY_RSAPSSParamsTemplate)); + ASSERT_NE(nullptr, srcParams); + } else { + srcParams = NULL; + } + + SECItem *params = SEC_CreateSignatureAlgorithmParameters( + arena_.get(), nullptr, SEC_OID_PKCS1_RSA_PSS_SIGNATURE, SEC_OID_MD5, + srcParams, privk_.get()); + + EXPECT_EQ(nullptr, params); +} + +TEST_P(SignParamsSourceTest, CreateRsaPssWithInvalidHashAlg) { + SECOidTag hashAlg = GetParam(); + + SECItem *srcParams; + SECKEYRSAPSSParams pssParams; + ASSERT_NO_FATAL_FAILURE( + CreatePssParams(&pssParams, SEC_OID_MD5, SEC_OID_MD5)); + srcParams = SEC_ASN1EncodeItem(arena_.get(), nullptr, &pssParams, + SEC_ASN1_GET(SECKEY_RSAPSSParamsTemplate)); + ASSERT_NE(nullptr, srcParams); + + SECItem *params = SEC_CreateSignatureAlgorithmParameters( + arena_.get(), nullptr, SEC_OID_PKCS1_RSA_PSS_SIGNATURE, hashAlg, + srcParams, privk_.get()); + + EXPECT_EQ(nullptr, params); +} + +TEST_P(SignParamsSourceTest, CreateRsaPssWithInvalidSaltLength) { + SECOidTag hashAlg = GetParam(); + + SECItem *srcParams; + SECKEYRSAPSSParams pssParams; + ASSERT_NO_FATAL_FAILURE( + CreatePssParams(&pssParams, SEC_OID_SHA512, SEC_OID_SHA512, 100)); + srcParams = SEC_ASN1EncodeItem(arena_.get(), nullptr, &pssParams, + SEC_ASN1_GET(SECKEY_RSAPSSParamsTemplate)); + ASSERT_NE(nullptr, srcParams); + + SECItem *params = SEC_CreateSignatureAlgorithmParameters( + arena_.get(), nullptr, SEC_OID_PKCS1_RSA_PSS_SIGNATURE, hashAlg, + srcParams, privk_.get()); + + EXPECT_EQ(nullptr, params); +} + +TEST_P(SignParamsSourceTest, CreateRsaPssWithHashMismatch) { + SECOidTag hashAlg = GetParam(); + + SECItem *srcParams; + SECKEYRSAPSSParams pssParams; + ASSERT_NO_FATAL_FAILURE( + CreatePssParams(&pssParams, SEC_OID_SHA256, SEC_OID_SHA512)); + srcParams = SEC_ASN1EncodeItem(arena_.get(), nullptr, &pssParams, + SEC_ASN1_GET(SECKEY_RSAPSSParamsTemplate)); + ASSERT_NE(nullptr, srcParams); + + SECItem *params = SEC_CreateSignatureAlgorithmParameters( + arena_.get(), nullptr, SEC_OID_PKCS1_RSA_PSS_SIGNATURE, hashAlg, + srcParams, privk_.get()); + + EXPECT_EQ(nullptr, params); +} + +INSTANTIATE_TEST_CASE_P( + SignParamsTestCases, SignParamsTest, + ::testing::Combine(::testing::Values(SEC_OID_UNKNOWN, SEC_OID_SHA1, + SEC_OID_SHA224, SEC_OID_SHA256, + SEC_OID_SHA384, SEC_OID_SHA512), + ::testing::Values(SEC_OID_UNKNOWN, SEC_OID_SHA1, + SEC_OID_SHA224, SEC_OID_SHA256, + SEC_OID_SHA384, SEC_OID_SHA512))); + +INSTANTIATE_TEST_CASE_P(SignParamsSourceTestCases, SignParamsSourceTest, + ::testing::Values(SEC_OID_UNKNOWN, SEC_OID_SHA1, + SEC_OID_SHA224, SEC_OID_SHA256, + SEC_OID_SHA384, SEC_OID_SHA512)); + +} // namespace nss_test diff --git a/security/nss/gtests/cryptohi_gtest/manifest.mn b/security/nss/gtests/cryptohi_gtest/manifest.mn new file mode 100644 index 000000000..644463aa6 --- /dev/null +++ b/security/nss/gtests/cryptohi_gtest/manifest.mn @@ -0,0 +1,22 @@ +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +CORE_DEPTH = ../.. +DEPTH = ../.. +MODULE = nss + +CPPSRCS = \ + cryptohi_unittest.cc \ + $(NULL) + +INCLUDES += -I$(CORE_DEPTH)/gtests/google_test/gtest/include \ + -I$(CORE_DEPTH)/gtests/common \ + -I$(CORE_DEPTH)/cpputil + +REQUIRES = nspr gtest + +PROGRAM = cryptohi_gtest + +EXTRA_LIBS = $(DIST)/lib/$(LIB_PREFIX)gtest.$(LIB_SUFFIX) $(EXTRA_OBJS) \ + $(DIST)/lib/$(LIB_PREFIX)gtestutil.$(LIB_SUFFIX) diff --git a/security/nss/gtests/der_gtest/der_gtest.gyp b/security/nss/gtests/der_gtest/der_gtest.gyp index 9a382912e..2df9242d3 100644 --- a/security/nss/gtests/der_gtest/der_gtest.gyp +++ b/security/nss/gtests/der_gtest/der_gtest.gyp @@ -13,6 +13,7 @@ 'sources': [ 'der_getint_unittest.cc', 'der_quickder_unittest.cc', + 'p12_import_unittest.cc', '<(DEPTH)/gtests/common/gtests.cc' ], 'dependencies': [ @@ -21,6 +22,8 @@ '<(DEPTH)/lib/util/util.gyp:nssutil3', '<(DEPTH)/lib/ssl/ssl.gyp:ssl3', '<(DEPTH)/lib/nss/nss.gyp:nss3', + '<(DEPTH)/lib/pkcs12/pkcs12.gyp:pkcs12', + '<(DEPTH)/lib/pkcs7/pkcs7.gyp:pkcs7', ] } ], diff --git a/security/nss/gtests/der_gtest/manifest.mn b/security/nss/gtests/der_gtest/manifest.mn index a61d0f104..f0d6b519f 100644 --- a/security/nss/gtests/der_gtest/manifest.mn +++ b/security/nss/gtests/der_gtest/manifest.mn @@ -9,6 +9,7 @@ MODULE = nss CPPSRCS = \ der_getint_unittest.cc \ der_quickder_unittest.cc \ + p12_import_unittest.cc \ $(NULL) INCLUDES += -I$(CORE_DEPTH)/gtests/google_test/gtest/include \ diff --git a/security/nss/gtests/der_gtest/p12_import_unittest.cc b/security/nss/gtests/der_gtest/p12_import_unittest.cc new file mode 100644 index 000000000..6ffcda348 --- /dev/null +++ b/security/nss/gtests/der_gtest/p12_import_unittest.cc @@ -0,0 +1,251 @@ +/* -*- 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 "nss.h" +#include "p12.h" + +#include "gtest/gtest.h" +#include "scoped_ptrs.h" + +namespace nss_test { + +static const uint8_t cert_p12[] = { + 0x30, 0x82, 0x0a, 0x1f, 0x02, 0x01, 0x03, 0x30, 0x82, 0x09, 0xe5, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, + 0x09, 0xd6, 0x04, 0x82, 0x09, 0xd2, 0x30, 0x82, 0x09, 0xce, 0x30, 0x82, + 0x04, 0x42, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, + 0x06, 0xa0, 0x82, 0x04, 0x33, 0x30, 0x82, 0x04, 0x2f, 0x02, 0x01, 0x00, + 0x30, 0x82, 0x04, 0x28, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x07, 0x01, 0x30, 0x57, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x05, 0x0d, 0x30, 0x4a, 0x30, 0x29, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05, 0x0c, 0x30, 0x1c, 0x04, 0x08, 0x05, + 0x66, 0xc7, 0x5c, 0x27, 0x4e, 0x15, 0xd9, 0x02, 0x02, 0x08, 0x00, 0x30, + 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x09, 0x05, + 0x00, 0x30, 0x1d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, + 0x01, 0x2a, 0x04, 0x10, 0x4e, 0x61, 0xa7, 0x23, 0xc4, 0x3b, 0x37, 0xea, + 0xba, 0xe9, 0x9f, 0x44, 0x8e, 0x5e, 0xf7, 0xf2, 0x80, 0x82, 0x03, 0xc0, + 0x76, 0x7d, 0x91, 0x89, 0xe1, 0x04, 0x59, 0x91, 0x0c, 0x72, 0x14, 0x93, + 0xc4, 0x37, 0xe8, 0xd1, 0xbb, 0x49, 0xfc, 0x23, 0x49, 0x19, 0x6f, 0xc9, + 0x05, 0x08, 0x52, 0xd8, 0x63, 0xdf, 0x27, 0x63, 0x24, 0x85, 0x73, 0x11, + 0xfa, 0x6d, 0xca, 0xed, 0xb2, 0x91, 0x77, 0xc6, 0x1f, 0x0b, 0xdb, 0x4d, + 0x66, 0x34, 0xb9, 0x51, 0xef, 0xf0, 0x8f, 0xf8, 0x71, 0x2b, 0x68, 0xf7, + 0x5c, 0xdf, 0x99, 0x21, 0x7c, 0xb6, 0xa7, 0x45, 0xdb, 0x71, 0x69, 0x0b, + 0xb3, 0x2e, 0xff, 0x84, 0xcd, 0xd1, 0xb8, 0x87, 0xe9, 0xaa, 0x3e, 0xcd, + 0x11, 0x90, 0xcb, 0xd8, 0xe7, 0x08, 0x87, 0x32, 0x82, 0x26, 0x69, 0x9b, + 0xa6, 0xb1, 0x76, 0xf2, 0x28, 0xe2, 0x6c, 0xf5, 0x50, 0x16, 0x2d, 0x13, + 0x75, 0x73, 0xed, 0xd1, 0x40, 0x1b, 0xd9, 0x43, 0xf5, 0x1d, 0x60, 0x98, + 0x33, 0x5e, 0x18, 0xb0, 0xba, 0xe0, 0x8a, 0xaa, 0xa4, 0x3b, 0x78, 0x49, + 0x59, 0x5f, 0xa4, 0xd5, 0xb5, 0x10, 0xb8, 0x87, 0x46, 0x48, 0xff, 0x5e, + 0x91, 0x3b, 0xf9, 0xef, 0x29, 0x92, 0x99, 0xfd, 0x22, 0x8c, 0xcd, 0x05, + 0x2e, 0x0a, 0x24, 0xbf, 0xe4, 0x1b, 0x95, 0x86, 0x94, 0xf2, 0xd9, 0x8c, + 0x4d, 0xac, 0xe8, 0xb8, 0x49, 0x93, 0x74, 0xcd, 0x79, 0x3f, 0xa4, 0x29, + 0x09, 0x5a, 0x00, 0x44, 0xfe, 0x75, 0x53, 0x23, 0x7e, 0xe4, 0xf5, 0x71, + 0xcf, 0x1e, 0x48, 0x1d, 0x89, 0x42, 0x67, 0xa6, 0x1d, 0x0d, 0x0b, 0xe0, + 0x4a, 0x7a, 0x59, 0xe0, 0x88, 0x63, 0xfc, 0x72, 0x97, 0xc2, 0x9f, 0x5d, + 0xc3, 0xb2, 0x75, 0x73, 0x25, 0x10, 0x6f, 0x40, 0x93, 0x4f, 0x7d, 0x69, + 0x01, 0x2d, 0xf4, 0xbe, 0xa9, 0xd9, 0x3c, 0x83, 0x77, 0x92, 0xf4, 0xa1, + 0x2a, 0x7d, 0x3e, 0xab, 0x2d, 0xa1, 0x53, 0x63, 0x98, 0xaf, 0xc6, 0x11, + 0x78, 0x3d, 0x37, 0xa9, 0x3f, 0x9c, 0xa8, 0xce, 0xc1, 0x9f, 0xac, 0x45, + 0x9a, 0x2e, 0x38, 0x9f, 0x08, 0xf9, 0x2d, 0x9e, 0xf5, 0xca, 0x4d, 0x33, + 0x77, 0x89, 0x2b, 0xde, 0x32, 0x05, 0xe4, 0x39, 0x1a, 0x78, 0x06, 0x7f, + 0x74, 0x28, 0xab, 0x07, 0xbc, 0x59, 0xd0, 0x52, 0x11, 0x1b, 0x6a, 0x98, + 0x51, 0xed, 0x5c, 0xf7, 0x96, 0x59, 0xad, 0xb1, 0x48, 0x81, 0xc8, 0xde, + 0xec, 0xb0, 0x16, 0x7d, 0x61, 0x09, 0xaf, 0x36, 0xe8, 0x2d, 0xd3, 0x88, + 0x99, 0x35, 0xf2, 0x72, 0xa5, 0xfd, 0xd9, 0xbe, 0xf5, 0x6d, 0x52, 0x4f, + 0xdb, 0x65, 0x1b, 0x06, 0xfd, 0x1f, 0x61, 0xb3, 0xae, 0x03, 0x96, 0x50, + 0x96, 0xc4, 0x74, 0x28, 0x26, 0xda, 0x51, 0xc2, 0xd4, 0xff, 0xce, 0xc5, + 0x26, 0xea, 0x8c, 0xfd, 0x1e, 0x22, 0x03, 0xf0, 0xcd, 0x00, 0xf2, 0x72, + 0xf3, 0x81, 0x46, 0x1e, 0x95, 0xaf, 0xe1, 0xc1, 0x0a, 0x12, 0xfe, 0xb0, + 0x97, 0x2d, 0x40, 0xe8, 0x6d, 0xde, 0xe0, 0x9c, 0x7f, 0xad, 0x85, 0x89, + 0x28, 0x88, 0x4a, 0x64, 0xc1, 0xa4, 0x2f, 0xb6, 0x25, 0xae, 0x89, 0xb4, + 0xab, 0x02, 0xea, 0xca, 0xd6, 0x05, 0x4f, 0x3a, 0x64, 0xd0, 0xbf, 0x2d, + 0xba, 0x0a, 0x9c, 0x5a, 0xa5, 0x0b, 0xf5, 0xc7, 0x84, 0x6e, 0xb4, 0x5c, + 0x0e, 0x43, 0x96, 0xac, 0xfe, 0xc1, 0xc5, 0x3d, 0x15, 0x2b, 0x4d, 0x67, + 0x2a, 0x09, 0xd8, 0x64, 0x83, 0x13, 0x00, 0x10, 0xe1, 0x60, 0x76, 0x9b, + 0xf0, 0xa0, 0xdc, 0x8c, 0x4b, 0x4f, 0xc5, 0x93, 0xa8, 0xf8, 0xef, 0xd9, + 0x75, 0xdc, 0x62, 0xe9, 0xcf, 0xdf, 0x3f, 0x7b, 0x8d, 0x2c, 0x0e, 0x5a, + 0x99, 0xc6, 0x38, 0x4c, 0xd9, 0xfb, 0xe6, 0xb5, 0x1b, 0x6e, 0xbd, 0xae, + 0xef, 0x89, 0x71, 0x4e, 0xfd, 0x74, 0x46, 0x35, 0xf9, 0x48, 0x43, 0x11, + 0x81, 0xcd, 0x6f, 0xdc, 0xf3, 0x2e, 0x92, 0x93, 0x9e, 0xca, 0xf8, 0xfa, + 0xc6, 0x56, 0x75, 0x1e, 0x04, 0x89, 0x7d, 0x1c, 0x2e, 0xdb, 0xbd, 0x5b, + 0xec, 0xc8, 0x2d, 0xa3, 0xe2, 0x05, 0xef, 0xe9, 0x5f, 0x05, 0x4b, 0x89, + 0x82, 0x0c, 0x1e, 0x8c, 0x74, 0xe1, 0x5a, 0x67, 0xe4, 0x97, 0x9b, 0x22, + 0xd7, 0xdc, 0xe2, 0x74, 0xcf, 0x93, 0xc1, 0xca, 0xc6, 0xde, 0xae, 0xc0, + 0xd2, 0xf9, 0x57, 0xc5, 0x90, 0x96, 0x48, 0x0a, 0x25, 0x43, 0x75, 0xc1, + 0x94, 0xa4, 0xd5, 0x14, 0xb2, 0x27, 0xf8, 0x45, 0xf1, 0x3c, 0x01, 0xd6, + 0xb8, 0x73, 0x1c, 0xb6, 0x55, 0xc5, 0xc9, 0x10, 0x28, 0x2f, 0xba, 0x18, + 0x36, 0x8d, 0xfe, 0x0b, 0x23, 0xf3, 0x9a, 0x98, 0xfb, 0x2f, 0x59, 0x52, + 0x3a, 0x0f, 0x75, 0x60, 0xa0, 0x92, 0x0d, 0x78, 0xf0, 0xc7, 0x5d, 0x9d, + 0x3a, 0x72, 0xd0, 0xd1, 0x30, 0x73, 0x9e, 0x3c, 0x03, 0x99, 0x4c, 0xe2, + 0xe5, 0xd4, 0x77, 0xfe, 0x3a, 0x92, 0x08, 0x5b, 0x99, 0x51, 0x15, 0x57, + 0x05, 0x13, 0x51, 0xc2, 0xf4, 0xb5, 0x2d, 0xae, 0x68, 0x9f, 0x4e, 0xbf, + 0x00, 0x11, 0xc1, 0xe1, 0x48, 0xb3, 0xce, 0x36, 0x42, 0x6a, 0x74, 0xd7, + 0xe7, 0x84, 0x1e, 0xf3, 0x47, 0xc4, 0xab, 0x59, 0x18, 0x15, 0x31, 0xa4, + 0x28, 0x68, 0x16, 0xa3, 0x68, 0xbf, 0x6c, 0xfe, 0x7a, 0x36, 0xd9, 0xc1, + 0x22, 0xd6, 0x5e, 0x2d, 0xbb, 0x9a, 0x1f, 0xb6, 0x8c, 0xa6, 0x65, 0x24, + 0x3e, 0x01, 0x9c, 0x75, 0x5e, 0x17, 0x42, 0x12, 0x89, 0x85, 0x6f, 0x05, + 0xac, 0x54, 0xd5, 0x02, 0xea, 0x1e, 0xc2, 0xe1, 0xcd, 0x61, 0x0e, 0x53, + 0xd5, 0x9d, 0x3a, 0x67, 0x1b, 0x50, 0x9b, 0x90, 0x18, 0x66, 0x6d, 0xb2, + 0x7f, 0x3a, 0x69, 0xc9, 0xef, 0x07, 0x17, 0x91, 0x8a, 0xe9, 0x15, 0x35, + 0xed, 0x70, 0x9e, 0x74, 0x8c, 0xe7, 0xf4, 0xaa, 0xcf, 0xbe, 0xa3, 0x98, + 0x89, 0x8d, 0x3c, 0x5e, 0xa4, 0x6b, 0x8f, 0x1b, 0x18, 0x04, 0x79, 0xd2, + 0x11, 0x64, 0xb1, 0xc7, 0x68, 0xca, 0xaf, 0x44, 0xa1, 0x39, 0x29, 0x58, + 0x70, 0x4e, 0xce, 0xb7, 0x7a, 0x3c, 0x4b, 0xdc, 0x32, 0x92, 0x76, 0x74, + 0xab, 0x0a, 0x6f, 0x8b, 0x74, 0xf5, 0xfd, 0xed, 0x3b, 0x11, 0x95, 0xe8, + 0x10, 0x74, 0x4c, 0xd8, 0xbe, 0x0f, 0x50, 0xee, 0xa0, 0xee, 0x39, 0xd8, + 0x9f, 0xa1, 0xa0, 0x21, 0xa3, 0x47, 0x8c, 0xa6, 0xd9, 0xca, 0x8c, 0xb3, + 0x8b, 0x86, 0x9e, 0x31, 0x3b, 0xcc, 0x7f, 0xea, 0x23, 0xb1, 0x25, 0x73, + 0xfb, 0x66, 0x99, 0x28, 0xff, 0xf4, 0xe9, 0xb7, 0x19, 0x3e, 0xd5, 0xc6, + 0x5d, 0xd1, 0xaa, 0x08, 0x6f, 0xf2, 0xff, 0xab, 0x39, 0x69, 0x1f, 0xd3, + 0x6b, 0x20, 0xf3, 0x2f, 0xe4, 0xd5, 0xb8, 0x76, 0x3f, 0x6c, 0x8f, 0x05, + 0x3c, 0xe0, 0x18, 0x81, 0x82, 0xca, 0x05, 0x7f, 0xc0, 0x8e, 0x87, 0x50, + 0xfb, 0xb1, 0x65, 0xfa, 0x2f, 0xb7, 0xba, 0x20, 0x0b, 0x35, 0x5c, 0x87, + 0xba, 0x90, 0x5a, 0x7f, 0xfc, 0xe9, 0xf2, 0x98, 0x5f, 0x6e, 0xb2, 0xcc, + 0xef, 0x4b, 0x2d, 0xde, 0xdd, 0x6f, 0xd9, 0x8e, 0x79, 0x89, 0x45, 0xcd, + 0x4c, 0xdf, 0x27, 0xf1, 0x26, 0x47, 0x9e, 0x83, 0xdb, 0x73, 0x4a, 0x20, + 0x84, 0xde, 0x09, 0xe0, 0x58, 0xfe, 0x19, 0xcb, 0x92, 0xc4, 0x5b, 0x83, + 0x30, 0x82, 0x05, 0x84, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x07, 0x01, 0xa0, 0x82, 0x05, 0x75, 0x04, 0x82, 0x05, 0x71, 0x30, + 0x82, 0x05, 0x6d, 0x30, 0x82, 0x05, 0x69, 0x06, 0x0b, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x0a, 0x01, 0x02, 0xa0, 0x82, 0x05, 0x31, + 0x30, 0x82, 0x05, 0x2d, 0x30, 0x57, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x05, 0x0d, 0x30, 0x4a, 0x30, 0x29, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05, 0x0c, 0x30, 0x1c, 0x04, 0x08, + 0x5c, 0x72, 0x5e, 0xfb, 0xbc, 0x49, 0xaa, 0xa1, 0x02, 0x02, 0x08, 0x00, + 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x09, + 0x05, 0x00, 0x30, 0x1d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x01, 0x2a, 0x04, 0x10, 0xcb, 0xa8, 0xda, 0x75, 0xba, 0x64, 0x22, + 0x70, 0x39, 0x3c, 0x83, 0x35, 0x0b, 0x41, 0xc4, 0x49, 0x04, 0x82, 0x04, + 0xd0, 0xb3, 0x3d, 0x9b, 0x03, 0x34, 0xdf, 0x62, 0x37, 0xb0, 0xbb, 0x37, + 0x0d, 0x88, 0x8c, 0x6b, 0xf2, 0x46, 0x33, 0xa4, 0x4b, 0x48, 0x86, 0x0a, + 0x36, 0x37, 0x24, 0x21, 0x08, 0x8e, 0x86, 0xbf, 0x4e, 0x9c, 0xe7, 0xa9, + 0x56, 0x4a, 0x02, 0xb4, 0x74, 0x6a, 0x8a, 0x1e, 0x51, 0x91, 0xe3, 0x8f, + 0xe3, 0xf6, 0xca, 0x0a, 0x2d, 0xe7, 0x09, 0x5e, 0x1e, 0x59, 0x46, 0x01, + 0xda, 0xe9, 0x5b, 0xb9, 0xd8, 0x15, 0x7c, 0x05, 0xd9, 0x5f, 0x8c, 0x3d, + 0xd4, 0xb2, 0xff, 0x25, 0x9d, 0xfe, 0x0e, 0xe3, 0x0c, 0xf0, 0x7f, 0x30, + 0x25, 0x92, 0x0e, 0x44, 0xf4, 0x16, 0xc7, 0xa2, 0x22, 0xb2, 0x31, 0xfa, + 0x55, 0x97, 0xf7, 0xd0, 0xd7, 0x58, 0x1f, 0x96, 0x81, 0x06, 0x86, 0xbb, + 0x07, 0x30, 0x9d, 0x01, 0xb8, 0x15, 0xb2, 0x81, 0xa9, 0x35, 0x09, 0x2c, + 0x97, 0xbc, 0x8e, 0x2e, 0x2e, 0x30, 0x20, 0x51, 0x94, 0x9d, 0x9f, 0xbd, + 0x83, 0x48, 0x7b, 0x25, 0xfc, 0x95, 0x42, 0xd7, 0x29, 0xd5, 0x67, 0xcd, + 0x48, 0xc6, 0x78, 0xe1, 0x6d, 0xdf, 0xf8, 0x0b, 0x3a, 0x95, 0xcc, 0xd0, + 0x93, 0xfe, 0x23, 0x8d, 0x99, 0xd9, 0x8c, 0x67, 0x38, 0x9f, 0xd0, 0x4c, + 0xff, 0x32, 0x45, 0x32, 0xa9, 0xe8, 0x9d, 0xbc, 0xbf, 0xaa, 0xb2, 0x49, + 0xaa, 0x1d, 0xa0, 0x04, 0x53, 0x14, 0xa4, 0x77, 0x96, 0x3f, 0x17, 0xbb, + 0x2e, 0x14, 0xbe, 0x39, 0x6b, 0x69, 0x16, 0x7a, 0x99, 0xb2, 0xf4, 0x16, + 0x1a, 0xb7, 0xaa, 0x0a, 0x97, 0xd9, 0x1d, 0x62, 0xbe, 0xfc, 0x38, 0x00, + 0x6c, 0x65, 0x75, 0xe0, 0xb0, 0x65, 0x8f, 0xb6, 0x4b, 0xe7, 0x21, 0x41, + 0x65, 0x65, 0x5a, 0x7c, 0x5b, 0xe8, 0x70, 0x83, 0x71, 0xd6, 0x65, 0x7c, + 0x4f, 0x00, 0x90, 0x55, 0xca, 0xff, 0xc9, 0x3f, 0x61, 0x1e, 0xc0, 0x41, + 0x67, 0x0c, 0x71, 0xb2, 0xef, 0x12, 0x8e, 0xb1, 0xaa, 0xcf, 0xf1, 0x78, + 0x9f, 0x5b, 0xb9, 0x7b, 0xbe, 0x04, 0x39, 0xf0, 0x87, 0xca, 0x3a, 0x77, + 0x31, 0xab, 0x85, 0x8f, 0x4f, 0x06, 0xad, 0x45, 0xf2, 0xe2, 0xc2, 0x20, + 0x74, 0xf1, 0xdc, 0x21, 0x3f, 0x79, 0x0d, 0xcc, 0xcf, 0x7f, 0xb9, 0x85, + 0x9e, 0x1a, 0x1b, 0x84, 0xe2, 0x5b, 0xe3, 0x77, 0x27, 0x91, 0xcc, 0xf2, + 0xe4, 0xf2, 0x19, 0xdd, 0x98, 0x64, 0x9d, 0xcb, 0xf1, 0xc5, 0xe6, 0x7b, + 0x75, 0x55, 0x4e, 0xa5, 0xca, 0xe3, 0x5b, 0xbe, 0xc2, 0xcd, 0x83, 0x27, + 0x92, 0xe1, 0x23, 0x3f, 0xd7, 0x3d, 0xb7, 0x3a, 0x8b, 0x3a, 0x26, 0xc1, + 0xfb, 0xed, 0x69, 0x7a, 0xab, 0xec, 0x0a, 0xe5, 0xaa, 0x81, 0x9f, 0xdf, + 0x97, 0x45, 0x64, 0x35, 0x7d, 0xad, 0x88, 0x4a, 0x75, 0x13, 0xc3, 0x13, + 0xd6, 0x9a, 0xf3, 0xa2, 0x94, 0xf7, 0x96, 0x09, 0xa7, 0xbe, 0xb8, 0xe4, + 0x29, 0x7d, 0xb0, 0xef, 0x4a, 0x5d, 0x0d, 0x02, 0xb4, 0x10, 0x54, 0x17, + 0x62, 0xef, 0xe2, 0xad, 0x89, 0x6d, 0x91, 0x51, 0x7e, 0x35, 0x28, 0xb4, + 0xe7, 0x02, 0xbb, 0xcb, 0x03, 0x37, 0xa6, 0xeb, 0x55, 0x51, 0xc0, 0xc2, + 0x21, 0x7a, 0x78, 0x44, 0x44, 0x70, 0x06, 0xb0, 0x5d, 0x19, 0xaa, 0xcb, + 0xf1, 0x9f, 0xaa, 0xd3, 0x5a, 0x29, 0xc4, 0xc7, 0x7a, 0x36, 0x1d, 0x65, + 0x21, 0x52, 0xf9, 0xe2, 0xc7, 0x60, 0xd4, 0x32, 0x03, 0xdf, 0x03, 0xcc, + 0xe5, 0x7c, 0xf9, 0x15, 0xe3, 0xe6, 0x46, 0xeb, 0xa8, 0xa8, 0x6f, 0xe7, + 0x46, 0x03, 0xc7, 0x5c, 0x29, 0xf6, 0xac, 0x61, 0x2d, 0xbe, 0xa0, 0xda, + 0xdc, 0xca, 0x29, 0x35, 0x3b, 0xa0, 0x43, 0x22, 0x22, 0x61, 0x65, 0x8f, + 0x2d, 0x13, 0xce, 0x61, 0x7c, 0x27, 0x45, 0x9d, 0x9b, 0x8d, 0xd6, 0xc1, + 0xb5, 0x8c, 0x5b, 0xdb, 0xbb, 0xf6, 0x7e, 0x9a, 0xd4, 0x5c, 0x6b, 0x7e, + 0xf3, 0x6d, 0x7e, 0x45, 0x2e, 0x55, 0x7d, 0x9f, 0x62, 0xc7, 0xf4, 0x03, + 0x6f, 0xb9, 0x02, 0xcf, 0x3d, 0x07, 0xc5, 0xc8, 0xce, 0x9e, 0xac, 0x56, + 0x43, 0x8b, 0xcc, 0xf0, 0x2d, 0xc5, 0x56, 0xfa, 0x61, 0xf9, 0xee, 0x1b, + 0x89, 0xa9, 0xd6, 0xe8, 0x1e, 0xa2, 0xdf, 0xfd, 0x0d, 0x33, 0x03, 0x91, + 0xd9, 0x30, 0x4d, 0xfb, 0x2d, 0x7e, 0x5b, 0xb0, 0xb5, 0x55, 0x1e, 0x9c, + 0x13, 0x96, 0x5a, 0xa6, 0xab, 0x88, 0x79, 0xe7, 0x42, 0x31, 0xb2, 0x2d, + 0xf8, 0x40, 0x89, 0xe4, 0x96, 0x4c, 0x42, 0xc9, 0x72, 0xd1, 0x8f, 0x3f, + 0x2d, 0xee, 0x1d, 0x91, 0xe0, 0xfb, 0x1f, 0xb5, 0x94, 0x41, 0xce, 0x89, + 0xed, 0xe7, 0xec, 0xa0, 0xb6, 0xb2, 0xa2, 0x5c, 0x72, 0xa1, 0x91, 0x40, + 0x82, 0xde, 0x62, 0xba, 0x12, 0x12, 0xa1, 0xab, 0x31, 0x62, 0x38, 0x48, + 0x4c, 0x49, 0x9e, 0x6c, 0xf3, 0xf1, 0x69, 0x3e, 0x8b, 0x6a, 0x24, 0x45, + 0x99, 0x5c, 0x5a, 0xe3, 0x52, 0x24, 0xb7, 0xcf, 0xf0, 0xc8, 0x82, 0x5e, + 0x9e, 0x10, 0x29, 0xcf, 0xda, 0x01, 0xd0, 0xc0, 0x81, 0xfd, 0x56, 0x15, + 0x1c, 0x6b, 0xff, 0x78, 0x91, 0xaa, 0x47, 0x63, 0xb0, 0xe2, 0xbd, 0x67, + 0x0d, 0x24, 0xc5, 0xfd, 0x1a, 0x6a, 0x6a, 0x71, 0x9b, 0xca, 0xc4, 0xb3, + 0xc0, 0x07, 0x3d, 0xd7, 0x3b, 0xf4, 0xc0, 0xb7, 0xb5, 0xc4, 0x46, 0x85, + 0x3d, 0x22, 0x03, 0x1b, 0xcf, 0xe6, 0xce, 0x2f, 0xae, 0x41, 0xcf, 0x67, + 0x6b, 0xd3, 0x87, 0x3f, 0xca, 0x4c, 0xb7, 0x9f, 0x47, 0x36, 0xa5, 0xd7, + 0xd3, 0x70, 0xf7, 0xc4, 0x9f, 0x7d, 0xbd, 0xe4, 0xc6, 0xec, 0x7b, 0x03, + 0xca, 0xb0, 0x78, 0x06, 0xa3, 0xf1, 0xd0, 0x98, 0xdf, 0x1c, 0x60, 0x90, + 0x61, 0xcb, 0x7b, 0x68, 0xd2, 0x8e, 0x24, 0x76, 0x7b, 0xf6, 0x2f, 0xf3, + 0x7b, 0x96, 0x2d, 0x80, 0x6f, 0xae, 0xc5, 0x2b, 0xe9, 0xad, 0x78, 0x25, + 0x78, 0x4e, 0xd7, 0x81, 0xb7, 0x60, 0x20, 0x0c, 0x20, 0x46, 0xb4, 0x88, + 0xfe, 0x12, 0x0a, 0x8d, 0x7a, 0x9a, 0x0b, 0xdd, 0x6d, 0x37, 0xb3, 0xa5, + 0x99, 0x1d, 0xf2, 0xd4, 0xa6, 0x79, 0x1e, 0x89, 0x1a, 0xda, 0xe8, 0x83, + 0x24, 0xc9, 0xd9, 0x1f, 0x76, 0x82, 0xec, 0x64, 0x35, 0x6b, 0x9b, 0xfd, + 0x91, 0x31, 0x96, 0xf2, 0x8b, 0x4f, 0x30, 0xbb, 0xd9, 0xcd, 0xe0, 0x66, + 0x73, 0xfd, 0xd7, 0x05, 0x16, 0x7c, 0xed, 0x94, 0xc0, 0xa0, 0x73, 0x9e, + 0xe7, 0x85, 0xac, 0x0e, 0x20, 0xd1, 0x5e, 0x66, 0x7a, 0xef, 0x93, 0x20, + 0xd7, 0x3f, 0xb5, 0xbd, 0xb7, 0xb7, 0xcb, 0x64, 0xc8, 0xde, 0x2f, 0xd9, + 0x92, 0x5f, 0xa1, 0xb6, 0xbd, 0xd0, 0xe6, 0xb4, 0x55, 0xf4, 0xa1, 0xa8, + 0x51, 0x5e, 0x00, 0x6f, 0xaa, 0x09, 0xff, 0x56, 0xb4, 0xbc, 0xdf, 0xc1, + 0x20, 0x13, 0xc4, 0x3c, 0x48, 0xb1, 0x6d, 0xeb, 0x19, 0xb8, 0xbf, 0x4f, + 0x3d, 0x35, 0x96, 0x14, 0xc3, 0xc3, 0xef, 0x8e, 0x0b, 0x95, 0xbc, 0x78, + 0x47, 0x6a, 0x6c, 0x24, 0x10, 0xbd, 0x06, 0x13, 0x5c, 0x69, 0x7b, 0xb5, + 0x53, 0x43, 0xd1, 0x7a, 0x1d, 0x9a, 0x7f, 0x57, 0xcd, 0x81, 0xc5, 0x3f, + 0xde, 0x98, 0xb5, 0x73, 0x95, 0xd2, 0x10, 0xcf, 0x4f, 0x6a, 0xce, 0xac, + 0x35, 0x49, 0x4d, 0xf3, 0xbe, 0xbf, 0x38, 0xf2, 0xcf, 0x1b, 0x1c, 0x19, + 0x27, 0xa3, 0x3f, 0xd9, 0x35, 0xfe, 0xc2, 0xe5, 0x49, 0x16, 0x28, 0xd0, + 0x8e, 0xb9, 0x34, 0x6e, 0x8b, 0xa5, 0xe2, 0x9c, 0xbe, 0xad, 0xa1, 0x43, + 0x61, 0x2e, 0x48, 0x65, 0xb3, 0x20, 0xe7, 0x1d, 0x65, 0x00, 0x9d, 0x6e, + 0x71, 0xe7, 0x79, 0x44, 0xac, 0x0c, 0x38, 0x5a, 0x1d, 0x40, 0x06, 0x30, + 0xd0, 0xe8, 0xbe, 0x95, 0x16, 0xaf, 0xd8, 0x5f, 0x67, 0xd3, 0xb0, 0x6a, + 0xa3, 0x7c, 0xc1, 0x9b, 0x3f, 0xc7, 0xae, 0x27, 0xb1, 0xc1, 0xb5, 0xce, + 0xdf, 0xbb, 0xa4, 0x4f, 0xb4, 0x58, 0xa1, 0xb9, 0x7c, 0x9c, 0x5f, 0x26, + 0x4f, 0x13, 0xfa, 0x7c, 0x1a, 0xb7, 0x1b, 0x69, 0xd6, 0x0e, 0x1b, 0x92, + 0x31, 0x4b, 0xb4, 0x71, 0x12, 0xc8, 0xc4, 0xbd, 0x99, 0xe3, 0xc8, 0x9d, + 0x68, 0xb3, 0x38, 0x35, 0x3f, 0x16, 0xd8, 0xde, 0x01, 0x71, 0xf6, 0x66, + 0x77, 0xcb, 0xbd, 0xe2, 0x97, 0x10, 0x91, 0x41, 0x00, 0xa1, 0x0d, 0x9d, + 0x40, 0x0b, 0xfc, 0x25, 0xc8, 0x44, 0xc3, 0x78, 0xaa, 0x89, 0xd5, 0x59, + 0xe4, 0xa2, 0x9e, 0xd0, 0x85, 0xa2, 0xdd, 0x80, 0x3b, 0x35, 0x5a, 0x50, + 0x86, 0xcd, 0x72, 0xf4, 0x9d, 0x69, 0x0e, 0x2d, 0x97, 0x42, 0x09, 0x5e, + 0xa6, 0x86, 0xf7, 0x35, 0xcf, 0x9b, 0x42, 0xa7, 0x60, 0xa0, 0x71, 0x41, + 0x28, 0x35, 0x22, 0xd6, 0x55, 0xe1, 0xdb, 0xb3, 0x8e, 0x0d, 0x47, 0xb7, + 0xd6, 0x02, 0x0f, 0xb1, 0xdf, 0xb8, 0xfb, 0xd8, 0x20, 0xcf, 0x6a, 0x47, + 0x3f, 0x8a, 0x91, 0x08, 0x64, 0x08, 0xba, 0x19, 0x10, 0x1f, 0xcf, 0xe5, + 0x34, 0xf1, 0x32, 0x49, 0x3b, 0xaf, 0x18, 0x67, 0x96, 0x47, 0x7f, 0x21, + 0x8a, 0x37, 0x15, 0x5c, 0xc0, 0xe8, 0x7b, 0xd6, 0x08, 0x5b, 0x45, 0x10, + 0x1f, 0x1c, 0x7f, 0xce, 0x3b, 0x88, 0xe5, 0x0e, 0xd9, 0x00, 0xce, 0xe5, + 0x9b, 0x4b, 0x25, 0xc7, 0x11, 0x8a, 0x4f, 0x22, 0xa7, 0x31, 0x25, 0x30, + 0x23, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x15, + 0x31, 0x16, 0x04, 0x14, 0xad, 0x7f, 0xeb, 0xe6, 0xb2, 0x6c, 0xf4, 0xdc, + 0x9f, 0x4d, 0x52, 0x40, 0x07, 0x15, 0xd9, 0xe8, 0xbc, 0x0d, 0x4e, 0xd7, + 0x30, 0x31, 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, + 0x1a, 0x05, 0x00, 0x04, 0x14, 0xa4, 0xac, 0xdb, 0xa8, 0x4c, 0xe9, 0x7a, + 0x02, 0x9d, 0x07, 0x39, 0x21, 0xf0, 0x71, 0xae, 0x46, 0x5a, 0xd8, 0x13, + 0x51, 0x04, 0x08, 0xa1, 0x52, 0xdd, 0x64, 0x46, 0xe9, 0x9e, 0x3e, 0x02, + 0x02, 0x08, 0x00}; + +class PK12ImportTest : public ::testing::Test {}; + +TEST_F(PK12ImportTest, ImportPK12With2P7) { + SECItem password = {siBuffer, nullptr, 0}; + ScopedPK11SlotInfo slot(PK11_GetInternalSlot()); + ScopedSEC_PKCS12DecoderContext dcx( + SEC_PKCS12DecoderStart(&password, slot.get(), nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr)); + ASSERT_TRUE(dcx); + SECStatus rv = SEC_PKCS12DecoderUpdate( + dcx.get(), const_cast<uint8_t *>(cert_p12), sizeof(cert_p12)); + ASSERT_EQ(SECSuccess, rv); + rv = SEC_PKCS12DecoderVerify(dcx.get()); + // NSS can't properly decode this P12. But it shouldn't crash. + ASSERT_EQ(SECFailure, rv); +} + +} // namespace nss_test diff --git a/security/nss/gtests/freebl_gtest/blake2b_unittest.cc b/security/nss/gtests/freebl_gtest/blake2b_unittest.cc new file mode 100644 index 000000000..e6b0c1157 --- /dev/null +++ b/security/nss/gtests/freebl_gtest/blake2b_unittest.cc @@ -0,0 +1,277 @@ +/* + * blake2b_unittest.cc - unittests for blake2b hash function + * + * 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 "blapi.h" +#include "nspr.h" +#include "nss.h" +#include "secerr.h" + +#include <cstdlib> +#include <iostream> +#include <memory> + +#define GTEST_HAS_RTTI 0 +#include "gtest/gtest.h" + +#include "kat/blake2b_kat.h" + +template <class T> +struct ScopedDelete { + void operator()(T* ptr) { + if (ptr) { + BLAKE2B_DestroyContext(ptr, PR_TRUE); + } + } +}; + +typedef std::unique_ptr<BLAKE2BContext, ScopedDelete<BLAKE2BContext>> + ScopedBLAKE2BContext; + +class Blake2BTests : public ::testing::Test {}; + +class Blake2BKAT + : public ::testing::TestWithParam<std::pair<int, std::vector<uint8_t>>> {}; + +class Blake2BKATUnkeyed : public Blake2BKAT {}; +class Blake2BKATKeyed : public Blake2BKAT {}; + +TEST_P(Blake2BKATUnkeyed, Unkeyed) { + std::vector<uint8_t> values(BLAKE2B512_LENGTH); + SECStatus rv = + BLAKE2B_HashBuf(values.data(), kat_data.data(), std::get<0>(GetParam())); + ASSERT_EQ(SECSuccess, rv); + EXPECT_EQ(values, std::get<1>(GetParam())); +} + +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(), + BLAKE2B_KEY_SIZE); + ASSERT_EQ(SECSuccess, rv); + EXPECT_EQ(values, std::get<1>(GetParam())); +} + +INSTANTIATE_TEST_CASE_P(UnkeyedKAT, Blake2BKATUnkeyed, + ::testing::ValuesIn(TestcasesUnkeyed)); +INSTANTIATE_TEST_CASE_P(KeyedKAT, Blake2BKATKeyed, + ::testing::ValuesIn(TestcasesKeyed)); + +TEST_F(Blake2BTests, ContextTest) { + ScopedBLAKE2BContext ctx(BLAKE2B_NewContext()); + ASSERT_TRUE(ctx) << "BLAKE2B_NewContext failed!"; + + SECStatus rv = BLAKE2B_Begin(ctx.get()); + ASSERT_EQ(SECSuccess, rv); + + size_t src_length = 252; + const size_t quarter = 63; + + for (int i = 0; i < 4 && src_length > 0; i++) { + rv = BLAKE2B_Update(ctx.get(), kat_data.data() + i * quarter, + PR_MIN(quarter, src_length)); + ASSERT_EQ(SECSuccess, rv); + + size_t len = BLAKE2B_FlattenSize(ctx.get()); + std::vector<unsigned char> ctxbytes(len); + rv = BLAKE2B_Flatten(ctx.get(), ctxbytes.data()); + ASSERT_EQ(SECSuccess, rv); + ScopedBLAKE2BContext ctx_cpy(BLAKE2B_Resurrect(ctxbytes.data(), NULL)); + ASSERT_TRUE(ctx_cpy) << "BLAKE2B_Resurrect failed!"; + ASSERT_EQ(SECSuccess, PORT_Memcmp(ctx.get(), ctx_cpy.get(), len)); + src_length -= quarter; + } + ASSERT_EQ(0U, src_length); + + std::vector<uint8_t> digest(BLAKE2B512_LENGTH); + rv = BLAKE2B_End(ctx.get(), digest.data(), nullptr, BLAKE2B512_LENGTH); + ASSERT_EQ(SECSuccess, rv); + ASSERT_EQ(std::get<1>(TestcasesUnkeyed[252]), digest) + << "BLAKE2B_End failed!"; +} + +TEST_F(Blake2BTests, ContextTest2) { + ScopedBLAKE2BContext ctx(BLAKE2B_NewContext()); + ASSERT_TRUE(ctx) << "BLAKE2B_NewContext failed!"; + + SECStatus rv = BLAKE2B_Begin(ctx.get()); + ASSERT_EQ(SECSuccess, rv); + + rv = BLAKE2B_Update(ctx.get(), kat_data.data(), 128); + ASSERT_EQ(SECSuccess, rv); + rv = BLAKE2B_Update(ctx.get(), kat_data.data() + 128, 127); + ASSERT_EQ(SECSuccess, rv); + + std::vector<uint8_t> digest(BLAKE2B512_LENGTH); + rv = BLAKE2B_End(ctx.get(), digest.data(), nullptr, BLAKE2B512_LENGTH); + ASSERT_EQ(SECSuccess, rv); + ASSERT_EQ(std::get<1>(TestcasesUnkeyed[255]), digest) + << "BLAKE2B_End failed!"; +} + +TEST_F(Blake2BTests, CloneTest) { + ScopedBLAKE2BContext ctx(BLAKE2B_NewContext()); + ScopedBLAKE2BContext cloned_ctx(BLAKE2B_NewContext()); + ASSERT_TRUE(ctx) << "BLAKE2B_NewContext failed!"; + ASSERT_TRUE(cloned_ctx) << "BLAKE2B_NewContext failed!"; + + SECStatus rv = BLAKE2B_Begin(ctx.get()); + ASSERT_EQ(SECSuccess, rv); + rv = BLAKE2B_Update(ctx.get(), kat_data.data(), 255); + ASSERT_EQ(SECSuccess, rv); + BLAKE2B_Clone(cloned_ctx.get(), ctx.get()); + + std::vector<uint8_t> digest(BLAKE2B512_LENGTH); + rv = BLAKE2B_End(cloned_ctx.get(), digest.data(), nullptr, BLAKE2B512_LENGTH); + ASSERT_EQ(SECSuccess, rv); + ASSERT_EQ(std::get<1>(TestcasesUnkeyed[255]), digest) + << "BLAKE2B_End failed!"; +} + +TEST_F(Blake2BTests, NullTest) { + std::vector<uint8_t> digest(BLAKE2B512_LENGTH); + SECStatus rv = BLAKE2B_HashBuf(digest.data(), nullptr, 0); + ASSERT_EQ(SECSuccess, rv); + 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(), + BLAKE2B_KEY_SIZE); + ASSERT_EQ(SECSuccess, rv); + EXPECT_EQ(std::get<1>(TestcasesKeyed[0]), digest); +} + +TEST_F(Blake2BTests, HashTest) { + ScopedBLAKE2BContext ctx(BLAKE2B_NewContext()); + ASSERT_TRUE(ctx) << "BLAKE2B_NewContext failed!"; + + std::vector<uint8_t> digest(BLAKE2B512_LENGTH); + SECStatus rv = BLAKE2B_Hash(digest.data(), "abc"); + std::vector<uint8_t> expected = { + 0xba, 0x80, 0xa5, 0x3f, 0x98, 0x1c, 0x4d, 0x0d, 0x6a, 0x27, 0x97, + 0xb6, 0x9f, 0x12, 0xf6, 0xe9, 0x4c, 0x21, 0x2f, 0x14, 0x68, 0x5a, + 0xc4, 0xb7, 0x4b, 0x12, 0xbb, 0x6f, 0xdb, 0xff, 0xa2, 0xd1, 0x7d, + 0x87, 0xc5, 0x39, 0x2a, 0xab, 0x79, 0x2d, 0xc2, 0x52, 0xd5, 0xde, + 0x45, 0x33, 0xcc, 0x95, 0x18, 0xd3, 0x8a, 0xa8, 0xdb, 0xf1, 0x92, + 0x5a, 0xb9, 0x23, 0x86, 0xed, 0xd4, 0x00, 0x99, 0x23}; + ASSERT_EQ(SECSuccess, rv); + EXPECT_EQ(expected, digest); +} + +TEST_F(Blake2BTests, LongHashTest) { + ScopedBLAKE2BContext ctx(BLAKE2B_NewContext()); + ASSERT_TRUE(ctx) << "BLAKE2B_NewContext failed!"; + + std::vector<uint8_t> digest(BLAKE2B512_LENGTH); + SECStatus rv = BLAKE2B_Hash( + digest.data(), + "qwertzuiopasdfghjklyxcvbnm123456789qwertzuiopasdfghjklyxcvbnm123456789qw" + "ertzuiopasdfghjklyxcvbnm123456789qwertzuiopasdfghjklyxcvbnm123456789qwer" + "tzuiopasdfghjklyxcvbnm123456789qwertzuiopasdfghjklyxcvbnm123456789qwertz" + "uiopasdfghjklyxcvbnm123456789qwertzuiopasdfghjklyxcvbnm123456789"); + std::vector<uint8_t> expected = { + 0x1f, 0x9e, 0xe6, 0x5a, 0xa0, 0x36, 0x05, 0xfc, 0x41, 0x0e, 0x2f, + 0x55, 0x96, 0xfd, 0xb5, 0x9d, 0x85, 0x95, 0x5e, 0x24, 0x37, 0xe7, + 0x0d, 0xe4, 0xa0, 0x22, 0x4a, 0xe1, 0x59, 0x1f, 0x97, 0x03, 0x57, + 0x54, 0xf0, 0xca, 0x92, 0x75, 0x2f, 0x9e, 0x86, 0xeb, 0x82, 0x4f, + 0x9c, 0xf4, 0x02, 0x17, 0x7f, 0x76, 0x56, 0x26, 0x46, 0xf4, 0x07, + 0xfd, 0x1f, 0x78, 0xdb, 0x7b, 0x0d, 0x24, 0x43, 0xf0}; + ASSERT_EQ(SECSuccess, rv); + EXPECT_EQ(expected, digest); +} + +TEST_F(Blake2BTests, TruncatedHashTest) { + ScopedBLAKE2BContext ctx(BLAKE2B_NewContext()); + ASSERT_TRUE(ctx) << "BLAKE2B_NewContext failed!"; + + SECStatus rv = BLAKE2B_Begin(ctx.get()); + ASSERT_EQ(SECSuccess, rv); + + rv = BLAKE2B_Update(ctx.get(), kat_data.data(), 128); + ASSERT_EQ(SECSuccess, rv); + rv = BLAKE2B_Update(ctx.get(), kat_data.data() + 128, 127); + ASSERT_EQ(SECSuccess, rv); + + size_t max_digest_len = BLAKE2B512_LENGTH - 5; + std::vector<uint8_t> digest(max_digest_len); + unsigned int digest_len; + rv = BLAKE2B_End(ctx.get(), digest.data(), &digest_len, max_digest_len); + ASSERT_EQ(SECSuccess, rv); + ASSERT_EQ(digest.size(), digest_len); + ASSERT_EQ(0, memcmp(std::get<1>(TestcasesUnkeyed[255]).data(), digest.data(), + max_digest_len)) + << "BLAKE2B_End failed!"; +} + +TEST_F(Blake2BTests, TruncatedHashTest2) { + ScopedBLAKE2BContext ctx(BLAKE2B_NewContext()); + ASSERT_TRUE(ctx) << "BLAKE2B_NewContext failed!"; + + SECStatus rv = BLAKE2B_Begin(ctx.get()); + ASSERT_EQ(SECSuccess, rv); + + rv = BLAKE2B_Update(ctx.get(), kat_data.data(), 128); + ASSERT_EQ(SECSuccess, rv); + rv = BLAKE2B_Update(ctx.get(), kat_data.data() + 128, 127); + ASSERT_EQ(SECSuccess, rv); + + size_t max_digest_len = BLAKE2B512_LENGTH - 60; + std::vector<uint8_t> digest(max_digest_len); + unsigned int digest_len; + rv = BLAKE2B_End(ctx.get(), digest.data(), &digest_len, max_digest_len); + ASSERT_EQ(SECSuccess, rv); + ASSERT_EQ(digest.size(), digest_len); +} + +TEST_F(Blake2BTests, OverlongKeyTest) { + ScopedBLAKE2BContext ctx(BLAKE2B_NewContext()); + ASSERT_TRUE(ctx) << "BLAKE2B_NewContext failed!"; + + std::vector<uint8_t> key = { + 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, + 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, + 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, + 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, + 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35}; + std::vector<uint8_t> data = {0x61, 0x62, 0x63}; + + std::vector<uint8_t> digest(BLAKE2B512_LENGTH); + SECStatus rv = + BLAKE2B_MAC_HashBuf(digest.data(), data.data(), 3, key.data(), 65); + EXPECT_EQ(SECFailure, rv); + EXPECT_EQ(SEC_ERROR_INVALID_ARGS, PORT_GetError()); +} + +TEST_F(Blake2BTests, EmptyKeyTest) { + ScopedBLAKE2BContext ctx(BLAKE2B_NewContext()); + ASSERT_TRUE(ctx) << "BLAKE2B_NewContext failed!"; + + uint8_t key[1]; // A vector.data() would give us a nullptr. + std::vector<uint8_t> data = {0x61, 0x62, 0x63}; + + std::vector<uint8_t> digest(BLAKE2B512_LENGTH); + SECStatus rv = BLAKE2B_MAC_HashBuf(digest.data(), data.data(), 3, key, 0); + EXPECT_EQ(SECFailure, rv); + EXPECT_EQ(SEC_ERROR_INVALID_ARGS, PORT_GetError()); +} + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + + if (NSS_NoDB_Init(nullptr) != SECSuccess) { + return 1; + } + + int rv = RUN_ALL_TESTS(); + + if (NSS_Shutdown() != SECSuccess) { + return 1; + } + + return rv; +} diff --git a/security/nss/gtests/freebl_gtest/freebl_gtest.gyp b/security/nss/gtests/freebl_gtest/freebl_gtest.gyp index 7e11cd103..21a87c557 100644 --- a/security/nss/gtests/freebl_gtest/freebl_gtest.gyp +++ b/security/nss/gtests/freebl_gtest/freebl_gtest.gyp @@ -8,17 +8,10 @@ ], 'targets': [ { - 'target_name': 'freebl_gtest', - 'type': 'executable', - 'sources': [ - 'mpi_unittest.cc', - 'dh_unittest.cc', - 'ecl_unittest.cc', - 'ghash_unittest.cc', - '<(DEPTH)/gtests/common/gtests.cc' - ], + # Dependencies for tests. + 'target_name': 'freebl_gtest_deps', + 'type': 'none', 'dependencies': [ - '<(DEPTH)/exports.gyp:nss_exports', '<(DEPTH)/lib/util/util.gyp:nssutil3', '<(DEPTH)/gtests/google_test/google_test.gyp:gtest', '<(DEPTH)/lib/nss/nss.gyp:nss_static', @@ -33,42 +26,57 @@ ], }, { + 'target_name': 'freebl_gtest', + 'type': 'executable', + 'sources': [ + 'mpi_unittest.cc', + 'dh_unittest.cc', + 'ecl_unittest.cc', + 'ghash_unittest.cc', + 'rsa_unittest.cc', + '<(DEPTH)/gtests/common/gtests.cc' + ], + 'dependencies': [ + 'freebl_gtest_deps', + '<(DEPTH)/exports.gyp:nss_exports', + ], + }, + { 'target_name': 'prng_gtest', 'type': 'executable', 'sources': [ 'prng_kat_unittest.cc', ], 'dependencies': [ + 'freebl_gtest_deps', '<(DEPTH)/exports.gyp:nss_exports', - '<(DEPTH)/lib/util/util.gyp:nssutil3', - '<(DEPTH)/gtests/google_test/google_test.gyp:gtest', - '<(DEPTH)/lib/nss/nss.gyp:nss_static', - '<(DEPTH)/lib/pk11wrap/pk11wrap.gyp:pk11wrap_static', - '<(DEPTH)/lib/cryptohi/cryptohi.gyp:cryptohi', - '<(DEPTH)/lib/certhigh/certhigh.gyp:certhi', - '<(DEPTH)/lib/certdb/certdb.gyp:certdb', - '<(DEPTH)/lib/base/base.gyp:nssb', - '<(DEPTH)/lib/dev/dev.gyp:nssdev', - '<(DEPTH)/lib/pki/pki.gyp:nsspki', - '<(DEPTH)/lib/ssl/ssl.gyp:ssl', - '<(DEPTH)/lib/libpkix/libpkix.gyp:libpkix', ], - 'conditions': [ - [ 'OS=="win"', { - 'libraries': [ - 'advapi32.lib', - ], - }], + }, + { + 'target_name': 'blake2b_gtest', + 'type': 'executable', + 'sources': [ + 'blake2b_unittest.cc', ], - 'defines': [ - 'NSS_USE_STATIC_LIBS' + 'dependencies': [ + 'freebl_gtest_deps', + '<(DEPTH)/exports.gyp:nss_exports', ], }, ], 'target_defaults': { 'include_dirs': [ + '<(DEPTH)/lib/freebl/ecl', '<(DEPTH)/lib/freebl/mpi', '<(DEPTH)/lib/freebl/', + '<(DEPTH)/lib/ssl/', + '<(DEPTH)/lib/util/', + '<(DEPTH)/lib/certdb/', + '<(DEPTH)/lib/cryptohi/', + '<(DEPTH)/lib/pk11wrap/', + ], + 'defines': [ + 'NSS_USE_STATIC_LIBS', ], # For test builds we have to set MPI defines. 'conditions': [ @@ -85,6 +93,11 @@ 'MP_ASSEMBLY_DIV_2DX1D', ], }], + [ 'OS=="win"', { + 'libraries': [ + 'advapi32.lib', + ], + }], ], }, 'variables': { diff --git a/security/nss/gtests/freebl_gtest/kat/blake2b_kat.h b/security/nss/gtests/freebl_gtest/kat/blake2b_kat.h new file mode 100644 index 000000000..28921cc94 --- /dev/null +++ b/security/nss/gtests/freebl_gtest/kat/blake2b_kat.h @@ -0,0 +1,4646 @@ +/* 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/. */ + +/* https://github.com/BLAKE2/BLAKE2/blob/master/testvectors/blake2b-kat.txt */ + +#include <vector> +#include <stdint.h> + +const std::vector<uint8_t> 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, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63}; + +const std::vector<uint8_t> kat_data = { + 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, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, + 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, + 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255}; + +std::vector<std::pair<int, std::vector<uint8_t>>> TestcasesUnkeyed = { + std::make_pair( + 0, + std::vector<uint8_t>( + {0x78, 0x6a, 0x02, 0xf7, 0x42, 0x01, 0x59, 0x03, 0xc6, 0xc6, 0xfd, + 0x85, 0x25, 0x52, 0xd2, 0x72, 0x91, 0x2f, 0x47, 0x40, 0xe1, 0x58, + 0x47, 0x61, 0x8a, 0x86, 0xe2, 0x17, 0xf7, 0x1f, 0x54, 0x19, 0xd2, + 0x5e, 0x10, 0x31, 0xaf, 0xee, 0x58, 0x53, 0x13, 0x89, 0x64, 0x44, + 0x93, 0x4e, 0xb0, 0x4b, 0x90, 0x3a, 0x68, 0x5b, 0x14, 0x48, 0xb7, + 0x55, 0xd5, 0x6f, 0x70, 0x1a, 0xfe, 0x9b, 0xe2, 0xce})), + std::make_pair( + 1, + std::vector<uint8_t>( + {0x2f, 0xa3, 0xf6, 0x86, 0xdf, 0x87, 0x69, 0x95, 0x16, 0x7e, 0x7c, + 0x2e, 0x5d, 0x74, 0xc4, 0xc7, 0xb6, 0xe4, 0x8f, 0x80, 0x68, 0xfe, + 0x0e, 0x44, 0x20, 0x83, 0x44, 0xd4, 0x80, 0xf7, 0x90, 0x4c, 0x36, + 0x96, 0x3e, 0x44, 0x11, 0x5f, 0xe3, 0xeb, 0x2a, 0x3a, 0xc8, 0x69, + 0x4c, 0x28, 0xbc, 0xb4, 0xf5, 0xa0, 0xf3, 0x27, 0x6f, 0x2e, 0x79, + 0x48, 0x7d, 0x82, 0x19, 0x05, 0x7a, 0x50, 0x6e, 0x4b})), + std::make_pair( + 2, + std::vector<uint8_t>( + {0x1c, 0x08, 0x79, 0x8d, 0xc6, 0x41, 0xab, 0xa9, 0xde, 0xe4, 0x35, + 0xe2, 0x25, 0x19, 0xa4, 0x72, 0x9a, 0x09, 0xb2, 0xbf, 0xe0, 0xff, + 0x00, 0xef, 0x2d, 0xcd, 0x8e, 0xd6, 0xf8, 0xa0, 0x7d, 0x15, 0xea, + 0xf4, 0xae, 0xe5, 0x2b, 0xbf, 0x18, 0xab, 0x56, 0x08, 0xa6, 0x19, + 0x0f, 0x70, 0xb9, 0x04, 0x86, 0xc8, 0xa7, 0xd4, 0x87, 0x37, 0x10, + 0xb1, 0x11, 0x5d, 0x3d, 0xeb, 0xbb, 0x43, 0x27, 0xb5})), + std::make_pair( + 3, + std::vector<uint8_t>( + {0x40, 0xa3, 0x74, 0x72, 0x73, 0x02, 0xd9, 0xa4, 0x76, 0x9c, 0x17, + 0xb5, 0xf4, 0x09, 0xff, 0x32, 0xf5, 0x8a, 0xa2, 0x4f, 0xf1, 0x22, + 0xd7, 0x60, 0x3e, 0x4f, 0xda, 0x15, 0x09, 0xe9, 0x19, 0xd4, 0x10, + 0x7a, 0x52, 0xc5, 0x75, 0x70, 0xa6, 0xd9, 0x4e, 0x50, 0x96, 0x7a, + 0xea, 0x57, 0x3b, 0x11, 0xf8, 0x6f, 0x47, 0x3f, 0x53, 0x75, 0x65, + 0xc6, 0x6f, 0x70, 0x39, 0x83, 0x0a, 0x85, 0xd1, 0x86})), + std::make_pair( + 4, + std::vector<uint8_t>( + {0x77, 0xdd, 0xf4, 0xb1, 0x44, 0x25, 0xeb, 0x3d, 0x05, 0x3c, 0x1e, + 0x84, 0xe3, 0x46, 0x9d, 0x92, 0xc4, 0xcd, 0x91, 0x0e, 0xd2, 0x0f, + 0x92, 0x03, 0x5e, 0x0c, 0x99, 0xd8, 0xa7, 0xa8, 0x6c, 0xec, 0xaf, + 0x69, 0xf9, 0x66, 0x3c, 0x20, 0xa7, 0xaa, 0x23, 0x0b, 0xc8, 0x2f, + 0x60, 0xd2, 0x2f, 0xb4, 0xa0, 0x0b, 0x09, 0xd3, 0xeb, 0x8f, 0xc6, + 0x5e, 0xf5, 0x47, 0xfe, 0x63, 0xc8, 0xd3, 0xdd, 0xce})), + std::make_pair( + 5, + std::vector<uint8_t>( + {0xcb, 0xaa, 0x0b, 0xa7, 0xd4, 0x82, 0xb1, 0xf3, 0x01, 0x10, 0x9a, + 0xe4, 0x10, 0x51, 0x99, 0x1a, 0x32, 0x89, 0xbc, 0x11, 0x98, 0x00, + 0x5a, 0xf2, 0x26, 0xc5, 0xe4, 0xf1, 0x03, 0xb6, 0x65, 0x79, 0xf4, + 0x61, 0x36, 0x10, 0x44, 0xc8, 0xba, 0x34, 0x39, 0xff, 0x12, 0xc5, + 0x15, 0xfb, 0x29, 0xc5, 0x21, 0x61, 0xb7, 0xeb, 0x9c, 0x28, 0x37, + 0xb7, 0x6a, 0x5d, 0xc3, 0x3f, 0x7c, 0xb2, 0xe2, 0xe8})), + std::make_pair( + 6, + std::vector<uint8_t>( + {0xf9, 0x5d, 0x45, 0xcf, 0x69, 0xaf, 0x5c, 0x20, 0x23, 0xbd, 0xb5, + 0x05, 0x82, 0x1e, 0x62, 0xe8, 0x5d, 0x7c, 0xae, 0xdf, 0x7b, 0xed, + 0xa1, 0x2c, 0x02, 0x48, 0x77, 0x5b, 0x0c, 0x88, 0x20, 0x5e, 0xeb, + 0x35, 0xaf, 0x3a, 0x90, 0x81, 0x6f, 0x66, 0x08, 0xce, 0x7d, 0xd4, + 0x4e, 0xc2, 0x8d, 0xb1, 0x14, 0x06, 0x14, 0xe1, 0xdd, 0xeb, 0xf3, + 0xaa, 0x9c, 0xd1, 0x84, 0x3e, 0x0f, 0xad, 0x2c, 0x36})), + std::make_pair( + 7, + std::vector<uint8_t>( + {0x8f, 0x94, 0x5b, 0xa7, 0x00, 0xf2, 0x53, 0x0e, 0x5c, 0x2a, 0x7d, + 0xf7, 0xd5, 0xdc, 0xe0, 0xf8, 0x3f, 0x9e, 0xfc, 0x78, 0xc0, 0x73, + 0xfe, 0x71, 0xae, 0x1f, 0x88, 0x20, 0x4a, 0x4f, 0xd1, 0xcf, 0x70, + 0xa0, 0x73, 0xf5, 0xd1, 0xf9, 0x42, 0xed, 0x62, 0x3a, 0xa1, 0x6e, + 0x90, 0xa8, 0x71, 0x24, 0x6c, 0x90, 0xc4, 0x5b, 0x62, 0x1b, 0x34, + 0x01, 0xa5, 0xdd, 0xbd, 0x9d, 0xf6, 0x26, 0x41, 0x65})), + std::make_pair( + 8, + std::vector<uint8_t>( + {0xe9, 0x98, 0xe0, 0xdc, 0x03, 0xec, 0x30, 0xeb, 0x99, 0xbb, 0x6b, + 0xfa, 0xaf, 0x66, 0x18, 0xac, 0xc6, 0x20, 0x32, 0x0d, 0x72, 0x20, + 0xb3, 0xaf, 0x2b, 0x23, 0xd1, 0x12, 0xd8, 0xe9, 0xcb, 0x12, 0x62, + 0xf3, 0xc0, 0xd6, 0x0d, 0x18, 0x3b, 0x1e, 0xe7, 0xf0, 0x96, 0xd1, + 0x2d, 0xae, 0x42, 0xc9, 0x58, 0x41, 0x86, 0x00, 0x21, 0x4d, 0x04, + 0xf5, 0xed, 0x6f, 0x5e, 0x71, 0x8b, 0xe3, 0x55, 0x66})), + std::make_pair( + 9, + std::vector<uint8_t>( + {0x6a, 0x9a, 0x09, 0x0c, 0x61, 0xb3, 0x41, 0x0a, 0xed, 0xe7, 0xec, + 0x91, 0x38, 0x14, 0x6c, 0xeb, 0x2c, 0x69, 0x66, 0x2f, 0x46, 0x0c, + 0x3d, 0xa5, 0x3c, 0x65, 0x15, 0xc1, 0xeb, 0x31, 0xf4, 0x1c, 0xa3, + 0xd2, 0x80, 0xe5, 0x67, 0x88, 0x2f, 0x95, 0xcf, 0x66, 0x4a, 0x94, + 0x14, 0x7d, 0x78, 0xf4, 0x2c, 0xfc, 0x71, 0x4a, 0x40, 0xd2, 0x2e, + 0xf1, 0x94, 0x70, 0xe0, 0x53, 0x49, 0x35, 0x08, 0xa2})), + std::make_pair( + 10, + std::vector<uint8_t>( + {0x29, 0x10, 0x25, 0x11, 0xd7, 0x49, 0xdb, 0x3c, 0xc9, 0xb4, 0xe3, + 0x35, 0xfa, 0x1f, 0x5e, 0x8f, 0xac, 0xa8, 0x42, 0x1d, 0x55, 0x8f, + 0x6a, 0x3f, 0x33, 0x21, 0xd5, 0x0d, 0x04, 0x4a, 0x24, 0x8b, 0xa5, + 0x95, 0xcf, 0xc3, 0xef, 0xd3, 0xd2, 0xad, 0xc9, 0x73, 0x34, 0xda, + 0x73, 0x24, 0x13, 0xf5, 0xcb, 0xf4, 0x75, 0x1c, 0x36, 0x2b, 0xa1, + 0xd5, 0x38, 0x62, 0xac, 0x1e, 0x8d, 0xab, 0xee, 0xe8})), + std::make_pair( + 11, + std::vector<uint8_t>( + {0xc9, 0x7a, 0x47, 0x79, 0xd4, 0x7e, 0x6f, 0x77, 0x72, 0x9b, 0x59, + 0x17, 0xd0, 0x13, 0x8a, 0xbb, 0x35, 0x98, 0x0a, 0xb6, 0x41, 0xbd, + 0x73, 0xa8, 0x85, 0x9e, 0xb1, 0xac, 0x98, 0xc0, 0x53, 0x62, 0xed, + 0x7d, 0x60, 0x8f, 0x2e, 0x95, 0x87, 0xd6, 0xba, 0x9e, 0x27, 0x1d, + 0x34, 0x31, 0x25, 0xd4, 0x0d, 0x93, 0x3a, 0x8e, 0xd0, 0x4e, 0xc1, + 0xfe, 0x75, 0xec, 0x40, 0x7c, 0x7a, 0x53, 0xc3, 0x4e})), + std::make_pair( + 12, + std::vector<uint8_t>( + {0x10, 0xf0, 0xdc, 0x91, 0xb9, 0xf8, 0x45, 0xfb, 0x95, 0xfa, 0xd6, + 0x86, 0x0e, 0x6c, 0xe1, 0xad, 0xfa, 0x00, 0x2c, 0x7f, 0xc3, 0x27, + 0x11, 0x6d, 0x44, 0xd0, 0x47, 0xcd, 0x7d, 0x58, 0x70, 0xd7, 0x72, + 0xbb, 0x12, 0xb5, 0xfa, 0xc0, 0x0e, 0x02, 0xb0, 0x8a, 0xc2, 0xa0, + 0x17, 0x4d, 0x04, 0x46, 0xc3, 0x6a, 0xb3, 0x5f, 0x14, 0xca, 0x31, + 0x89, 0x4c, 0xd6, 0x1c, 0x78, 0xc8, 0x49, 0xb4, 0x8a})), + std::make_pair( + 13, + std::vector<uint8_t>( + {0xde, 0xa9, 0x10, 0x1c, 0xac, 0x62, 0xb8, 0xf6, 0xa3, 0xc6, 0x50, + 0xf9, 0x0e, 0xea, 0x5b, 0xfa, 0xe2, 0x65, 0x3a, 0x4e, 0xaf, 0xd6, + 0x3a, 0x6d, 0x1f, 0x0f, 0x13, 0x2d, 0xb9, 0xe4, 0xf2, 0xb1, 0xb6, + 0x62, 0x43, 0x2e, 0xc8, 0x5b, 0x17, 0xbc, 0xac, 0x41, 0xe7, 0x75, + 0x63, 0x78, 0x81, 0xf6, 0xaa, 0xb3, 0x8d, 0xd6, 0x6d, 0xcb, 0xd0, + 0x80, 0xf0, 0x99, 0x0a, 0x7a, 0x6e, 0x98, 0x54, 0xfe})), + std::make_pair( + 14, + std::vector<uint8_t>( + {0x44, 0x1f, 0xfa, 0xa0, 0x8c, 0xd7, 0x9d, 0xff, 0x4a, 0xfc, 0x9b, + 0x9e, 0x5b, 0x56, 0x20, 0xee, 0xc0, 0x86, 0x73, 0x0c, 0x25, 0xf6, + 0x61, 0xb1, 0xd6, 0xfb, 0xfb, 0xd1, 0xce, 0xc3, 0x14, 0x8d, 0xd7, + 0x22, 0x58, 0xc6, 0x56, 0x41, 0xf2, 0xfc, 0xa5, 0xeb, 0x15, 0x5f, + 0xad, 0xbc, 0xab, 0xb1, 0x3c, 0x6e, 0x21, 0xdc, 0x11, 0xfa, 0xf7, + 0x2c, 0x2a, 0x28, 0x1b, 0x7d, 0x56, 0x14, 0x5f, 0x19})), + std::make_pair( + 15, + std::vector<uint8_t>( + {0x44, 0x4b, 0x24, 0x0f, 0xe3, 0xed, 0x86, 0xd0, 0xe2, 0xef, 0x4c, + 0xe7, 0xd8, 0x51, 0xed, 0xde, 0x22, 0x15, 0x55, 0x82, 0xaa, 0x09, + 0x14, 0x79, 0x7b, 0x72, 0x6c, 0xd0, 0x58, 0xb6, 0xf4, 0x59, 0x32, + 0xe0, 0xe1, 0x29, 0x51, 0x68, 0x76, 0x52, 0x7b, 0x1d, 0xd8, 0x8f, + 0xc6, 0x6d, 0x71, 0x19, 0xf4, 0xab, 0x3b, 0xed, 0x93, 0xa6, 0x1a, + 0x0e, 0x2d, 0x2d, 0x2a, 0xea, 0xc3, 0x36, 0xd9, 0x58})), + std::make_pair( + 16, + std::vector<uint8_t>( + {0xbf, 0xba, 0xbb, 0xef, 0x45, 0x55, 0x4c, 0xcf, 0xa0, 0xdc, 0x83, + 0x75, 0x2a, 0x19, 0xcc, 0x35, 0xd5, 0x92, 0x09, 0x56, 0xb3, 0x01, + 0xd5, 0x58, 0xd7, 0x72, 0x28, 0x2b, 0xc8, 0x67, 0x00, 0x91, 0x68, + 0xe9, 0xe9, 0x86, 0x06, 0xbb, 0x5b, 0xa7, 0x3a, 0x38, 0x5d, 0xe5, + 0x74, 0x92, 0x28, 0xc9, 0x25, 0xa8, 0x50, 0x19, 0xb7, 0x1f, 0x72, + 0xfe, 0x29, 0xb3, 0xcd, 0x37, 0xca, 0x52, 0xef, 0xe6})), + std::make_pair( + 17, + std::vector<uint8_t>( + {0x9c, 0x4d, 0x0c, 0x3e, 0x1c, 0xdb, 0xbf, 0x48, 0x5b, 0xec, 0x86, + 0xf4, 0x1c, 0xec, 0x7c, 0x98, 0x37, 0x3f, 0x0e, 0x09, 0xf3, 0x92, + 0x84, 0x9a, 0xaa, 0x22, 0x9e, 0xbf, 0xbf, 0x39, 0x7b, 0x22, 0x08, + 0x55, 0x29, 0xcb, 0x7e, 0xf3, 0x9f, 0x9c, 0x7c, 0x22, 0x22, 0xa5, + 0x14, 0x18, 0x2b, 0x1e, 0xff, 0xaa, 0x17, 0x8c, 0xc3, 0x68, 0x7b, + 0x1b, 0x2b, 0x6c, 0xbc, 0xb6, 0xfd, 0xeb, 0x96, 0xf8})), + std::make_pair( + 18, + std::vector<uint8_t>( + {0x47, 0x71, 0x76, 0xb3, 0xbf, 0xcb, 0xad, 0xd7, 0x65, 0x7c, 0x23, + 0xc2, 0x46, 0x25, 0xe4, 0xd0, 0xd6, 0x74, 0xd1, 0x86, 0x8f, 0x00, + 0x60, 0x06, 0x39, 0x8a, 0xf9, 0x7a, 0xa4, 0x18, 0x77, 0xc8, 0xe7, + 0x0d, 0x3d, 0x14, 0xc3, 0xbb, 0xc9, 0xbb, 0xcd, 0xce, 0xa8, 0x01, + 0xbd, 0x0e, 0x15, 0x99, 0xaf, 0x1f, 0x3e, 0xec, 0x67, 0x40, 0x51, + 0x70, 0xf4, 0xe2, 0x6c, 0x96, 0x4a, 0x57, 0xa8, 0xb7})), + std::make_pair( + 19, + std::vector<uint8_t>( + {0xa7, 0x8c, 0x49, 0x0e, 0xda, 0x31, 0x73, 0xbb, 0x3f, 0x10, 0xde, + 0xe5, 0x2f, 0x11, 0x0f, 0xb1, 0xc0, 0x8e, 0x03, 0x02, 0x23, 0x0b, + 0x85, 0xdd, 0xd7, 0xc1, 0x12, 0x57, 0xd9, 0x2d, 0xe1, 0x48, 0x78, + 0x5e, 0xf0, 0x0c, 0x03, 0x9c, 0x0b, 0xb8, 0xeb, 0x98, 0x08, 0xa3, + 0x5b, 0x2d, 0x8c, 0x08, 0x0f, 0x57, 0x28, 0x59, 0x71, 0x4c, 0x9d, + 0x40, 0x69, 0xc5, 0xbc, 0xaf, 0x09, 0x0e, 0x89, 0x8e})), + std::make_pair( + 20, + std::vector<uint8_t>( + {0x58, 0xd0, 0x23, 0x39, 0x7b, 0xeb, 0x5b, 0x41, 0x45, 0xcb, 0x22, + 0x55, 0xb0, 0x7d, 0x74, 0x29, 0x0b, 0x36, 0xd9, 0xfd, 0x1e, 0x59, + 0x4a, 0xfb, 0xd8, 0xee, 0xa4, 0x7c, 0x20, 0x5b, 0x2e, 0xfb, 0xfe, + 0x6f, 0x46, 0x19, 0x0f, 0xaf, 0x95, 0xaf, 0x50, 0x4a, 0xb0, 0x72, + 0xe3, 0x6f, 0x6c, 0x85, 0xd7, 0x67, 0xa3, 0x21, 0xbf, 0xd7, 0xf2, + 0x26, 0x87, 0xa4, 0xab, 0xbf, 0x49, 0x4a, 0x68, 0x9c})), + std::make_pair( + 21, + std::vector<uint8_t>( + {0x40, 0x01, 0xec, 0x74, 0xd5, 0xa4, 0x6f, 0xd2, 0x9c, 0x2c, 0x3c, + 0xdb, 0xe5, 0xd1, 0xb9, 0xf2, 0x0e, 0x51, 0xa9, 0x41, 0xbe, 0x98, + 0xd2, 0xa4, 0xe1, 0xe2, 0xfb, 0xf8, 0x66, 0xa6, 0x72, 0x12, 0x1d, + 0xb6, 0xf8, 0x1a, 0x51, 0x4c, 0xfd, 0x10, 0xe7, 0x35, 0x8d, 0x57, + 0x1b, 0xdb, 0xa4, 0x8e, 0x4c, 0xe7, 0x08, 0xb9, 0xd1, 0x24, 0x89, + 0x4b, 0xc0, 0xb5, 0xed, 0x55, 0x49, 0x35, 0xf7, 0x3a})), + std::make_pair( + 22, + std::vector<uint8_t>( + {0xcc, 0xd1, 0xb2, 0x2d, 0xab, 0x65, 0x11, 0x22, 0x5d, 0x24, 0x01, + 0xea, 0x2d, 0x86, 0x25, 0xd2, 0x06, 0xa1, 0x24, 0x73, 0xcc, 0x73, + 0x2b, 0x61, 0x5e, 0x56, 0x40, 0xce, 0xff, 0xf0, 0xa4, 0xad, 0xf9, + 0x71, 0xb0, 0xe8, 0x27, 0xa6, 0x19, 0xe0, 0xa8, 0x0f, 0x5d, 0xb9, + 0xcc, 0xd0, 0x96, 0x23, 0x29, 0x01, 0x0d, 0x07, 0xe3, 0x4a, 0x20, + 0x64, 0xe7, 0x31, 0xc5, 0x20, 0x81, 0x7b, 0x21, 0x83})), + std::make_pair( + 23, + std::vector<uint8_t>( + {0xb4, 0xa0, 0xa9, 0xe3, 0x57, 0x4e, 0xdb, 0x9e, 0x1e, 0x72, 0xaa, + 0x31, 0xe3, 0x9c, 0xc5, 0xf3, 0x0d, 0xbf, 0x94, 0x3f, 0x8c, 0xab, + 0xc4, 0x08, 0x44, 0x96, 0x54, 0xa3, 0x91, 0x31, 0xe6, 0x6d, 0x71, + 0x8a, 0x18, 0x81, 0x91, 0x43, 0xe3, 0xea, 0x96, 0xb4, 0xa1, 0x89, + 0x59, 0x88, 0xa1, 0xc0, 0x05, 0x6c, 0xf2, 0xb6, 0xe0, 0x4f, 0x9a, + 0xc1, 0x9d, 0x65, 0x73, 0x83, 0xc2, 0x91, 0x0c, 0x44})), + std::make_pair( + 24, + std::vector<uint8_t>( + {0x44, 0x7b, 0xec, 0xab, 0x16, 0x63, 0x06, 0x08, 0xd3, 0x9f, 0x4f, + 0x05, 0x8b, 0x16, 0xf7, 0xaf, 0x95, 0xb8, 0x5a, 0x76, 0xaa, 0x0f, + 0xa7, 0xce, 0xa2, 0xb8, 0x07, 0x55, 0xfb, 0x76, 0xe9, 0xc8, 0x04, + 0xf2, 0xca, 0x78, 0xf0, 0x26, 0x43, 0xc9, 0x15, 0xfb, 0xf2, 0xfc, + 0xe5, 0xe1, 0x9d, 0xe8, 0x60, 0x00, 0xde, 0x03, 0xb1, 0x88, 0x61, + 0x81, 0x5a, 0x83, 0x12, 0x60, 0x71, 0xf8, 0xa3, 0x7b})), + std::make_pair( + 25, + std::vector<uint8_t>( + {0x54, 0xe6, 0xda, 0xb9, 0x97, 0x73, 0x80, 0xa5, 0x66, 0x58, 0x22, + 0xdb, 0x93, 0x37, 0x4e, 0xda, 0x52, 0x8d, 0x9b, 0xeb, 0x62, 0x6f, + 0x9b, 0x94, 0x02, 0x70, 0x71, 0xcb, 0x26, 0x67, 0x5e, 0x11, 0x2b, + 0x4a, 0x7f, 0xec, 0x94, 0x1e, 0xe6, 0x0a, 0x81, 0xe4, 0xd2, 0xea, + 0x3f, 0xf7, 0xbc, 0x52, 0xcf, 0xc4, 0x5d, 0xfb, 0xfe, 0x73, 0x5a, + 0x1c, 0x64, 0x6b, 0x2c, 0xf6, 0xd6, 0xa4, 0x9b, 0x62})), + std::make_pair( + 26, + std::vector<uint8_t>( + {0x3e, 0xa6, 0x26, 0x25, 0x94, 0x9e, 0x36, 0x46, 0x70, 0x4d, 0x7e, + 0x3c, 0x90, 0x6f, 0x82, 0xf6, 0xc0, 0x28, 0xf5, 0x40, 0xf5, 0xf7, + 0x2a, 0x79, 0x4b, 0x0c, 0x57, 0xbf, 0x97, 0xb7, 0x64, 0x9b, 0xfe, + 0xb9, 0x0b, 0x01, 0xd3, 0xca, 0x3e, 0x82, 0x9d, 0xe2, 0x1b, 0x38, + 0x26, 0xe6, 0xf8, 0x70, 0x14, 0xd3, 0xc7, 0x73, 0x50, 0xcb, 0x5a, + 0x15, 0xff, 0x5d, 0x46, 0x8a, 0x81, 0xbe, 0xc1, 0x60})), + std::make_pair( + 27, + std::vector<uint8_t>( + {0x21, 0x3c, 0xfe, 0x14, 0x5c, 0x54, 0xa3, 0x36, 0x91, 0x56, 0x99, + 0x80, 0xe5, 0x93, 0x8c, 0x88, 0x83, 0xa4, 0x6d, 0x84, 0xd1, 0x49, + 0xc8, 0xff, 0x1a, 0x67, 0xcd, 0x28, 0x7b, 0x4d, 0x49, 0xc6, 0xda, + 0x69, 0xd3, 0xa0, 0x35, 0x44, 0x3d, 0xb0, 0x85, 0x98, 0x3d, 0x0e, + 0xfe, 0x63, 0x70, 0x6b, 0xd5, 0xb6, 0xf1, 0x5a, 0x7d, 0xa4, 0x59, + 0xe8, 0xd5, 0x0a, 0x19, 0x09, 0x3d, 0xb5, 0x5e, 0x80})), + std::make_pair( + 28, + std::vector<uint8_t>( + {0x57, 0x16, 0xc4, 0xa3, 0x8f, 0x38, 0xdb, 0x10, 0x4e, 0x49, 0x4a, + 0x0a, 0x27, 0xcb, 0xe8, 0x9a, 0x26, 0xa6, 0xbb, 0x6f, 0x49, 0x9e, + 0xc0, 0x1c, 0x8c, 0x01, 0xaa, 0x7c, 0xb8, 0x84, 0x97, 0xe7, 0x51, + 0x48, 0xcd, 0x6e, 0xee, 0x12, 0xa7, 0x16, 0x8b, 0x6f, 0x78, 0xab, + 0x74, 0xe4, 0xbe, 0x74, 0x92, 0x51, 0xa1, 0xa7, 0x4c, 0x38, 0xc8, + 0x6d, 0x61, 0x29, 0x17, 0x7e, 0x28, 0x89, 0xe0, 0xb6})), + std::make_pair( + 29, + std::vector<uint8_t>( + {0x03, 0x04, 0x60, 0xa9, 0x8b, 0xdf, 0x9f, 0xf1, 0x7c, 0xd9, 0x64, + 0x04, 0xf2, 0x8f, 0xc3, 0x04, 0xf2, 0xb7, 0xc0, 0x4e, 0xaa, 0xde, + 0x53, 0x67, 0x7f, 0xd2, 0x8f, 0x78, 0x8c, 0xa2, 0x21, 0x86, 0xb8, + 0xbc, 0x80, 0xdd, 0x21, 0xd1, 0x7f, 0x85, 0x49, 0xc7, 0x11, 0xaf, + 0xf0, 0xe5, 0x14, 0xe1, 0x9d, 0x4e, 0x15, 0xf5, 0x99, 0x02, 0x52, + 0xa0, 0x3e, 0x08, 0x2f, 0x28, 0xdc, 0x20, 0x52, 0xf6})), + std::make_pair( + 30, + std::vector<uint8_t>( + {0x19, 0xe7, 0xf1, 0xcc, 0xee, 0x88, 0xa1, 0x06, 0x72, 0x33, 0x3e, + 0x39, 0x0c, 0xf2, 0x20, 0x13, 0xa8, 0xc7, 0x34, 0xc6, 0xcb, 0x9e, + 0xab, 0x41, 0xf1, 0x7c, 0x3c, 0x80, 0x32, 0xa2, 0xe4, 0xac, 0xa0, + 0x56, 0x9e, 0xa3, 0x6f, 0x08, 0x60, 0xc7, 0xa1, 0xaf, 0x28, 0xfa, + 0x47, 0x68, 0x40, 0xd6, 0x60, 0x11, 0x16, 0x88, 0x59, 0x33, 0x4a, + 0x9e, 0x4e, 0xf9, 0xcc, 0x2e, 0x61, 0xa0, 0xe2, 0x9e})), + std::make_pair( + 31, + std::vector<uint8_t>( + {0x29, 0xf8, 0xb8, 0xc7, 0x8c, 0x80, 0xf2, 0xfc, 0xb4, 0xbd, 0xf7, + 0x82, 0x5e, 0xd9, 0x0a, 0x70, 0xd6, 0x25, 0xff, 0x78, 0x5d, 0x26, + 0x26, 0x77, 0xe2, 0x50, 0xc0, 0x4f, 0x37, 0x20, 0xc8, 0x88, 0xd0, + 0x3f, 0x80, 0x45, 0xe4, 0xed, 0xf3, 0xf5, 0x28, 0x5b, 0xd3, 0x9d, + 0x92, 0x8a, 0x10, 0xa7, 0xd0, 0xa5, 0xdf, 0x00, 0xb8, 0x48, 0x4a, + 0xc2, 0x86, 0x81, 0x42, 0xa1, 0xe8, 0xbe, 0xa3, 0x51})), + std::make_pair( + 32, + std::vector<uint8_t>( + {0x5c, 0x52, 0x92, 0x0a, 0x72, 0x63, 0xe3, 0x9d, 0x57, 0x92, 0x0c, + 0xa0, 0xcb, 0x75, 0x2a, 0xc6, 0xd7, 0x9a, 0x04, 0xfe, 0xf8, 0xa7, + 0xa2, 0x16, 0xa1, 0xec, 0xb7, 0x11, 0x5c, 0xe0, 0x6d, 0x89, 0xfd, + 0x7d, 0x73, 0x5b, 0xd6, 0xf4, 0x27, 0x25, 0x55, 0xdb, 0xa2, 0x2c, + 0x2d, 0x1c, 0x96, 0xe6, 0x35, 0x23, 0x22, 0xc6, 0x2c, 0x56, 0x30, + 0xfd, 0xe0, 0xf4, 0x77, 0x7a, 0x76, 0xc3, 0xde, 0x2c})), + std::make_pair( + 33, + std::vector<uint8_t>( + {0x83, 0xb0, 0x98, 0xf2, 0x62, 0x25, 0x1b, 0xf6, 0x60, 0x06, 0x4a, + 0x9d, 0x35, 0x11, 0xce, 0x76, 0x87, 0xa0, 0x9e, 0x6d, 0xfb, 0xb8, + 0x78, 0x29, 0x9c, 0x30, 0xe9, 0x3d, 0xfb, 0x43, 0xa9, 0x31, 0x4d, + 0xb9, 0xa6, 0x00, 0x33, 0x7d, 0xb2, 0x6e, 0xbe, 0xed, 0xaf, 0x22, + 0x56, 0xa9, 0x6d, 0xab, 0xe9, 0xb2, 0x9e, 0x75, 0x73, 0xad, 0x11, + 0xc3, 0x52, 0x3d, 0x87, 0x4d, 0xde, 0x5b, 0xe7, 0xed})), + std::make_pair( + 34, + std::vector<uint8_t>( + {0x94, 0x47, 0xd9, 0x8a, 0xa5, 0xc9, 0x33, 0x13, 0x52, 0xf4, 0x3d, + 0x3e, 0x56, 0xd0, 0xa9, 0xa9, 0xf9, 0x58, 0x18, 0x65, 0x99, 0x8e, + 0x28, 0x85, 0xcc, 0x56, 0xdd, 0x0a, 0x0b, 0xd5, 0xa7, 0xb5, 0x05, + 0x95, 0xbd, 0x10, 0xf7, 0x52, 0x9b, 0xcd, 0x31, 0xf3, 0x7d, 0xc1, + 0x6a, 0x14, 0x65, 0xd5, 0x94, 0x07, 0x96, 0x67, 0xda, 0x2a, 0x3f, + 0xcb, 0x70, 0x40, 0x14, 0x98, 0x83, 0x7c, 0xed, 0xeb})), + std::make_pair( + 35, + std::vector<uint8_t>( + {0x86, 0x77, 0x32, 0xf2, 0xfe, 0xeb, 0x23, 0x89, 0x30, 0x97, 0x56, + 0x1a, 0xc7, 0x10, 0xa4, 0xbf, 0xf4, 0x53, 0xbe, 0x9c, 0xfb, 0xed, + 0xba, 0x8b, 0xa3, 0x24, 0xf9, 0xd3, 0x12, 0xa8, 0x2d, 0x73, 0x2e, + 0x1b, 0x83, 0xb8, 0x29, 0xfd, 0xcd, 0x17, 0x7b, 0x88, 0x2c, 0xa0, + 0xc1, 0xbf, 0x54, 0x4b, 0x22, 0x3b, 0xe5, 0x29, 0x92, 0x4a, 0x24, + 0x6a, 0x63, 0xcf, 0x05, 0x9b, 0xfd, 0xc5, 0x0a, 0x1b})), + std::make_pair( + 36, + std::vector<uint8_t>( + {0xf1, 0x5a, 0xb2, 0x6d, 0x4c, 0xdf, 0xcf, 0x56, 0xe1, 0x96, 0xbb, + 0x6b, 0xa1, 0x70, 0xa8, 0xfc, 0xcc, 0x41, 0x4d, 0xe9, 0x28, 0x5a, + 0xfd, 0x98, 0xa3, 0xd3, 0xcf, 0x2f, 0xb8, 0x8f, 0xcb, 0xc0, 0xf1, + 0x98, 0x32, 0xac, 0x43, 0x3a, 0x5b, 0x2c, 0xc2, 0x39, 0x2a, 0x4c, + 0xe3, 0x43, 0x32, 0x98, 0x7d, 0x8d, 0x2c, 0x2b, 0xef, 0x6c, 0x34, + 0x66, 0x13, 0x8d, 0xb0, 0xc6, 0xe4, 0x2f, 0xa4, 0x7b})), + std::make_pair( + 37, + std::vector<uint8_t>( + {0x28, 0x13, 0x51, 0x6d, 0x68, 0xed, 0x4a, 0x08, 0xb3, 0x9d, 0x64, + 0x8a, 0xa6, 0xaa, 0xcd, 0x81, 0xe9, 0xd6, 0x55, 0xec, 0xd5, 0xf0, + 0xc1, 0x35, 0x56, 0xc6, 0x0f, 0xdf, 0x0d, 0x33, 0x3e, 0xa3, 0x84, + 0x64, 0xb3, 0x6c, 0x02, 0xba, 0xcc, 0xd7, 0x46, 0xe9, 0x57, 0x5e, + 0x96, 0xc6, 0x30, 0x14, 0xf0, 0x74, 0xae, 0x34, 0xa0, 0xa2, 0x5b, + 0x32, 0x0f, 0x0f, 0xbe, 0xdd, 0x6a, 0xcf, 0x76, 0x65})), + std::make_pair( + 38, + std::vector<uint8_t>( + {0xd3, 0x25, 0x9a, 0xfc, 0xa8, 0xa4, 0x89, 0x62, 0xfa, 0x89, 0x2e, + 0x14, 0x5a, 0xcf, 0x54, 0x7f, 0x26, 0x92, 0x3a, 0xe8, 0xd4, 0x92, + 0x4c, 0x8a, 0x53, 0x15, 0x81, 0x52, 0x6b, 0x04, 0xb4, 0x4c, 0x7a, + 0xf8, 0x3c, 0x64, 0x3e, 0xf5, 0xa0, 0xbc, 0x28, 0x2d, 0x36, 0xf3, + 0xfb, 0x04, 0xc8, 0x4e, 0x28, 0xb3, 0x51, 0xf4, 0x0c, 0x74, 0xb6, + 0x9d, 0xc7, 0x84, 0x0b, 0xc7, 0x17, 0xb6, 0xf1, 0x5f})), + std::make_pair( + 39, + std::vector<uint8_t>( + {0xf1, 0x4b, 0x06, 0x1a, 0xe3, 0x59, 0xfa, 0x31, 0xb9, 0x89, 0xe3, + 0x03, 0x32, 0xbf, 0xe8, 0xde, 0x8c, 0xc8, 0xcd, 0xb5, 0x68, 0xe1, + 0x4b, 0xe2, 0x14, 0xa2, 0x22, 0x3b, 0x84, 0xca, 0xab, 0x74, 0x19, + 0x54, 0x9e, 0xcf, 0xcc, 0x96, 0xce, 0x2a, 0xce, 0xc1, 0x19, 0x48, + 0x5d, 0x87, 0xd1, 0x57, 0xd3, 0xa8, 0x73, 0x4f, 0xc4, 0x26, 0x59, + 0x7d, 0x64, 0xf3, 0x65, 0x70, 0xce, 0xaf, 0x22, 0x4d})), + std::make_pair( + 40, + std::vector<uint8_t>( + {0x55, 0xe7, 0x0b, 0x01, 0xd1, 0xfb, 0xf8, 0xb2, 0x3b, 0x57, 0xfb, + 0x62, 0xe2, 0x6c, 0x2c, 0xe5, 0x4f, 0x13, 0xf8, 0xfa, 0x24, 0x64, + 0xe6, 0xeb, 0x98, 0xd1, 0x6a, 0x61, 0x17, 0x02, 0x6d, 0x8b, 0x90, + 0x81, 0x90, 0x12, 0x49, 0x6d, 0x40, 0x71, 0xeb, 0xe2, 0xe5, 0x95, + 0x57, 0xec, 0xe3, 0x51, 0x9a, 0x7a, 0xa4, 0x58, 0x02, 0xf9, 0x61, + 0x53, 0x74, 0x87, 0x73, 0x32, 0xb7, 0x34, 0x90, 0xb3})), + std::make_pair( + 41, + std::vector<uint8_t>( + {0x25, 0x26, 0x1e, 0xb2, 0x96, 0x97, 0x1d, 0x6e, 0x4a, 0x71, 0xb2, + 0x92, 0x8e, 0x64, 0x83, 0x9c, 0x67, 0xd4, 0x22, 0x87, 0x2b, 0xf9, + 0xf3, 0xc3, 0x19, 0x93, 0x61, 0x52, 0x22, 0xde, 0x9f, 0x8f, 0x0b, + 0x2c, 0x4b, 0xe8, 0x54, 0x85, 0x59, 0xb4, 0xb3, 0x54, 0xe7, 0x36, + 0x41, 0x6e, 0x32, 0x18, 0xd4, 0xe8, 0xa1, 0xe2, 0x19, 0xa4, 0xa6, + 0xd4, 0x3e, 0x1a, 0x9a, 0x52, 0x1d, 0x0e, 0x75, 0xfc})), + std::make_pair( + 42, + std::vector<uint8_t>( + {0x08, 0x30, 0x7f, 0x34, 0x7c, 0x41, 0x29, 0x4e, 0x34, 0xbb, 0x54, + 0xcb, 0x42, 0xb1, 0x52, 0x2d, 0x22, 0xf8, 0x24, 0xf7, 0xb6, 0xe5, + 0xdb, 0x50, 0xfd, 0xa0, 0x96, 0x79, 0x8e, 0x18, 0x1a, 0x8f, 0x02, + 0x6f, 0xa2, 0x7b, 0x4a, 0xe4, 0x5d, 0x52, 0xa6, 0x2c, 0xaf, 0x9d, + 0x51, 0x98, 0xe2, 0x4a, 0x49, 0x13, 0xc6, 0x67, 0x17, 0x75, 0xb2, + 0xd7, 0x23, 0xc1, 0x23, 0x9b, 0xfb, 0xf0, 0x16, 0xd7})), + std::make_pair( + 43, + std::vector<uint8_t>( + {0x1e, 0x5c, 0x62, 0xe7, 0xe9, 0xbf, 0xa1, 0xb1, 0x18, 0x74, 0x7a, + 0x2d, 0xe0, 0x8b, 0x3c, 0xa1, 0x01, 0x12, 0xaf, 0x96, 0xa4, 0x6e, + 0x4b, 0x22, 0xc3, 0xfc, 0x06, 0xf9, 0xbf, 0xee, 0x4e, 0xb5, 0xc4, + 0x9e, 0x05, 0x7a, 0x4a, 0x48, 0x86, 0x23, 0x43, 0x24, 0x57, 0x25, + 0x76, 0xbb, 0x9b, 0x5e, 0xcf, 0xde, 0x0d, 0x99, 0xb0, 0xde, 0x4f, + 0x98, 0xec, 0x16, 0xe4, 0xd1, 0xb8, 0x5f, 0xa9, 0x47})), + std::make_pair( + 44, + std::vector<uint8_t>( + {0xc7, 0x4a, 0x77, 0x39, 0x5f, 0xb8, 0xbc, 0x12, 0x64, 0x47, 0x45, + 0x48, 0x38, 0xe5, 0x61, 0xe9, 0x62, 0x85, 0x3d, 0xc7, 0xeb, 0x49, + 0xa1, 0xe3, 0xcb, 0x67, 0xc3, 0xd0, 0x85, 0x1f, 0x3e, 0x39, 0x51, + 0x7b, 0xe8, 0xc3, 0x50, 0xac, 0x91, 0x09, 0x03, 0xd4, 0x9c, 0xd2, + 0xbf, 0xdf, 0x54, 0x5c, 0x99, 0x31, 0x6d, 0x03, 0x46, 0x17, 0x0b, + 0x73, 0x9f, 0x0a, 0xdd, 0x5d, 0x53, 0x3c, 0x2c, 0xfc})), + std::make_pair( + 45, + std::vector<uint8_t>( + {0x0d, 0xd5, 0x7b, 0x42, 0x3c, 0xc0, 0x1e, 0xb2, 0x86, 0x13, 0x91, + 0xeb, 0x88, 0x6a, 0x0d, 0x17, 0x07, 0x9b, 0x93, 0x3f, 0xc7, 0x6e, + 0xb3, 0xfc, 0x08, 0xa1, 0x9f, 0x8a, 0x74, 0x95, 0x2c, 0xb6, 0x8f, + 0x6b, 0xcd, 0xc6, 0x44, 0xf7, 0x73, 0x70, 0x96, 0x6e, 0x4d, 0x13, + 0xe8, 0x05, 0x60, 0xbc, 0xf0, 0x82, 0xef, 0x04, 0x79, 0xd4, 0x8f, + 0xbb, 0xab, 0x4d, 0xf0, 0x3b, 0x53, 0xa4, 0xe1, 0x78})), + std::make_pair( + 46, + std::vector<uint8_t>( + {0x4d, 0x8d, 0xc3, 0x92, 0x3e, 0xdc, 0xcd, 0xfc, 0xe7, 0x00, 0x72, + 0x39, 0x8b, 0x8a, 0x3d, 0xa5, 0xc3, 0x1f, 0xcb, 0x3e, 0xe3, 0xb6, + 0x45, 0xc8, 0x5f, 0x71, 0x7c, 0xba, 0xeb, 0x4b, 0x67, 0x3a, 0x19, + 0x39, 0x44, 0x25, 0xa5, 0x85, 0xbf, 0xb4, 0x64, 0xd9, 0x2f, 0x15, + 0x97, 0xd0, 0xb7, 0x54, 0xd1, 0x63, 0xf9, 0x7c, 0xed, 0x34, 0x3b, + 0x25, 0xdb, 0x5a, 0x70, 0xef, 0x48, 0xeb, 0xb3, 0x4f})), + std::make_pair( + 47, + std::vector<uint8_t>( + {0xf0, 0xa5, 0x05, 0x53, 0xe4, 0xdf, 0xb0, 0xc4, 0xe3, 0xe3, 0xd3, + 0xba, 0x82, 0x03, 0x48, 0x57, 0xe3, 0xb1, 0xe5, 0x09, 0x18, 0xf5, + 0xb8, 0xa7, 0xd6, 0x98, 0xe1, 0x0d, 0x24, 0x2b, 0x0f, 0xb5, 0x44, + 0xaf, 0x6c, 0x92, 0xd0, 0xc3, 0xaa, 0xf9, 0x93, 0x22, 0x20, 0x41, + 0x61, 0x17, 0xb4, 0xe7, 0x8e, 0xcb, 0x8a, 0x8f, 0x43, 0x0e, 0x13, + 0xb8, 0x2a, 0x59, 0x15, 0x29, 0x0a, 0x58, 0x19, 0xc5})), + std::make_pair( + 48, + std::vector<uint8_t>( + {0xb1, 0x55, 0x43, 0xf3, 0xf7, 0x36, 0x08, 0x66, 0x27, 0xcc, 0x53, + 0x65, 0xe7, 0xe8, 0x98, 0x8c, 0x2e, 0xf1, 0x55, 0xc0, 0xfd, 0x4f, + 0x42, 0x89, 0x61, 0xb0, 0x0d, 0x15, 0x26, 0xf0, 0x4d, 0x6d, 0x6a, + 0x65, 0x8b, 0x4b, 0x8e, 0xd3, 0x2c, 0x5d, 0x86, 0x21, 0xe7, 0xf4, + 0xf8, 0xe8, 0xa9, 0x33, 0xd9, 0xec, 0xc9, 0xdd, 0x1b, 0x83, 0x33, + 0xcb, 0xe2, 0x8c, 0xfc, 0x37, 0xd9, 0x71, 0x9e, 0x1c})), + std::make_pair( + 49, + std::vector<uint8_t>( + {0x7b, 0x4f, 0xa1, 0x58, 0xe4, 0x15, 0xfe, 0xf0, 0x23, 0x24, 0x72, + 0x64, 0xcb, 0xbe, 0x15, 0xd1, 0x6d, 0x91, 0xa4, 0x44, 0x24, 0xa8, + 0xdb, 0x70, 0x7e, 0xb1, 0xe2, 0x03, 0x3c, 0x30, 0xe9, 0xe1, 0xe7, + 0xc8, 0xc0, 0x86, 0x45, 0x95, 0xd2, 0xcb, 0x8c, 0x58, 0x0e, 0xb4, + 0x7e, 0x9d, 0x16, 0xab, 0xbd, 0x7e, 0x44, 0xe8, 0x24, 0xf7, 0xce, + 0xdb, 0x7d, 0xef, 0x57, 0x13, 0x0e, 0x52, 0xcf, 0xe9})), + std::make_pair( + 50, + std::vector<uint8_t>( + {0x60, 0x42, 0x4f, 0xf2, 0x32, 0x34, 0xc3, 0x4d, 0xc9, 0x68, 0x7a, + 0xd5, 0x02, 0x86, 0x93, 0x72, 0xcc, 0x31, 0xa5, 0x93, 0x80, 0x18, + 0x6b, 0xc2, 0x36, 0x1c, 0x83, 0x5d, 0x97, 0x2f, 0x49, 0x66, 0x6e, + 0xb1, 0xac, 0x69, 0x62, 0x9d, 0xe6, 0x46, 0xf0, 0x3f, 0x9b, 0x4d, + 0xb9, 0xe2, 0xac, 0xe0, 0x93, 0xfb, 0xfd, 0xf8, 0xf2, 0x0a, 0xb5, + 0xf9, 0x85, 0x41, 0x97, 0x8b, 0xe8, 0xef, 0x54, 0x9f})), + std::make_pair( + 51, + std::vector<uint8_t>( + {0x74, 0x06, 0x01, 0x8c, 0xe7, 0x04, 0xd8, 0x4f, 0x5e, 0xb9, 0xc7, + 0x9f, 0xea, 0x97, 0xda, 0x34, 0x56, 0x99, 0x46, 0x8a, 0x35, 0x0e, + 0xe0, 0xb2, 0xd0, 0xf3, 0xa4, 0xbf, 0x20, 0x70, 0x30, 0x4e, 0xa8, + 0x62, 0xd7, 0x2a, 0x51, 0xc5, 0x7d, 0x30, 0x64, 0x94, 0x72, 0x86, + 0xf5, 0x31, 0xe0, 0xea, 0xf7, 0x56, 0x37, 0x02, 0x26, 0x2e, 0x6c, + 0x72, 0x4a, 0xbf, 0x5e, 0xd8, 0xc8, 0x39, 0x8d, 0x17})), + std::make_pair( + 52, + std::vector<uint8_t>( + {0x14, 0xef, 0x5c, 0x6d, 0x64, 0x7b, 0x3b, 0xd1, 0xe6, 0xe3, 0x20, + 0x06, 0xc2, 0x31, 0x19, 0x98, 0x10, 0xde, 0x5c, 0x4d, 0xc8, 0x8e, + 0x70, 0x24, 0x02, 0x73, 0xb0, 0xea, 0x18, 0xe6, 0x51, 0xa3, 0xeb, + 0x4f, 0x5c, 0xa3, 0x11, 0x4b, 0x8a, 0x56, 0x71, 0x69, 0x69, 0xc7, + 0xcd, 0xa2, 0x7e, 0x0c, 0x8d, 0xb8, 0x32, 0xad, 0x5e, 0x89, 0xa2, + 0xdc, 0x6c, 0xb0, 0xad, 0xbe, 0x7d, 0x93, 0xab, 0xd1})), + std::make_pair( + 53, + std::vector<uint8_t>( + {0x38, 0xcf, 0x6c, 0x24, 0xe3, 0xe0, 0x8b, 0xcf, 0x1f, 0x6c, 0xf3, + 0xd1, 0xb1, 0xf6, 0x5b, 0x90, 0x52, 0x39, 0xa3, 0x11, 0x80, 0x33, + 0x24, 0x9e, 0x44, 0x81, 0x13, 0xec, 0x63, 0x2e, 0xa6, 0xdc, 0x34, + 0x6f, 0xee, 0xb2, 0x57, 0x1c, 0x38, 0xbd, 0x9a, 0x73, 0x98, 0xb2, + 0x22, 0x12, 0x80, 0x32, 0x80, 0x02, 0xb2, 0x3e, 0x1a, 0x45, 0xad, + 0xaf, 0xfe, 0x66, 0xd9, 0x3f, 0x65, 0x64, 0xea, 0xa2})), + std::make_pair( + 54, + std::vector<uint8_t>( + {0x6c, 0xd7, 0x20, 0x8a, 0x4b, 0xc7, 0xe7, 0xe5, 0x62, 0x01, 0xbb, + 0xba, 0x02, 0xa0, 0xf4, 0x89, 0xcd, 0x38, 0x4a, 0xbe, 0x40, 0xaf, + 0xd4, 0x22, 0x2f, 0x15, 0x8b, 0x3d, 0x98, 0x6e, 0xe7, 0x2a, 0x54, + 0xc5, 0x0f, 0xb6, 0x4f, 0xd4, 0xed, 0x25, 0x30, 0xed, 0xa2, 0xc8, + 0xaf, 0x29, 0x28, 0xa0, 0xda, 0x6d, 0x4f, 0x83, 0x0a, 0xe1, 0xc9, + 0xdb, 0x46, 0x9d, 0xfd, 0x97, 0x0f, 0x12, 0xa5, 0x6f})), + std::make_pair( + 55, + std::vector<uint8_t>( + {0x65, 0x98, 0x58, 0xf0, 0xb5, 0xc9, 0xed, 0xab, 0x5b, 0x94, 0xfd, + 0x73, 0x2f, 0x6e, 0x6b, 0x17, 0xc5, 0x1c, 0xc0, 0x96, 0x10, 0x4f, + 0x09, 0xbe, 0xb3, 0xaf, 0xc3, 0xaa, 0x46, 0x7c, 0x2e, 0xcf, 0x88, + 0x5c, 0x4c, 0x65, 0x41, 0xef, 0xfa, 0x90, 0x23, 0xd3, 0xb5, 0x73, + 0x8a, 0xe5, 0xa1, 0x4d, 0x86, 0x7e, 0x15, 0xdb, 0x06, 0xfe, 0x1f, + 0x9d, 0x11, 0x27, 0xb7, 0x7e, 0x1a, 0xab, 0xb5, 0x16})), + std::make_pair( + 56, + std::vector<uint8_t>( + {0x26, 0xcc, 0xa0, 0x12, 0x6f, 0x5d, 0x1a, 0x81, 0x3c, 0x62, 0xe5, + 0xc7, 0x10, 0x01, 0xc0, 0x46, 0xf9, 0xc9, 0x20, 0x95, 0x70, 0x45, + 0x50, 0xbe, 0x58, 0x73, 0xa4, 0x95, 0xa9, 0x99, 0xad, 0x01, 0x0a, + 0x4f, 0x79, 0x49, 0x1f, 0x24, 0xf2, 0x86, 0x50, 0x0a, 0xdc, 0xe1, + 0xa1, 0x37, 0xbc, 0x20, 0x84, 0xe4, 0x94, 0x9f, 0x5b, 0x72, 0x94, + 0xce, 0xfe, 0x51, 0xec, 0xaf, 0xf8, 0xe9, 0x5c, 0xba})), + std::make_pair( + 57, + std::vector<uint8_t>( + {0x41, 0x47, 0xc1, 0xf5, 0x51, 0x72, 0x78, 0x8c, 0x55, 0x67, 0xc5, + 0x61, 0xfe, 0xef, 0x87, 0x6f, 0x62, 0x1f, 0xff, 0x1c, 0xe8, 0x77, + 0x86, 0xb8, 0x46, 0x76, 0x37, 0xe7, 0x0d, 0xfb, 0xcd, 0x0d, 0xbd, + 0xb6, 0x41, 0x5c, 0xb6, 0x00, 0x95, 0x4a, 0xb9, 0xc0, 0x4c, 0x0e, + 0x45, 0x7e, 0x62, 0x5b, 0x40, 0x72, 0x22, 0xc0, 0xfe, 0x1a, 0xe2, + 0x1b, 0x21, 0x43, 0x68, 0x8a, 0xda, 0x94, 0xdc, 0x58})), + std::make_pair( + 58, + std::vector<uint8_t>( + {0x5b, 0x1b, 0xf1, 0x54, 0xc6, 0x2a, 0x8a, 0xf6, 0xe9, 0x3d, 0x35, + 0xf1, 0x8f, 0x7f, 0x90, 0xab, 0xb1, 0x6a, 0x6e, 0xf0, 0xe8, 0xd1, + 0xae, 0xcd, 0x11, 0x8b, 0xf7, 0x01, 0x67, 0xba, 0xb2, 0xaf, 0x08, + 0x93, 0x5c, 0x6f, 0xdc, 0x06, 0x63, 0xce, 0x74, 0x48, 0x2d, 0x17, + 0xa8, 0xe5, 0x4b, 0x54, 0x6d, 0x1c, 0x29, 0x66, 0x31, 0xc6, 0x5f, + 0x3b, 0x52, 0x2a, 0x51, 0x58, 0x39, 0xd4, 0x3d, 0x71})), + std::make_pair( + 59, + std::vector<uint8_t>( + {0x9f, 0x60, 0x04, 0x19, 0xa4, 0xe8, 0xf4, 0xfb, 0x83, 0x4c, 0x24, + 0xb0, 0xf7, 0xfc, 0x13, 0xbf, 0x4e, 0x27, 0x9d, 0x98, 0xe8, 0xa3, + 0xc7, 0x65, 0xee, 0x93, 0x49, 0x17, 0x40, 0x3e, 0x3a, 0x66, 0x09, + 0x71, 0x82, 0xea, 0x21, 0x45, 0x3c, 0xb6, 0x3e, 0xbb, 0xe8, 0xb7, + 0x3a, 0x9c, 0x21, 0x67, 0x59, 0x64, 0x46, 0x43, 0x8c, 0x57, 0x62, + 0x7f, 0x33, 0x0b, 0xad, 0xd4, 0xf5, 0x69, 0xf7, 0xd6})), + std::make_pair( + 60, + std::vector<uint8_t>( + {0x45, 0x7e, 0xf6, 0x46, 0x6a, 0x89, 0x24, 0xfd, 0x80, 0x11, 0xa3, + 0x44, 0x71, 0xa5, 0xa1, 0xac, 0x8c, 0xcd, 0x9b, 0xd0, 0xd0, 0x7a, + 0x97, 0x41, 0x4a, 0xc9, 0x43, 0x02, 0x1c, 0xe4, 0xb9, 0xe4, 0xb9, + 0xc8, 0xdb, 0x0a, 0x28, 0xf0, 0x16, 0xed, 0x43, 0xb1, 0x54, 0x24, + 0x81, 0x99, 0x00, 0x22, 0x14, 0x7b, 0x31, 0x3e, 0x19, 0x46, 0x71, + 0x13, 0x1e, 0x70, 0x8d, 0xd4, 0x3a, 0x3e, 0xd7, 0xdc})), + std::make_pair( + 61, + std::vector<uint8_t>( + {0x99, 0x97, 0xb2, 0x19, 0x4d, 0x9a, 0xf6, 0xdf, 0xcb, 0x91, 0x43, + 0xf4, 0x1c, 0x0e, 0xd8, 0x3d, 0x3a, 0x3f, 0x43, 0x88, 0x36, 0x11, + 0x03, 0xd3, 0x8c, 0x2a, 0x49, 0xb2, 0x80, 0xa5, 0x81, 0x21, 0x27, + 0x15, 0xfd, 0x90, 0x8d, 0x41, 0xc6, 0x51, 0xf5, 0xc7, 0x15, 0xca, + 0x38, 0xc0, 0xce, 0x28, 0x30, 0xa3, 0x7e, 0x00, 0xe5, 0x08, 0xce, + 0xd1, 0xbc, 0xdc, 0x32, 0x0e, 0x5e, 0x4d, 0x1e, 0x2e})), + std::make_pair( + 62, + std::vector<uint8_t>( + {0x5c, 0x6b, 0xbf, 0x16, 0xba, 0xa1, 0x80, 0xf9, 0x86, 0xbd, 0x40, + 0xa1, 0x28, 0x7e, 0xd4, 0xc5, 0x49, 0x77, 0x0e, 0x72, 0x84, 0x85, + 0x8f, 0xc4, 0x7b, 0xc2, 0x1a, 0xb9, 0x5e, 0xbb, 0xf3, 0x37, 0x4b, + 0x4e, 0xe3, 0xfd, 0x9f, 0x2a, 0xf6, 0x0f, 0x33, 0x95, 0x22, 0x1b, + 0x2a, 0xcc, 0x76, 0xf2, 0xd3, 0x4c, 0x13, 0x29, 0x54, 0x04, 0x9f, + 0x8a, 0x3a, 0x99, 0x6f, 0x1e, 0x32, 0xec, 0x84, 0xe5})), + std::make_pair( + 63, + std::vector<uint8_t>( + {0xd1, 0x0b, 0xf9, 0xa1, 0x5b, 0x1c, 0x9f, 0xc8, 0xd4, 0x1f, 0x89, + 0xbb, 0x14, 0x0b, 0xf0, 0xbe, 0x08, 0xd2, 0xf3, 0x66, 0x61, 0x76, + 0xd1, 0x3b, 0xaa, 0xc4, 0xd3, 0x81, 0x35, 0x8a, 0xd0, 0x74, 0xc9, + 0xd4, 0x74, 0x8c, 0x30, 0x05, 0x20, 0xeb, 0x02, 0x6d, 0xae, 0xae, + 0xa7, 0xc5, 0xb1, 0x58, 0x89, 0x2f, 0xde, 0x4e, 0x8e, 0xc1, 0x7d, + 0xc9, 0x98, 0xdc, 0xd5, 0x07, 0xdf, 0x26, 0xeb, 0x63})), + std::make_pair( + 64, + std::vector<uint8_t>( + {0x2f, 0xc6, 0xe6, 0x9f, 0xa2, 0x6a, 0x89, 0xa5, 0xed, 0x26, 0x90, + 0x92, 0xcb, 0x9b, 0x2a, 0x44, 0x9a, 0x44, 0x09, 0xa7, 0xa4, 0x40, + 0x11, 0xee, 0xca, 0xd1, 0x3d, 0x7c, 0x4b, 0x04, 0x56, 0x60, 0x2d, + 0x40, 0x2f, 0xa5, 0x84, 0x4f, 0x1a, 0x7a, 0x75, 0x81, 0x36, 0xce, + 0x3d, 0x5d, 0x8d, 0x0e, 0x8b, 0x86, 0x92, 0x1f, 0xff, 0xf4, 0xf6, + 0x92, 0xdd, 0x95, 0xbd, 0xc8, 0xe5, 0xff, 0x00, 0x52})), + std::make_pair( + 65, + std::vector<uint8_t>( + {0xfc, 0xbe, 0x8b, 0xe7, 0xdc, 0xb4, 0x9a, 0x32, 0xdb, 0xdf, 0x23, + 0x94, 0x59, 0xe2, 0x63, 0x08, 0xb8, 0x4d, 0xff, 0x1e, 0xa4, 0x80, + 0xdf, 0x8d, 0x10, 0x4e, 0xef, 0xf3, 0x4b, 0x46, 0xfa, 0xe9, 0x86, + 0x27, 0xb4, 0x50, 0xc2, 0x26, 0x7d, 0x48, 0xc0, 0x94, 0x6a, 0x69, + 0x7c, 0x5b, 0x59, 0x53, 0x14, 0x52, 0xac, 0x04, 0x84, 0xf1, 0xc8, + 0x4e, 0x3a, 0x33, 0xd0, 0xc3, 0x39, 0xbb, 0x2e, 0x28})), + std::make_pair( + 66, + std::vector<uint8_t>( + {0xa1, 0x90, 0x93, 0xa6, 0xe3, 0xbc, 0xf5, 0x95, 0x2f, 0x85, 0x0f, + 0x20, 0x30, 0xf6, 0x9b, 0x96, 0x06, 0xf1, 0x47, 0xf9, 0x0b, 0x8b, + 0xae, 0xe3, 0x36, 0x2d, 0xa7, 0x1d, 0x9f, 0x35, 0xb4, 0x4e, 0xf9, + 0xd8, 0xf0, 0xa7, 0x71, 0x2b, 0xa1, 0x87, 0x7f, 0xdd, 0xcd, 0x2d, + 0x8e, 0xa8, 0xf1, 0xe5, 0xa7, 0x73, 0xd0, 0xb7, 0x45, 0xd4, 0x72, + 0x56, 0x05, 0x98, 0x3a, 0x2d, 0xe9, 0x01, 0xf8, 0x03})), + std::make_pair( + 67, + std::vector<uint8_t>( + {0x3c, 0x20, 0x06, 0x42, 0x3f, 0x73, 0xe2, 0x68, 0xfa, 0x59, 0xd2, + 0x92, 0x03, 0x77, 0xeb, 0x29, 0xa4, 0xf9, 0xa8, 0xb4, 0x62, 0xbe, + 0x15, 0x98, 0x3e, 0xe3, 0xb8, 0x5a, 0xe8, 0xa7, 0x8e, 0x99, 0x26, + 0x33, 0x58, 0x1a, 0x90, 0x99, 0x89, 0x3b, 0x63, 0xdb, 0x30, 0x24, + 0x1c, 0x34, 0xf6, 0x43, 0x02, 0x7d, 0xc8, 0x78, 0x27, 0x9a, 0xf5, + 0x85, 0x0d, 0x7e, 0x2d, 0x4a, 0x26, 0x53, 0x07, 0x3a})), + std::make_pair( + 68, + std::vector<uint8_t>( + {0xd0, 0xf2, 0xf2, 0xe3, 0x78, 0x76, 0x53, 0xf7, 0x7c, 0xce, 0x2f, + 0xa2, 0x48, 0x35, 0x78, 0x5b, 0xbd, 0x0c, 0x43, 0x3f, 0xc7, 0x79, + 0x46, 0x5a, 0x11, 0x51, 0x49, 0x90, 0x5a, 0x9d, 0xd1, 0xcb, 0x82, + 0x7a, 0x62, 0x85, 0x06, 0xd4, 0x57, 0xfc, 0xf1, 0x24, 0xa0, 0xc2, + 0xae, 0xf9, 0xce, 0x2d, 0x2a, 0x0a, 0x0f, 0x63, 0x54, 0x55, 0x70, + 0xd8, 0x66, 0x7f, 0xf9, 0xe2, 0xeb, 0xa0, 0x73, 0x34})), + std::make_pair( + 69, + std::vector<uint8_t>( + {0x78, 0xa9, 0xfc, 0x04, 0x8e, 0x25, 0xc6, 0xdc, 0xb5, 0xde, 0x45, + 0x66, 0x7d, 0xe8, 0xff, 0xdd, 0x3a, 0x93, 0x71, 0x11, 0x41, 0xd5, + 0x94, 0xe9, 0xfa, 0x62, 0xa9, 0x59, 0x47, 0x5d, 0xa6, 0x07, 0x5e, + 0xa8, 0xf0, 0x91, 0x6e, 0x84, 0xe4, 0x5a, 0xd9, 0x11, 0xb7, 0x54, + 0x67, 0x07, 0x7e, 0xe5, 0x2d, 0x2c, 0x9a, 0xeb, 0xf4, 0xd5, 0x8f, + 0x20, 0xce, 0x4a, 0x3a, 0x00, 0x45, 0x8b, 0x05, 0xd4})), + std::make_pair( + 70, + std::vector<uint8_t>( + {0x45, 0x81, 0x3f, 0x44, 0x17, 0x69, 0xab, 0x6e, 0xd3, 0x7d, 0x34, + 0x9f, 0xf6, 0xe7, 0x22, 0x67, 0xd7, 0x6a, 0xe6, 0xbb, 0x3e, 0x3c, + 0x61, 0x2e, 0xc0, 0x5c, 0x6e, 0x02, 0xa1, 0x2a, 0xf5, 0xa3, 0x7c, + 0x91, 0x8b, 0x52, 0xbf, 0x74, 0x26, 0x7c, 0x3f, 0x6a, 0x3f, 0x18, + 0x3a, 0x80, 0x64, 0xff, 0x84, 0xc0, 0x7b, 0x19, 0x3d, 0x08, 0x06, + 0x67, 0x89, 0xa0, 0x1a, 0xcc, 0xdb, 0x6f, 0x93, 0x40})), + std::make_pair( + 71, + std::vector<uint8_t>( + {0x95, 0x6d, 0xa1, 0xc6, 0x8d, 0x83, 0xa7, 0xb8, 0x81, 0xe0, 0x1b, + 0x9a, 0x96, 0x6c, 0x3c, 0x0b, 0xf2, 0x7f, 0x68, 0x60, 0x6a, 0x8b, + 0x71, 0xd4, 0x57, 0xbd, 0x01, 0x6d, 0x4c, 0x41, 0xdd, 0x8a, 0x38, + 0x0c, 0x70, 0x9a, 0x29, 0x6c, 0xb4, 0xc6, 0x54, 0x47, 0x92, 0x92, + 0x0f, 0xd7, 0x88, 0x83, 0x57, 0x71, 0xa0, 0x7d, 0x4a, 0x16, 0xfb, + 0x52, 0xed, 0x48, 0x05, 0x03, 0x31, 0xdc, 0x4c, 0x8b})), + std::make_pair( + 72, + std::vector<uint8_t>( + {0xdf, 0x18, 0x6c, 0x2d, 0xc0, 0x9c, 0xaa, 0x48, 0xe1, 0x4e, 0x94, + 0x2f, 0x75, 0xde, 0x5a, 0xc1, 0xb7, 0xa2, 0x1e, 0x4f, 0x9f, 0x07, + 0x2a, 0x5b, 0x37, 0x1e, 0x09, 0xe0, 0x73, 0x45, 0xb0, 0x74, 0x0c, + 0x76, 0x17, 0x7b, 0x01, 0x27, 0x88, 0x08, 0xfe, 0xc0, 0x25, 0xed, + 0xed, 0x98, 0x22, 0xc1, 0x22, 0xaf, 0xd1, 0xc6, 0x3e, 0x6f, 0x0c, + 0xe2, 0xe3, 0x26, 0x31, 0x04, 0x10, 0x63, 0x14, 0x5c})), + std::make_pair( + 73, + std::vector<uint8_t>( + {0x87, 0x47, 0x56, 0x40, 0x96, 0x6a, 0x9f, 0xdc, 0xd6, 0xd3, 0xa3, + 0xb5, 0xa2, 0xcc, 0xa5, 0xc0, 0x8f, 0x0d, 0x88, 0x2b, 0x10, 0x24, + 0x3c, 0x0e, 0xc1, 0xbf, 0x3c, 0x6b, 0x1c, 0x37, 0xf2, 0xcd, 0x32, + 0x12, 0xf1, 0x9a, 0x05, 0x78, 0x64, 0x47, 0x7d, 0x5e, 0xaf, 0x8f, + 0xae, 0xd7, 0x3f, 0x29, 0x37, 0xc7, 0x68, 0xa0, 0xaf, 0x41, 0x5e, + 0x84, 0xbb, 0xce, 0x6b, 0xd7, 0xde, 0x23, 0xb6, 0x60})), + std::make_pair( + 74, + std::vector<uint8_t>( + {0xc3, 0xb5, 0x73, 0xbb, 0xe1, 0x09, 0x49, 0xa0, 0xfb, 0xd4, 0xff, + 0x88, 0x4c, 0x44, 0x6f, 0x22, 0x29, 0xb7, 0x69, 0x02, 0xf9, 0xdf, + 0xdb, 0xb8, 0xa0, 0x35, 0x3d, 0xa5, 0xc8, 0x3c, 0xa1, 0x4e, 0x81, + 0x51, 0xbb, 0xaa, 0xc8, 0x2f, 0xd1, 0x57, 0x6a, 0x00, 0x9a, 0xdc, + 0x6f, 0x19, 0x35, 0xcf, 0x26, 0xed, 0xd4, 0xf1, 0xfb, 0x8d, 0xa4, + 0x83, 0xe6, 0xc5, 0xcd, 0x9d, 0x89, 0x23, 0xad, 0xc3})), + std::make_pair( + 75, + std::vector<uint8_t>( + {0xb0, 0x9d, 0x8d, 0x0b, 0xba, 0x8a, 0x72, 0x86, 0xe4, 0x35, 0x68, + 0xf7, 0x90, 0x75, 0x50, 0xe4, 0x20, 0x36, 0xd6, 0x74, 0xe3, 0xc8, + 0xfc, 0x34, 0xd8, 0xca, 0x46, 0xf7, 0x71, 0xd6, 0x46, 0x6b, 0x70, + 0xfb, 0x60, 0x58, 0x75, 0xf6, 0xa8, 0x63, 0xc8, 0x77, 0xd1, 0x2f, + 0x07, 0x06, 0x3f, 0xdc, 0x2e, 0x90, 0xcc, 0xd4, 0x59, 0xb1, 0x91, + 0x0d, 0xcd, 0x52, 0xd8, 0xf1, 0x0b, 0x2b, 0x0a, 0x15})), + std::make_pair( + 76, + std::vector<uint8_t>( + {0xaf, 0x3a, 0x22, 0xbf, 0x75, 0xb2, 0x1a, 0xbf, 0xb0, 0xac, 0xd5, + 0x44, 0x22, 0xba, 0x1b, 0x73, 0x00, 0xa9, 0x52, 0xef, 0xf0, 0x2e, + 0xbe, 0xb6, 0x5b, 0x5c, 0x23, 0x44, 0x71, 0xa9, 0x8d, 0xf3, 0x2f, + 0x4f, 0x96, 0x43, 0xce, 0x19, 0x04, 0x10, 0x8a, 0x16, 0x87, 0x67, + 0x92, 0x42, 0x80, 0xbd, 0x76, 0xc8, 0x3f, 0x8c, 0x82, 0xd9, 0xa7, + 0x9d, 0x92, 0x59, 0xb1, 0x95, 0x36, 0x2a, 0x2a, 0x04})), + std::make_pair( + 77, + std::vector<uint8_t>( + {0xbf, 0x4f, 0xf2, 0x22, 0x1b, 0x7e, 0x69, 0x57, 0xa7, 0x24, 0xcd, + 0x96, 0x4a, 0xa3, 0xd5, 0xd0, 0xd9, 0x94, 0x1f, 0x54, 0x04, 0x13, + 0x75, 0x2f, 0x46, 0x99, 0xd8, 0x10, 0x1b, 0x3e, 0x53, 0x75, 0x08, + 0xbf, 0x09, 0xf8, 0x50, 0x8b, 0x31, 0x77, 0x36, 0xff, 0xd2, 0x65, + 0xf2, 0x84, 0x7a, 0xa7, 0xd8, 0x4b, 0xd2, 0xd9, 0x75, 0x69, 0xc4, + 0x9d, 0x63, 0x2a, 0xed, 0x99, 0x45, 0xe5, 0xfa, 0x5e})), + std::make_pair( + 78, + std::vector<uint8_t>( + {0x9c, 0x6b, 0x6b, 0x78, 0x19, 0x9b, 0x1b, 0xda, 0xcb, 0x43, 0x00, + 0xe3, 0x14, 0x79, 0xfa, 0x62, 0x2a, 0x6b, 0x5b, 0xc8, 0x0d, 0x46, + 0x78, 0xa6, 0x07, 0x8f, 0x88, 0xa8, 0x26, 0x8c, 0xd7, 0x20, 0x6a, + 0x27, 0x99, 0xe8, 0xd4, 0x62, 0x1a, 0x46, 0x4e, 0xf6, 0xb4, 0x3d, + 0xd8, 0xad, 0xff, 0xe9, 0x7c, 0xaf, 0x22, 0x1b, 0x22, 0xb6, 0xb8, + 0x77, 0x8b, 0x14, 0x9a, 0x82, 0x2a, 0xef, 0xbb, 0x09})), + std::make_pair( + 79, + std::vector<uint8_t>( + {0x89, 0x06, 0x56, 0xf0, 0x9c, 0x99, 0xd2, 0x80, 0xb5, 0xec, 0xb3, + 0x81, 0xf5, 0x64, 0x27, 0xb8, 0x13, 0x75, 0x1b, 0xc6, 0x52, 0xc7, + 0x82, 0x80, 0x78, 0xb2, 0x3a, 0x4a, 0xf8, 0x3b, 0x4e, 0x3a, 0x61, + 0xfd, 0xba, 0xc6, 0x1f, 0x89, 0xbe, 0xe8, 0x4e, 0xa6, 0xbe, 0xe7, + 0x60, 0xc0, 0x47, 0xf2, 0x5c, 0x6b, 0x0a, 0x20, 0x1c, 0x69, 0xa3, + 0x8f, 0xd6, 0xfd, 0x97, 0x1a, 0xf1, 0x85, 0x88, 0xbb})), + std::make_pair( + 80, + std::vector<uint8_t>( + {0x31, 0xa0, 0x46, 0xf7, 0x88, 0x2f, 0xfe, 0x6f, 0x83, 0xce, 0x47, + 0x2e, 0x9a, 0x07, 0x01, 0x83, 0x2e, 0xc7, 0xb3, 0xf7, 0x6f, 0xbc, + 0xfd, 0x1d, 0xf6, 0x0f, 0xe3, 0xea, 0x48, 0xfd, 0xe1, 0x65, 0x12, + 0x54, 0x24, 0x7c, 0x3f, 0xd9, 0x5e, 0x10, 0x0f, 0x91, 0x72, 0x73, + 0x1e, 0x17, 0xfd, 0x52, 0x97, 0xc1, 0x1f, 0x4b, 0xb3, 0x28, 0x36, + 0x3c, 0xa3, 0x61, 0x62, 0x4a, 0x81, 0xaf, 0x79, 0x7c})), + std::make_pair( + 81, + std::vector<uint8_t>( + {0x27, 0xa6, 0x0b, 0x2d, 0x00, 0xe7, 0xa6, 0x71, 0xd4, 0x7d, 0x0a, + 0xec, 0x2a, 0x68, 0x6a, 0x0a, 0xc0, 0x4b, 0x52, 0xf4, 0x0a, 0xb6, + 0x62, 0x90, 0x28, 0xeb, 0x7d, 0x13, 0xf4, 0xba, 0xa9, 0x9a, 0xc0, + 0xfe, 0x46, 0xee, 0x6c, 0x81, 0x49, 0x44, 0xf2, 0xf4, 0xb4, 0xd2, + 0x0e, 0x93, 0x78, 0xe4, 0x84, 0x7e, 0xa4, 0x4c, 0x13, 0x17, 0x80, + 0x91, 0xe2, 0x77, 0xb8, 0x7e, 0xa7, 0xa5, 0x57, 0x11})), + std::make_pair( + 82, + std::vector<uint8_t>( + {0x8b, 0x5c, 0xce, 0xf1, 0x94, 0x16, 0x2c, 0x1f, 0x19, 0xd6, 0x8f, + 0x91, 0xe0, 0xb0, 0x92, 0x8f, 0x28, 0x9e, 0xc5, 0x28, 0x37, 0x20, + 0x84, 0x0c, 0x2f, 0x73, 0xd2, 0x53, 0x11, 0x12, 0x38, 0xdc, 0xfe, + 0x94, 0xaf, 0x2b, 0x59, 0xc2, 0xc1, 0xca, 0x25, 0x91, 0x90, 0x1a, + 0x7b, 0xc0, 0x60, 0xe7, 0x45, 0x9b, 0x6c, 0x47, 0xdf, 0x0f, 0x71, + 0x70, 0x1a, 0x35, 0xcc, 0x0a, 0xa8, 0x31, 0xb5, 0xb6})), + std::make_pair( + 83, + std::vector<uint8_t>( + {0x57, 0xab, 0x6c, 0x4b, 0x22, 0x29, 0xae, 0xb3, 0xb7, 0x04, 0x76, + 0xd8, 0x03, 0xcd, 0x63, 0x81, 0x2f, 0x10, 0x7c, 0xe6, 0xda, 0x17, + 0xfe, 0xd9, 0xb1, 0x78, 0x75, 0xe8, 0xf8, 0x6c, 0x72, 0x4f, 0x49, + 0xe0, 0x24, 0xcb, 0xf3, 0xa1, 0xb8, 0xb1, 0x19, 0xc5, 0x03, 0x57, + 0x65, 0x2b, 0x81, 0x87, 0x9d, 0x2a, 0xde, 0x2d, 0x58, 0x8b, 0x9e, + 0x4f, 0x7c, 0xed, 0xba, 0x0e, 0x46, 0x44, 0xc9, 0xee})), + std::make_pair( + 84, + std::vector<uint8_t>( + {0x01, 0x90, 0xa8, 0xda, 0xc3, 0x20, 0xa7, 0x39, 0xf3, 0x22, 0xe1, + 0x57, 0x31, 0xaa, 0x14, 0x0d, 0xda, 0xf5, 0xbe, 0xd2, 0x94, 0xd5, + 0xc8, 0x2e, 0x54, 0xfe, 0xf2, 0x9f, 0x21, 0x4e, 0x18, 0xaa, 0xfa, + 0xa8, 0x4f, 0x8b, 0xe9, 0x9a, 0xf6, 0x29, 0x50, 0x26, 0x6b, 0x8f, + 0x90, 0x1f, 0x15, 0xdd, 0x4c, 0x5d, 0x35, 0x51, 0x6f, 0xc3, 0x5b, + 0x4c, 0xab, 0x2e, 0x96, 0xe4, 0x69, 0x5b, 0xbe, 0x1c})), + std::make_pair( + 85, + std::vector<uint8_t>( + {0xd1, 0x4d, 0x7c, 0x4c, 0x41, 0x5e, 0xeb, 0x0e, 0x10, 0xb1, 0x59, + 0x22, 0x4b, 0xea, 0x12, 0x7e, 0xbd, 0x84, 0xf9, 0x59, 0x1c, 0x70, + 0x2a, 0x33, 0x0f, 0x5b, 0xb7, 0xbb, 0x7a, 0xa4, 0x4e, 0xa3, 0x9d, + 0xe6, 0xed, 0x01, 0xf1, 0x8d, 0xa7, 0xad, 0xf4, 0x0c, 0xfb, 0x97, + 0xc5, 0xd1, 0x52, 0xc2, 0x75, 0x28, 0x82, 0x4b, 0x21, 0xe2, 0x39, + 0x52, 0x6a, 0xf8, 0xf3, 0x6b, 0x21, 0x4e, 0x0c, 0xfb})), + std::make_pair( + 86, + std::vector<uint8_t>( + {0xbe, 0x28, 0xc4, 0xbe, 0x70, 0x69, 0x70, 0x48, 0x8f, 0xac, 0x7d, + 0x29, 0xc3, 0xbd, 0x5c, 0x4e, 0x98, 0x60, 0x85, 0xc4, 0xc3, 0x33, + 0x2f, 0x1f, 0x3f, 0xd3, 0x09, 0x73, 0xdb, 0x61, 0x41, 0x64, 0xba, + 0x2f, 0x31, 0xa7, 0x88, 0x75, 0xff, 0xdc, 0x15, 0x03, 0x25, 0xc8, + 0x83, 0x27, 0xa9, 0x44, 0x3e, 0xd0, 0x4f, 0xdf, 0xe5, 0xbe, 0x93, + 0x87, 0x6d, 0x16, 0x28, 0x56, 0x0c, 0x76, 0x4a, 0x80})), + std::make_pair( + 87, + std::vector<uint8_t>( + {0x03, 0x1d, 0xa1, 0x06, 0x9e, 0x3a, 0x2e, 0x9c, 0x33, 0x82, 0xe4, + 0x36, 0xff, 0xd7, 0x9d, 0xf7, 0x4b, 0x1c, 0xa6, 0xa8, 0xad, 0xb2, + 0xde, 0xab, 0xe6, 0x76, 0xab, 0x45, 0x99, 0x4c, 0xbc, 0x05, 0x4f, + 0x03, 0x7d, 0x2f, 0x0e, 0xac, 0xe8, 0x58, 0xd3, 0x2c, 0x14, 0xe2, + 0xd1, 0xc8, 0xb4, 0x60, 0x77, 0x30, 0x8e, 0x3b, 0xdc, 0x2c, 0x1b, + 0x53, 0x17, 0x2e, 0xcf, 0x7a, 0x8c, 0x14, 0xe3, 0x49})), + std::make_pair( + 88, + std::vector<uint8_t>( + {0x46, 0x65, 0xce, 0xf8, 0xba, 0x4d, 0xb4, 0xd0, 0xac, 0xb1, 0x18, + 0xf2, 0x98, 0x7f, 0x0b, 0xb0, 0x9f, 0x8f, 0x86, 0xaa, 0x44, 0x5a, + 0xa3, 0xd5, 0xfc, 0x9a, 0x8b, 0x34, 0x68, 0x64, 0x78, 0x74, 0x89, + 0xe8, 0xfc, 0xec, 0xc1, 0x25, 0xd1, 0x7e, 0x9b, 0x56, 0xe1, 0x29, + 0x88, 0xea, 0xc5, 0xec, 0xc7, 0x28, 0x68, 0x83, 0xdb, 0x06, 0x61, + 0xb8, 0xff, 0x05, 0xda, 0x2a, 0xff, 0xf3, 0x0f, 0xe4})), + std::make_pair( + 89, + std::vector<uint8_t>( + {0x63, 0xb7, 0x03, 0x2e, 0x5f, 0x93, 0x0c, 0xc9, 0x93, 0x95, 0x17, + 0xf9, 0xe9, 0x86, 0x81, 0x6c, 0xfb, 0xec, 0x2b, 0xe5, 0x9b, 0x95, + 0x68, 0xb1, 0x3f, 0x2e, 0xad, 0x05, 0xba, 0xe7, 0x77, 0x7c, 0xab, + 0x62, 0x0c, 0x66, 0x59, 0x40, 0x4f, 0x74, 0x09, 0xe4, 0x19, 0x9a, + 0x3b, 0xe5, 0xf7, 0x86, 0x5a, 0xa7, 0xcb, 0xdf, 0x8c, 0x42, 0x53, + 0xf7, 0xe8, 0x21, 0x9b, 0x1b, 0xd5, 0xf4, 0x6f, 0xea})), + std::make_pair( + 90, + std::vector<uint8_t>( + {0x9f, 0x09, 0xbf, 0x09, 0x3a, 0x2b, 0x0f, 0xf8, 0xc2, 0x63, 0x4b, + 0x49, 0xe3, 0x7f, 0x1b, 0x21, 0x35, 0xb4, 0x47, 0xaa, 0x91, 0x44, + 0xc9, 0x78, 0x7d, 0xbf, 0xd9, 0x21, 0x29, 0x31, 0x6c, 0x99, 0xe8, + 0x8a, 0xab, 0x8a, 0x21, 0xfd, 0xef, 0x23, 0x72, 0xd1, 0x18, 0x9a, + 0xec, 0x50, 0x0f, 0x95, 0x77, 0x5f, 0x1f, 0x92, 0xbf, 0xb4, 0x55, + 0x45, 0xe4, 0x25, 0x9f, 0xb9, 0xb7, 0xb0, 0x2d, 0x14})), + std::make_pair( + 91, + std::vector<uint8_t>( + {0xf9, 0xf8, 0x49, 0x3c, 0x68, 0x08, 0x88, 0x07, 0xdf, 0x7f, 0x6a, + 0x26, 0x93, 0xd6, 0x4e, 0xa5, 0x9f, 0x03, 0xe9, 0xe0, 0x5a, 0x22, + 0x3e, 0x68, 0x52, 0x4c, 0xa3, 0x21, 0x95, 0xa4, 0x73, 0x4b, 0x65, + 0x4f, 0xce, 0xa4, 0xd2, 0x73, 0x4c, 0x86, 0x6c, 0xf9, 0x5c, 0x88, + 0x9f, 0xb1, 0x0c, 0x49, 0x15, 0x9b, 0xe2, 0xf5, 0x04, 0x3d, 0xc9, + 0x8b, 0xb5, 0x5e, 0x02, 0xef, 0x7b, 0xdc, 0xb0, 0x82})), + std::make_pair( + 92, + std::vector<uint8_t>( + {0x3c, 0x9a, 0x73, 0x59, 0xab, 0x4f, 0xeb, 0xce, 0x07, 0xb2, 0x0a, + 0xc4, 0x47, 0xb0, 0x6a, 0x24, 0x0b, 0x7f, 0xe1, 0xda, 0xe5, 0x43, + 0x9c, 0x49, 0xb6, 0x0b, 0x58, 0x19, 0xf7, 0x81, 0x2e, 0x4c, 0x17, + 0x24, 0x06, 0xc1, 0xaa, 0xc3, 0x16, 0x71, 0x3c, 0xf0, 0xdd, 0xed, + 0x10, 0x38, 0x07, 0x72, 0x58, 0xe2, 0xef, 0xf5, 0xb3, 0x39, 0x13, + 0xd9, 0xd9, 0x5c, 0xae, 0xb4, 0xe6, 0xc6, 0xb9, 0x70})), + std::make_pair( + 93, + std::vector<uint8_t>( + {0xad, 0x6a, 0xab, 0x80, 0x84, 0x51, 0x0e, 0x82, 0x2c, 0xfc, 0xe8, + 0x62, 0x5d, 0x62, 0xcf, 0x4d, 0xe6, 0x55, 0xf4, 0x76, 0x38, 0x84, + 0xc7, 0x1e, 0x80, 0xba, 0xb9, 0xac, 0x9d, 0x53, 0x18, 0xdb, 0xa4, + 0xa6, 0x03, 0x3e, 0xd2, 0x90, 0x84, 0xe6, 0x52, 0x16, 0xc0, 0x31, + 0x60, 0x6c, 0xa1, 0x76, 0x15, 0xdc, 0xfe, 0x3b, 0xa1, 0x1d, 0x26, + 0x85, 0x1a, 0xe0, 0x99, 0x9c, 0xa6, 0xe2, 0x32, 0xcf})), + std::make_pair( + 94, + std::vector<uint8_t>( + {0x15, 0x6e, 0x9e, 0x62, 0x61, 0x37, 0x4c, 0x9d, 0xc8, 0x84, 0xf3, + 0x6e, 0x70, 0xf0, 0xfe, 0x1a, 0xb9, 0x29, 0x79, 0x97, 0xb8, 0x36, + 0xfa, 0x7d, 0x17, 0x0a, 0x9c, 0x9e, 0xbf, 0x57, 0x5b, 0x88, 0x1e, + 0x7b, 0xce, 0xa4, 0x4d, 0x6c, 0x02, 0x48, 0xd3, 0x55, 0x97, 0x90, + 0x71, 0x54, 0x82, 0x89, 0x55, 0xbe, 0x19, 0x13, 0x58, 0x52, 0xf9, + 0x22, 0x88, 0x15, 0xec, 0xa0, 0x24, 0xa8, 0xad, 0xfb})), + std::make_pair( + 95, + std::vector<uint8_t>( + {0x42, 0x15, 0x40, 0x76, 0x33, 0xf4, 0xcc, 0xa9, 0xb6, 0x78, 0x8b, + 0xe9, 0x3e, 0x6a, 0xa3, 0xd9, 0x63, 0xc7, 0xd6, 0xce, 0x4b, 0x14, + 0x72, 0x47, 0x09, 0x9f, 0x46, 0xa3, 0xac, 0xb5, 0x00, 0xa3, 0x00, + 0x38, 0xcb, 0x3e, 0x78, 0x8c, 0x3d, 0x29, 0xf1, 0x32, 0xad, 0x84, + 0x4e, 0x80, 0xe9, 0xe9, 0x92, 0x51, 0xf6, 0xdb, 0x96, 0xac, 0xd8, + 0xa0, 0x91, 0xcf, 0xc7, 0x70, 0xaf, 0x53, 0x84, 0x7b})), + std::make_pair( + 96, + std::vector<uint8_t>( + {0x1c, 0x07, 0x7e, 0x27, 0x9d, 0xe6, 0x54, 0x85, 0x23, 0x50, 0x2b, + 0x6d, 0xf8, 0x00, 0xff, 0xda, 0xb5, 0xe2, 0xc3, 0xe9, 0x44, 0x2e, + 0xb8, 0x38, 0xf5, 0x8c, 0x29, 0x5f, 0x3b, 0x14, 0x7c, 0xef, 0x9d, + 0x70, 0x1c, 0x41, 0xc3, 0x21, 0x28, 0x3f, 0x00, 0xc7, 0x1a, 0xff, + 0xa0, 0x61, 0x93, 0x10, 0x39, 0x91, 0x26, 0x29, 0x5b, 0x78, 0xdd, + 0x4d, 0x1a, 0x74, 0x57, 0x2e, 0xf9, 0xed, 0x51, 0x35})), + std::make_pair( + 97, + std::vector<uint8_t>( + {0xf0, 0x7a, 0x55, 0x5f, 0x49, 0xfe, 0x48, 0x1c, 0xf4, 0xcd, 0x0a, + 0x87, 0xb7, 0x1b, 0x82, 0xe4, 0xa9, 0x50, 0x64, 0xd0, 0x66, 0x77, + 0xfd, 0xd9, 0x0a, 0x0e, 0xb5, 0x98, 0x87, 0x7b, 0xa1, 0xc8, 0x3d, + 0x46, 0x77, 0xb3, 0x93, 0xc3, 0xa3, 0xb6, 0x66, 0x1c, 0x42, 0x1f, + 0x5b, 0x12, 0xcb, 0x99, 0xd2, 0x03, 0x76, 0xba, 0x72, 0x75, 0xc2, + 0xf3, 0xa8, 0xf5, 0xa9, 0xb7, 0x82, 0x17, 0x20, 0xda})), + std::make_pair( + 98, + std::vector<uint8_t>( + {0xb5, 0x91, 0x1b, 0x38, 0x0d, 0x20, 0xc7, 0xb0, 0x43, 0x23, 0xe4, + 0x02, 0x6b, 0x38, 0xe2, 0x00, 0xf5, 0x34, 0x25, 0x92, 0x33, 0xb5, + 0x81, 0xe0, 0x2c, 0x1e, 0x3e, 0x2d, 0x84, 0x38, 0xd6, 0xc6, 0x6d, + 0x5a, 0x4e, 0xb2, 0x01, 0xd5, 0xa8, 0xb7, 0x50, 0x72, 0xc4, 0xec, + 0x29, 0x10, 0x63, 0x34, 0xda, 0x70, 0xbc, 0x79, 0x52, 0x1b, 0x0c, + 0xed, 0x2c, 0xfd, 0x53, 0x3f, 0x5f, 0xf8, 0x4f, 0x95})), + std::make_pair( + 99, + std::vector<uint8_t>( + {0x01, 0xf0, 0x70, 0xa0, 0x9b, 0xae, 0x91, 0x12, 0x96, 0x36, 0x1f, + 0x91, 0xaa, 0x0e, 0x8e, 0x0d, 0x09, 0xa7, 0x72, 0x54, 0x78, 0x53, + 0x6d, 0x9d, 0x48, 0xc5, 0xfe, 0x1e, 0x5e, 0x7c, 0x3c, 0x5b, 0x9b, + 0x9d, 0x6e, 0xb0, 0x77, 0x96, 0xf6, 0xda, 0x57, 0xae, 0x56, 0x2a, + 0x7d, 0x70, 0xe8, 0x82, 0xe3, 0x7a, 0xdf, 0xde, 0x83, 0xf0, 0xc4, + 0x33, 0xc2, 0xcd, 0x36, 0x35, 0x36, 0xbb, 0x22, 0xc8})), + std::make_pair( + 100, + std::vector<uint8_t>( + {0x6f, 0x79, 0x3e, 0xb4, 0x37, 0x4a, 0x48, 0xb0, 0x77, 0x5a, 0xca, + 0xf9, 0xad, 0xcf, 0x8e, 0x45, 0xe5, 0x42, 0x70, 0xc9, 0x47, 0x5f, + 0x00, 0x4a, 0xd8, 0xd5, 0x97, 0x3e, 0x2a, 0xca, 0x52, 0x74, 0x7f, + 0xf4, 0xed, 0x04, 0xae, 0x96, 0x72, 0x75, 0xb9, 0xf9, 0xeb, 0x0e, + 0x1f, 0xf7, 0x5f, 0xb4, 0xf7, 0x94, 0xfa, 0x8b, 0xe9, 0xad, 0xd7, + 0xa4, 0x13, 0x04, 0x86, 0x8d, 0x10, 0x3f, 0xab, 0x10})), + std::make_pair( + 101, + std::vector<uint8_t>( + {0x96, 0x5f, 0x20, 0xf1, 0x39, 0x76, 0x5f, 0xcc, 0x4c, 0xe4, 0xba, + 0x37, 0x94, 0x67, 0x58, 0x63, 0xca, 0xc2, 0x4d, 0xb4, 0x72, 0xcd, + 0x2b, 0x79, 0x9d, 0x03, 0x5b, 0xce, 0x3d, 0xbe, 0xa5, 0x02, 0xda, + 0x7b, 0x52, 0x48, 0x65, 0xf6, 0xb8, 0x11, 0xd8, 0xc5, 0x82, 0x8d, + 0x3a, 0x88, 0x96, 0x46, 0xfe, 0x64, 0xa3, 0x80, 0xda, 0x1a, 0xa7, + 0xc7, 0x04, 0x4e, 0x9f, 0x24, 0x5d, 0xce, 0xd1, 0x28})), + std::make_pair( + 102, + std::vector<uint8_t>( + {0xec, 0x29, 0x5b, 0x57, 0x83, 0x60, 0x12, 0x44, 0xc3, 0x0e, 0x46, + 0x41, 0xe3, 0xb4, 0x5b, 0xe2, 0x22, 0xc4, 0xdc, 0xe7, 0x7a, 0x58, + 0x70, 0x0f, 0x53, 0xbc, 0x8e, 0xc5, 0x2a, 0x94, 0x16, 0x90, 0xb4, + 0xd0, 0xb0, 0x87, 0xfb, 0x6f, 0xcb, 0x3f, 0x39, 0x83, 0x2b, 0x9d, + 0xe8, 0xf7, 0x5e, 0xc2, 0x0b, 0xd4, 0x30, 0x79, 0x81, 0x17, 0x49, + 0xcd, 0xc9, 0x07, 0xed, 0xb9, 0x41, 0x57, 0xd1, 0x80})), + std::make_pair( + 103, + std::vector<uint8_t>( + {0x61, 0xc7, 0x2f, 0x8c, 0xcc, 0x91, 0xdb, 0xb5, 0x4c, 0xa6, 0x75, + 0x0b, 0xc4, 0x89, 0x67, 0x2d, 0xe0, 0x9f, 0xae, 0xdb, 0x8f, 0xdd, + 0x4f, 0x94, 0xff, 0x23, 0x20, 0x90, 0x9a, 0x30, 0x3f, 0x5d, 0x5a, + 0x98, 0x48, 0x1c, 0x0b, 0xc1, 0xa6, 0x25, 0x41, 0x9f, 0xb4, 0xde, + 0xbf, 0xbf, 0x7f, 0x8a, 0x53, 0xbb, 0x07, 0xec, 0x3d, 0x98, 0x5e, + 0x8e, 0xa1, 0x1e, 0x72, 0xd5, 0x59, 0x94, 0x07, 0x80})), + std::make_pair( + 104, + std::vector<uint8_t>( + {0xaf, 0xd8, 0x14, 0x5b, 0x25, 0x9e, 0xef, 0xc8, 0xd1, 0x26, 0x20, + 0xc3, 0xc5, 0xb0, 0x3e, 0x1e, 0xd8, 0xfd, 0x2c, 0xce, 0xfe, 0x03, + 0x65, 0x07, 0x8c, 0x80, 0xfd, 0x42, 0xc1, 0x77, 0x0e, 0x28, 0xb4, + 0x49, 0x48, 0xf2, 0x7e, 0x65, 0xa1, 0x88, 0x66, 0x90, 0x11, 0x0d, + 0xb8, 0x14, 0x39, 0x7b, 0x68, 0xe4, 0x3d, 0x80, 0xd1, 0xba, 0x16, + 0xdf, 0xa3, 0x58, 0xe7, 0x39, 0xc8, 0x98, 0xcf, 0xa3})), + std::make_pair( + 105, + std::vector<uint8_t>( + {0x55, 0x2f, 0xc7, 0x89, 0x3c, 0xf1, 0xce, 0x93, 0x3a, 0xda, 0x35, + 0xc0, 0xda, 0x98, 0x84, 0x4e, 0x41, 0x54, 0x5e, 0x24, 0x4c, 0x31, + 0x57, 0xa1, 0x42, 0x8d, 0x7b, 0x4c, 0x21, 0xf9, 0xcd, 0x7e, 0x40, + 0x71, 0xae, 0xd7, 0x7b, 0x7c, 0xa9, 0xf1, 0xc3, 0x8f, 0xba, 0x32, + 0x23, 0x74, 0x12, 0xef, 0x21, 0xa3, 0x42, 0x74, 0x2e, 0xc8, 0x32, + 0x43, 0x78, 0xf2, 0x1e, 0x50, 0x7f, 0xaf, 0xdd, 0x88})), + std::make_pair( + 106, + std::vector<uint8_t>( + {0x46, 0x7a, 0x33, 0xfb, 0xad, 0xf5, 0xeb, 0xc5, 0x25, 0x96, 0xef, + 0x86, 0xaa, 0xae, 0xfc, 0x6f, 0xab, 0xa8, 0xee, 0x65, 0x1b, 0x1c, + 0xe0, 0x4d, 0xe3, 0x68, 0xa0, 0x3a, 0x5a, 0x90, 0x40, 0xef, 0x28, + 0x35, 0xe0, 0x0a, 0xdb, 0x09, 0xab, 0xb3, 0xfb, 0xd2, 0xbc, 0xe8, + 0x18, 0xa2, 0x41, 0x3d, 0x0b, 0x02, 0x53, 0xb5, 0xbd, 0xa4, 0xfc, + 0x5b, 0x2f, 0x6f, 0x85, 0xf3, 0xfd, 0x5b, 0x55, 0xf2})), + std::make_pair( + 107, + std::vector<uint8_t>( + {0x22, 0xef, 0xf8, 0xe6, 0xdd, 0x52, 0x36, 0xf5, 0xf5, 0x7d, 0x94, + 0xed, 0xe8, 0x74, 0xd6, 0xc9, 0x42, 0x8e, 0x8f, 0x5d, 0x56, 0x6f, + 0x17, 0xcd, 0x6d, 0x18, 0x48, 0xcd, 0x75, 0x2f, 0xe1, 0x3c, 0x65, + 0x5c, 0xb1, 0x0f, 0xba, 0xaf, 0xf7, 0x68, 0x72, 0xf2, 0xbf, 0x2d, + 0xa9, 0x9e, 0x15, 0xdc, 0x62, 0x40, 0x75, 0xe1, 0xec, 0x2f, 0x58, + 0xa3, 0xf6, 0x40, 0x72, 0x12, 0x18, 0x38, 0x56, 0x9e})), + std::make_pair( + 108, + std::vector<uint8_t>( + {0x9c, 0xec, 0x6b, 0xbf, 0x62, 0xc4, 0xbc, 0xe4, 0x13, 0x8a, 0xba, + 0xe1, 0xcb, 0xec, 0x8d, 0xad, 0x31, 0x95, 0x04, 0x44, 0xe9, 0x03, + 0x21, 0xb1, 0x34, 0x71, 0x96, 0x83, 0x4c, 0x11, 0x4b, 0x86, 0x4a, + 0xf3, 0xf3, 0xcc, 0x35, 0x08, 0xf8, 0x37, 0x51, 0xff, 0xb4, 0xed, + 0xa7, 0xc8, 0x4d, 0x14, 0x07, 0x34, 0xbb, 0x42, 0x63, 0xc3, 0x62, + 0x5c, 0x00, 0xf0, 0x4f, 0x4c, 0x80, 0x68, 0x98, 0x1b})), + std::make_pair( + 109, + std::vector<uint8_t>( + {0xa8, 0xb6, 0x0f, 0xa4, 0xfc, 0x24, 0x42, 0xf6, 0xf1, 0x51, 0x4a, + 0xd7, 0x40, 0x26, 0x26, 0x92, 0x0c, 0xc7, 0xc2, 0xc9, 0xf7, 0x21, + 0x24, 0xb8, 0xcb, 0xa8, 0xee, 0x2c, 0xb7, 0xc4, 0x58, 0x6f, 0x65, + 0x8a, 0x44, 0x10, 0xcf, 0xfc, 0xc0, 0xab, 0x88, 0x34, 0x39, 0x55, + 0xe0, 0x94, 0xc6, 0xaf, 0x0d, 0x20, 0xd0, 0xc7, 0x14, 0xfb, 0x0a, + 0x98, 0x8f, 0x54, 0x3f, 0x30, 0x0f, 0x58, 0xd3, 0x89})), + std::make_pair( + 110, + std::vector<uint8_t>( + {0x82, 0x71, 0xcc, 0x45, 0xdf, 0xa5, 0xe4, 0x17, 0x0e, 0x84, 0x7e, + 0x86, 0x30, 0xb9, 0x52, 0xcf, 0x9c, 0x2a, 0xa7, 0x77, 0xd0, 0x6f, + 0x26, 0xa7, 0x58, 0x5b, 0x83, 0x81, 0xf1, 0x88, 0xda, 0xcc, 0x73, + 0x37, 0x39, 0x1c, 0xfc, 0xc9, 0x4b, 0x05, 0x3d, 0xc4, 0xec, 0x29, + 0xcc, 0x17, 0xf0, 0x77, 0x87, 0x04, 0x28, 0xf1, 0xac, 0x23, 0xfd, + 0xdd, 0xa1, 0x65, 0xef, 0x5a, 0x3f, 0x15, 0x5f, 0x39})), + std::make_pair( + 111, + std::vector<uint8_t>( + {0xbf, 0x23, 0xc0, 0xc2, 0x5c, 0x80, 0x60, 0xe4, 0xf6, 0x99, 0x5f, + 0x16, 0x23, 0xa3, 0xbe, 0xbe, 0xca, 0xa9, 0x6e, 0x30, 0x86, 0x80, + 0x00, 0x0a, 0x8a, 0xa3, 0xcd, 0x56, 0xbb, 0x1a, 0x6d, 0xa0, 0x99, + 0xe1, 0x0d, 0x92, 0x31, 0xb3, 0x7f, 0x45, 0x19, 0xb2, 0xef, 0xd2, + 0xc2, 0x4d, 0xe7, 0x2f, 0x31, 0xa5, 0xf1, 0x95, 0x35, 0x24, 0x1b, + 0x4a, 0x59, 0xfa, 0x3c, 0x03, 0xce, 0xb7, 0x90, 0xe7})), + std::make_pair( + 112, + std::vector<uint8_t>( + {0x87, 0x7f, 0xd6, 0x52, 0xc0, 0x52, 0x81, 0x00, 0x9c, 0x0a, 0x52, + 0x50, 0xe7, 0xa3, 0xa6, 0x71, 0xf8, 0xb1, 0x8c, 0x10, 0x88, 0x17, + 0xfe, 0x4a, 0x87, 0x4d, 0xe2, 0x2d, 0xa8, 0xe4, 0x5d, 0xb1, 0x19, + 0x58, 0xa6, 0x00, 0xc5, 0xf6, 0x2e, 0x67, 0xd3, 0x6c, 0xbf, 0x84, + 0x47, 0x4c, 0xf2, 0x44, 0xa9, 0xc2, 0xb0, 0x3a, 0x9f, 0xb9, 0xdc, + 0x71, 0x1c, 0xd1, 0xa2, 0xca, 0xb6, 0xf3, 0xfa, 0xe0})), + std::make_pair( + 113, + std::vector<uint8_t>( + {0x29, 0xdf, 0x4d, 0x87, 0xea, 0x44, 0x4b, 0xaf, 0x5b, 0xcd, 0xf5, + 0xf4, 0xe4, 0x15, 0x79, 0xe2, 0x8a, 0x67, 0xde, 0x84, 0x14, 0x9f, + 0x06, 0xc0, 0x3f, 0x11, 0x0e, 0xa8, 0x4f, 0x57, 0x2a, 0x9f, 0x67, + 0x6a, 0xdd, 0xd0, 0x4c, 0x48, 0x78, 0xf4, 0x9c, 0x5c, 0x00, 0xac, + 0xcd, 0xa4, 0x41, 0xb1, 0xa3, 0x87, 0xca, 0xce, 0xb2, 0xe9, 0x93, + 0xbb, 0x7a, 0x10, 0xcd, 0x8c, 0x2d, 0x67, 0x17, 0xe1})), + std::make_pair( + 114, + std::vector<uint8_t>( + {0x71, 0x0d, 0xac, 0xb1, 0x66, 0x84, 0x46, 0x39, 0xcd, 0x7b, 0x63, + 0x7c, 0x27, 0x42, 0x09, 0x42, 0x4e, 0x24, 0x49, 0xdc, 0x35, 0xd7, + 0x90, 0xbb, 0xfa, 0x4f, 0x76, 0x17, 0x70, 0x54, 0xa3, 0x6b, 0x3b, + 0x76, 0xfa, 0xc0, 0xca, 0x6e, 0x61, 0xdf, 0x1e, 0x68, 0x70, 0x00, + 0x67, 0x8a, 0xc0, 0x74, 0x6d, 0xf7, 0x5d, 0x0a, 0x39, 0x54, 0x89, + 0x76, 0x81, 0xfd, 0x39, 0x3a, 0x15, 0x5a, 0x1b, 0xb4})), + std::make_pair( + 115, + std::vector<uint8_t>( + {0xc1, 0xd5, 0xf9, 0x3b, 0x8d, 0xea, 0x1f, 0x25, 0x71, 0xba, 0xbc, + 0xcb, 0xc0, 0x17, 0x64, 0x54, 0x1a, 0x0c, 0xda, 0x87, 0xe4, 0x44, + 0xd6, 0x73, 0xc5, 0x09, 0x66, 0xca, 0x55, 0x9c, 0x33, 0x35, 0x4b, + 0x3a, 0xcb, 0x26, 0xe5, 0xd5, 0x78, 0x1f, 0xfb, 0x28, 0x84, 0x7a, + 0x4b, 0x47, 0x54, 0xd7, 0x70, 0x08, 0xc6, 0x2a, 0x83, 0x58, 0x35, + 0xf5, 0x00, 0xde, 0xa7, 0xc3, 0xb5, 0x8b, 0xda, 0xe2})), + std::make_pair( + 116, + std::vector<uint8_t>( + {0xa4, 0x1e, 0x41, 0x27, 0x1c, 0xda, 0xb8, 0xaf, 0x4d, 0x72, 0xb1, + 0x04, 0xbf, 0xb2, 0xad, 0x04, 0x1a, 0xc4, 0xdf, 0x14, 0x67, 0x7d, + 0xa6, 0x71, 0xd8, 0x56, 0x40, 0xc4, 0xb1, 0x87, 0xf5, 0x0c, 0x2b, + 0x66, 0x51, 0x3c, 0x46, 0x19, 0xfb, 0xd5, 0xd5, 0xdc, 0x4f, 0xe6, + 0x5d, 0xd3, 0x7b, 0x90, 0x42, 0xe9, 0x84, 0x8d, 0xda, 0x55, 0x6a, + 0x50, 0x4c, 0xaa, 0x2b, 0x1c, 0x6a, 0xfe, 0x47, 0x30})), + std::make_pair( + 117, + std::vector<uint8_t>( + {0xe7, 0xbc, 0xba, 0xcd, 0xc3, 0x79, 0xc4, 0x3d, 0x81, 0xeb, 0xad, + 0xcb, 0x37, 0x78, 0x15, 0x52, 0xfc, 0x1d, 0x75, 0x3e, 0x8c, 0xf3, + 0x10, 0xd9, 0x68, 0x39, 0x2d, 0x06, 0xc9, 0x1f, 0x1d, 0x64, 0xcc, + 0x9e, 0x90, 0xce, 0x1d, 0x22, 0xc3, 0x2d, 0x27, 0x7f, 0xc6, 0xcd, + 0xa4, 0x33, 0xa4, 0xd4, 0x42, 0xc7, 0x62, 0xe9, 0xea, 0xcf, 0x2c, + 0x25, 0x9f, 0x32, 0xd6, 0x4c, 0xf9, 0xda, 0x3a, 0x22})), + std::make_pair( + 118, + std::vector<uint8_t>( + {0x51, 0x75, 0x5b, 0x4a, 0xc5, 0x45, 0x6b, 0x13, 0x21, 0x8a, 0x19, + 0xc5, 0xb9, 0x24, 0x2f, 0x57, 0xc4, 0xa9, 0x81, 0xe4, 0xd4, 0xec, + 0xdc, 0xe0, 0x9a, 0x31, 0x93, 0x36, 0x2b, 0x80, 0x8a, 0x57, 0x93, + 0x45, 0xd4, 0x88, 0x1c, 0x26, 0x07, 0xa5, 0x65, 0x34, 0xdd, 0x7f, + 0x21, 0x95, 0x6a, 0xff, 0x72, 0xc2, 0xf4, 0x17, 0x3a, 0x6e, 0x7b, + 0x6c, 0xc2, 0x21, 0x2b, 0xa0, 0xe3, 0xda, 0xee, 0x1f})), + std::make_pair( + 119, + std::vector<uint8_t>( + {0xdc, 0xc2, 0xc4, 0xbe, 0xb9, 0xc1, 0xf2, 0x60, 0x7b, 0x78, 0x6c, + 0x20, 0xc6, 0x31, 0x97, 0x23, 0x47, 0x03, 0x4c, 0x1c, 0xc0, 0x2f, + 0xcc, 0x7d, 0x02, 0xff, 0x01, 0x09, 0x9c, 0xfe, 0x1c, 0x69, 0x89, + 0x84, 0x0a, 0xc2, 0x13, 0x92, 0x36, 0x29, 0x11, 0x3a, 0xa8, 0xba, + 0xd7, 0x13, 0xcc, 0xf0, 0xfe, 0x4c, 0xe1, 0x32, 0x64, 0xfb, 0x32, + 0xb8, 0xb0, 0xfe, 0x37, 0x2d, 0xa3, 0x82, 0x54, 0x4a})), + std::make_pair( + 120, + std::vector<uint8_t>( + {0x3d, 0x55, 0x17, 0x6a, 0xce, 0xa4, 0xa7, 0xe3, 0xa6, 0x5f, 0xfa, + 0x9f, 0xb1, 0x0a, 0x7a, 0x17, 0x67, 0x19, 0x9c, 0xf0, 0x77, 0xce, + 0xe9, 0xf7, 0x15, 0x32, 0xd6, 0x7c, 0xd7, 0xc7, 0x3c, 0x9f, 0x93, + 0xcf, 0xc3, 0x7c, 0xcd, 0xcc, 0x1f, 0xde, 0xf5, 0x0a, 0xad, 0x46, + 0xa5, 0x04, 0xa6, 0x50, 0xd2, 0x98, 0xd5, 0x97, 0xa3, 0xa9, 0xfa, + 0x95, 0xc6, 0xc4, 0x0c, 0xb7, 0x1f, 0xa5, 0xe7, 0x25})), + std::make_pair( + 121, + std::vector<uint8_t>( + {0xd0, 0x77, 0x13, 0xc0, 0x05, 0xde, 0x96, 0xdd, 0x21, 0xd2, 0xeb, + 0x8b, 0xbe, 0xca, 0x66, 0x74, 0x6e, 0xa5, 0x1a, 0x31, 0xae, 0x92, + 0x2a, 0x3e, 0x74, 0x86, 0x48, 0x89, 0x54, 0x0a, 0x48, 0xdb, 0x27, + 0xd7, 0xe4, 0xc9, 0x03, 0x11, 0x63, 0x8b, 0x22, 0x4b, 0xf0, 0x20, + 0x1b, 0x50, 0x18, 0x91, 0x75, 0x48, 0x48, 0x11, 0x3c, 0x26, 0x61, + 0x08, 0xd0, 0xad, 0xb1, 0x3d, 0xb7, 0x19, 0x09, 0xc7})), + std::make_pair( + 122, + std::vector<uint8_t>( + {0x58, 0x98, 0x3c, 0x21, 0x43, 0x3d, 0x95, 0x0c, 0xaa, 0x23, 0xe4, + 0xbc, 0x18, 0x54, 0x3b, 0x8e, 0x60, 0x1c, 0x20, 0x43, 0x18, 0x53, + 0x21, 0x52, 0xda, 0xf5, 0xe1, 0x59, 0xa0, 0xcd, 0x14, 0x80, 0x18, + 0x3d, 0x29, 0x28, 0x5c, 0x05, 0xf1, 0x29, 0xcb, 0x0c, 0xc3, 0x16, + 0x46, 0x87, 0x92, 0x80, 0x86, 0xff, 0xe3, 0x80, 0x15, 0x8d, 0xf1, + 0xd3, 0x94, 0xc6, 0xac, 0x0d, 0x42, 0x88, 0xbc, 0xa8})), + std::make_pair( + 123, + std::vector<uint8_t>( + {0x81, 0x00, 0xa8, 0xdc, 0x52, 0x8d, 0x2b, 0x68, 0x2a, 0xb4, 0x25, + 0x08, 0x01, 0xba, 0x33, 0xf0, 0x2a, 0x3e, 0x94, 0xc5, 0x4d, 0xac, + 0x0a, 0xe1, 0x48, 0x2a, 0xa2, 0x1f, 0x51, 0xef, 0x3a, 0x82, 0xf3, + 0x80, 0x7e, 0x6f, 0xac, 0xb0, 0xae, 0xb0, 0x59, 0x47, 0xbf, 0x7a, + 0xa2, 0xad, 0xcb, 0x03, 0x43, 0x56, 0xf9, 0x0f, 0xa4, 0x56, 0x0e, + 0xde, 0x02, 0x20, 0x1a, 0x37, 0xe4, 0x11, 0xec, 0x1a})), + std::make_pair( + 124, + std::vector<uint8_t>( + {0x07, 0x02, 0x5f, 0x1b, 0xb6, 0xc7, 0x84, 0xf3, 0xfe, 0x49, 0xde, + 0x5c, 0x14, 0xb9, 0x36, 0xa5, 0xac, 0xac, 0xac, 0xaa, 0xb3, 0x3f, + 0x6a, 0xc4, 0xd0, 0xe0, 0x0a, 0xb6, 0xa1, 0x24, 0x83, 0xd6, 0xbe, + 0xc0, 0x0b, 0x4f, 0xe6, 0x7c, 0x7c, 0xa5, 0xcc, 0x50, 0x8c, 0x2a, + 0x53, 0xef, 0xb5, 0xbf, 0xa5, 0x39, 0x87, 0x69, 0xd8, 0x43, 0xff, + 0x0d, 0x9e, 0x8b, 0x14, 0xd3, 0x6a, 0x01, 0xa7, 0x7f})), + std::make_pair( + 125, + std::vector<uint8_t>( + {0xba, 0x6a, 0xef, 0xd9, 0x72, 0xb6, 0x18, 0x6e, 0x02, 0x7a, 0x76, + 0x27, 0x3a, 0x4a, 0x72, 0x33, 0x21, 0xa3, 0xf5, 0x80, 0xcf, 0xa8, + 0x94, 0xda, 0x5a, 0x9c, 0xe8, 0xe7, 0x21, 0xc8, 0x28, 0x55, 0x2c, + 0x64, 0xda, 0xce, 0xe3, 0xa7, 0xfd, 0x2d, 0x74, 0x3b, 0x5c, 0x35, + 0xad, 0x0c, 0x8e, 0xfa, 0x71, 0xf8, 0xce, 0x99, 0xbf, 0x96, 0x33, + 0x47, 0x10, 0xe2, 0xc2, 0x34, 0x6e, 0x8f, 0x3c, 0x52})), + std::make_pair( + 126, + std::vector<uint8_t>( + {0xe0, 0x72, 0x1e, 0x02, 0x51, 0x7a, 0xed, 0xfa, 0x4e, 0x7e, 0x9b, + 0xa5, 0x03, 0xe0, 0x25, 0xfd, 0x46, 0xe7, 0x14, 0x56, 0x6d, 0xc8, + 0x89, 0xa8, 0x4c, 0xbf, 0xe5, 0x6a, 0x55, 0xdf, 0xbe, 0x2f, 0xc4, + 0x93, 0x8a, 0xc4, 0x12, 0x05, 0x88, 0x33, 0x5d, 0xea, 0xc8, 0xef, + 0x3f, 0xa2, 0x29, 0xad, 0xc9, 0x64, 0x7f, 0x54, 0xad, 0x2e, 0x34, + 0x72, 0x23, 0x4f, 0x9b, 0x34, 0xef, 0xc4, 0x65, 0x43})), + std::make_pair( + 127, + std::vector<uint8_t>( + {0xb6, 0x29, 0x26, 0x69, 0xcc, 0xd3, 0x8d, 0x5f, 0x01, 0xca, 0xae, + 0x96, 0xba, 0x27, 0x2c, 0x76, 0xa8, 0x79, 0xa4, 0x57, 0x43, 0xaf, + 0xa0, 0x72, 0x5d, 0x83, 0xb9, 0xeb, 0xb2, 0x66, 0x65, 0xb7, 0x31, + 0xf1, 0x84, 0x8c, 0x52, 0xf1, 0x19, 0x72, 0xb6, 0x64, 0x4f, 0x55, + 0x4c, 0x06, 0x4f, 0xa9, 0x07, 0x80, 0xdb, 0xbb, 0xf3, 0xa8, 0x9d, + 0x4f, 0xc3, 0x1f, 0x67, 0xdf, 0x3e, 0x58, 0x57, 0xef})), + std::make_pair( + 128, + std::vector<uint8_t>( + {0x23, 0x19, 0xe3, 0x78, 0x9c, 0x47, 0xe2, 0xda, 0xa5, 0xfe, 0x80, + 0x7f, 0x61, 0xbe, 0xc2, 0xa1, 0xa6, 0x53, 0x7f, 0xa0, 0x3f, 0x19, + 0xff, 0x32, 0xe8, 0x7e, 0xec, 0xbf, 0xd6, 0x4b, 0x7e, 0x0e, 0x8c, + 0xcf, 0xf4, 0x39, 0xac, 0x33, 0x3b, 0x04, 0x0f, 0x19, 0xb0, 0xc4, + 0xdd, 0xd1, 0x1a, 0x61, 0xe2, 0x4a, 0xc1, 0xfe, 0x0f, 0x10, 0xa0, + 0x39, 0x80, 0x6c, 0x5d, 0xcc, 0x0d, 0xa3, 0xd1, 0x15})), + std::make_pair( + 129, + std::vector<uint8_t>( + {0xf5, 0x97, 0x11, 0xd4, 0x4a, 0x03, 0x1d, 0x5f, 0x97, 0xa9, 0x41, + 0x3c, 0x06, 0x5d, 0x1e, 0x61, 0x4c, 0x41, 0x7e, 0xde, 0x99, 0x85, + 0x90, 0x32, 0x5f, 0x49, 0xba, 0xd2, 0xfd, 0x44, 0x4d, 0x3e, 0x44, + 0x18, 0xbe, 0x19, 0xae, 0xc4, 0xe1, 0x14, 0x49, 0xac, 0x1a, 0x57, + 0x20, 0x78, 0x98, 0xbc, 0x57, 0xd7, 0x6a, 0x1b, 0xcf, 0x35, 0x66, + 0x29, 0x2c, 0x20, 0xc6, 0x83, 0xa5, 0xc4, 0x64, 0x8f})), + std::make_pair( + 130, + std::vector<uint8_t>( + {0xdf, 0x0a, 0x9d, 0x0c, 0x21, 0x28, 0x43, 0xa6, 0xa9, 0x34, 0xe3, + 0x90, 0x2b, 0x2d, 0xd3, 0x0d, 0x17, 0xfb, 0xa5, 0xf9, 0x69, 0xd2, + 0x03, 0x0b, 0x12, 0xa5, 0x46, 0xd8, 0xa6, 0xa4, 0x5e, 0x80, 0xcf, + 0x56, 0x35, 0xf0, 0x71, 0xf0, 0x45, 0x2e, 0x9c, 0x91, 0x92, 0x75, + 0xda, 0x99, 0xbe, 0xd5, 0x1e, 0xb1, 0x17, 0x3c, 0x1a, 0xf0, 0x51, + 0x87, 0x26, 0xb7, 0x5b, 0x0e, 0xc3, 0xba, 0xe2, 0xb5})), + std::make_pair( + 131, + std::vector<uint8_t>( + {0xa3, 0xeb, 0x6e, 0x6c, 0x7b, 0xf2, 0xfb, 0x8b, 0x28, 0xbf, 0xe8, + 0xb1, 0x5e, 0x15, 0xbb, 0x50, 0x0f, 0x78, 0x1e, 0xcc, 0x86, 0xf7, + 0x78, 0xc3, 0xa4, 0xe6, 0x55, 0xfc, 0x58, 0x69, 0xbf, 0x28, 0x46, + 0xa2, 0x45, 0xd4, 0xe3, 0x3b, 0x7b, 0x14, 0x43, 0x6a, 0x17, 0xe6, + 0x3b, 0xe7, 0x9b, 0x36, 0x65, 0x5c, 0x22, 0x6a, 0x50, 0xff, 0xbc, + 0x71, 0x24, 0x20, 0x7b, 0x02, 0x02, 0x34, 0x2d, 0xb5})), + std::make_pair( + 132, + std::vector<uint8_t>( + {0x56, 0xd4, 0xcb, 0xcd, 0x07, 0x05, 0x63, 0x42, 0x6a, 0x01, 0x70, + 0x69, 0x42, 0x5c, 0x2c, 0xd2, 0xae, 0x54, 0x06, 0x68, 0x28, 0x7a, + 0x5f, 0xb9, 0xda, 0xc4, 0x32, 0xeb, 0x8a, 0xb1, 0xa3, 0x53, 0xa3, + 0x0f, 0x2f, 0xe1, 0xf4, 0x0d, 0x83, 0x33, 0x3a, 0xfe, 0x69, 0x6a, + 0x26, 0x77, 0x95, 0x40, 0x8a, 0x92, 0xfe, 0x7d, 0xa0, 0x7a, 0x0c, + 0x18, 0x14, 0xcf, 0x77, 0xf3, 0x6e, 0x10, 0x5e, 0xe8})), + std::make_pair( + 133, + std::vector<uint8_t>( + {0xe5, 0x9b, 0x99, 0x87, 0xd4, 0x28, 0xb3, 0xed, 0xa3, 0x7d, 0x80, + 0xab, 0xdb, 0x16, 0xcd, 0x2b, 0x0a, 0xef, 0x67, 0x4c, 0x2b, 0x1d, + 0xda, 0x44, 0x32, 0xea, 0x91, 0xee, 0x6c, 0x93, 0x5c, 0x68, 0x4b, + 0x48, 0xb4, 0x42, 0x8a, 0x8c, 0xc7, 0x40, 0xe5, 0x79, 0xa3, 0x0d, + 0xef, 0xf3, 0x5a, 0x80, 0x30, 0x13, 0x82, 0x0d, 0xd2, 0x3f, 0x14, + 0xae, 0x1d, 0x84, 0x13, 0xb5, 0xc8, 0x67, 0x2a, 0xec})), + std::make_pair( + 134, + std::vector<uint8_t>( + {0xcd, 0x9f, 0xcc, 0x99, 0xf9, 0x9d, 0x4c, 0xc1, 0x6d, 0x03, 0x19, + 0x00, 0xb2, 0xa7, 0x36, 0xe1, 0x50, 0x8d, 0xb4, 0xb5, 0x86, 0x81, + 0x4e, 0x63, 0x45, 0x85, 0x7f, 0x35, 0x4a, 0x70, 0xcc, 0xec, 0xb1, + 0xdf, 0x3b, 0x50, 0xa1, 0x9a, 0xda, 0xf4, 0x3c, 0x27, 0x8e, 0xfa, + 0x42, 0x3f, 0xf4, 0xbb, 0x6c, 0x52, 0x3e, 0xc7, 0xfd, 0x78, 0x59, + 0xb9, 0x7b, 0x16, 0x8a, 0x7e, 0xbf, 0xf8, 0x46, 0x7c})), + std::make_pair( + 135, + std::vector<uint8_t>( + {0x06, 0x02, 0x18, 0x5d, 0x8c, 0x3a, 0x78, 0x73, 0x8b, 0x99, 0x16, + 0x4b, 0x8b, 0xc6, 0xff, 0xb2, 0x1c, 0x7d, 0xeb, 0xeb, 0xbf, 0x80, + 0x63, 0x72, 0xe0, 0xda, 0x44, 0xd1, 0x21, 0x54, 0x55, 0x97, 0xb9, + 0xc6, 0x62, 0xa2, 0x55, 0xdc, 0x31, 0x54, 0x2c, 0xf9, 0x95, 0xec, + 0xbe, 0x6a, 0x50, 0xfb, 0x5e, 0x6e, 0x0e, 0xe4, 0xef, 0x24, 0x0f, + 0xe5, 0x57, 0xed, 0xed, 0x11, 0x88, 0x08, 0x7e, 0x86})), + std::make_pair( + 136, + std::vector<uint8_t>( + {0xc0, 0x8a, 0xfa, 0x5b, 0x92, 0x7b, 0xf0, 0x80, 0x97, 0xaf, 0xc5, + 0xff, 0xf9, 0xca, 0x4e, 0x78, 0x00, 0x12, 0x5c, 0x1f, 0x52, 0xf2, + 0xaf, 0x35, 0x53, 0xfa, 0x2b, 0x89, 0xe1, 0xe3, 0x01, 0x5c, 0x4f, + 0x87, 0xd5, 0xe0, 0xa4, 0x89, 0x56, 0xad, 0x31, 0x45, 0x0b, 0x08, + 0x3d, 0xad, 0x14, 0x7f, 0xfb, 0x5e, 0xc0, 0x34, 0x34, 0xa2, 0x68, + 0x30, 0xcf, 0x37, 0xd1, 0x03, 0xab, 0x50, 0xc5, 0xda})), + std::make_pair( + 137, + std::vector<uint8_t>( + {0x36, 0xf1, 0xe1, 0xc1, 0x1d, 0x6e, 0xf6, 0xbc, 0x3b, 0x53, 0x6d, + 0x50, 0x5d, 0x54, 0x4a, 0x87, 0x15, 0x22, 0xc5, 0xc2, 0xa2, 0x53, + 0x06, 0x7e, 0xc9, 0x93, 0x3b, 0x6e, 0xc2, 0x54, 0x64, 0xda, 0xf9, + 0x85, 0x52, 0x5f, 0x5b, 0x95, 0x60, 0xa1, 0x6d, 0x89, 0x02, 0x59, + 0xac, 0x1b, 0xb5, 0xcc, 0x67, 0xc0, 0xc4, 0x69, 0xcd, 0xe1, 0x33, + 0xde, 0xf0, 0x00, 0xea, 0x1d, 0x68, 0x6f, 0x4f, 0x5d})), + std::make_pair( + 138, + std::vector<uint8_t>( + {0xbf, 0x2a, 0xb2, 0xe2, 0x47, 0x0f, 0x54, 0x38, 0xc3, 0xb6, 0x89, + 0xe6, 0x6e, 0x76, 0x86, 0xff, 0xfa, 0x0c, 0xb1, 0xe1, 0x79, 0x8a, + 0xd3, 0xa8, 0x6f, 0xf9, 0x90, 0x75, 0xbf, 0x61, 0x38, 0xe3, 0x3d, + 0x9c, 0x0c, 0xe5, 0x9a, 0xfb, 0x24, 0xac, 0x67, 0xa0, 0x2a, 0xf3, + 0x44, 0x28, 0x19, 0x1a, 0x9a, 0x0a, 0x60, 0x41, 0xc0, 0x74, 0x71, + 0xb7, 0xc3, 0xb1, 0xa7, 0x52, 0xd6, 0xfc, 0x0b, 0x8b})), + std::make_pair( + 139, + std::vector<uint8_t>( + {0xd4, 0x00, 0x60, 0x1f, 0x97, 0x28, 0xcc, 0xc4, 0xc9, 0x23, 0x42, + 0xd9, 0x78, 0x7d, 0x8d, 0x28, 0xab, 0x32, 0x3a, 0xf3, 0x75, 0xca, + 0x56, 0x24, 0xb4, 0xbb, 0x91, 0xd1, 0x72, 0x71, 0xfb, 0xae, 0x86, + 0x2e, 0x41, 0x3b, 0xe7, 0x3f, 0x1f, 0x68, 0xe6, 0x15, 0xb8, 0xc5, + 0xc3, 0x91, 0xbe, 0x0d, 0xbd, 0x91, 0x44, 0x74, 0x6e, 0xb3, 0x39, + 0xad, 0x54, 0x15, 0x47, 0xba, 0x9c, 0x46, 0x8a, 0x17})), + std::make_pair( + 140, + std::vector<uint8_t>( + {0x79, 0xfe, 0x2f, 0xe1, 0x57, 0xeb, 0x85, 0xa0, 0x38, 0xab, 0xb8, + 0xeb, 0xbc, 0x64, 0x77, 0x31, 0xd2, 0xc8, 0x3f, 0x51, 0xb0, 0xac, + 0x6e, 0xe1, 0x4a, 0xa2, 0x84, 0xcb, 0x6a, 0x35, 0x49, 0xa4, 0xdc, + 0xce, 0xb3, 0x00, 0x74, 0x0a, 0x82, 0x5f, 0x52, 0xf5, 0xfb, 0x30, + 0xb0, 0x3b, 0x8c, 0x4d, 0x8b, 0x0f, 0x4a, 0xa6, 0x7a, 0x63, 0xf4, + 0xa9, 0x4e, 0x33, 0x03, 0xc4, 0xed, 0xa4, 0xc0, 0x2b})), + std::make_pair( + 141, + std::vector<uint8_t>( + {0x75, 0x35, 0x13, 0x13, 0xb5, 0x2a, 0x85, 0x29, 0x29, 0x8d, 0x8c, + 0x18, 0x6b, 0x17, 0x68, 0x66, 0x6d, 0xcc, 0xa8, 0x59, 0x53, 0x17, + 0xd7, 0xa4, 0x81, 0x6e, 0xb8, 0x8c, 0x06, 0x20, 0x20, 0xc0, 0xc8, + 0xef, 0xc5, 0x54, 0xbb, 0x34, 0x1b, 0x64, 0x68, 0x8d, 0xb5, 0xcc, + 0xaf, 0xc3, 0x5f, 0x3c, 0x3c, 0xd0, 0x9d, 0x65, 0x64, 0xb3, 0x6d, + 0x7b, 0x04, 0xa2, 0x48, 0xe1, 0x46, 0x98, 0x0d, 0x4b})), + std::make_pair( + 142, + std::vector<uint8_t>( + {0xe3, 0x12, 0x8b, 0x1d, 0x31, 0x1d, 0x02, 0x17, 0x9d, 0x7f, 0x25, + 0xf9, 0x7a, 0x5a, 0x8b, 0xee, 0x2c, 0xc8, 0xc8, 0x63, 0x03, 0x64, + 0x4f, 0xcd, 0x66, 0x4e, 0x15, 0x7d, 0x1f, 0xef, 0x00, 0xf2, 0x3e, + 0x46, 0xf9, 0xa5, 0xe8, 0xe5, 0xc8, 0x90, 0xce, 0x56, 0x5b, 0xb6, + 0xab, 0xd4, 0x30, 0x2c, 0xe0, 0x64, 0x69, 0xd5, 0x2a, 0x5b, 0xd5, + 0x3e, 0x1c, 0x5a, 0x54, 0xd0, 0x46, 0x49, 0xdc, 0x03})), + std::make_pair( + 143, + std::vector<uint8_t>( + {0xc2, 0x38, 0x2a, 0x72, 0xd2, 0xd3, 0xac, 0xe9, 0xd5, 0x93, 0x3d, + 0x00, 0xb6, 0x08, 0x27, 0xed, 0x38, 0x0c, 0xda, 0x08, 0xd0, 0xba, + 0x5f, 0x6d, 0xd4, 0x1e, 0x29, 0xee, 0x6d, 0xbe, 0x8e, 0xcb, 0x92, + 0x35, 0xf0, 0x6b, 0xe9, 0x5d, 0x83, 0xb6, 0x81, 0x6a, 0x2f, 0xb7, + 0xa5, 0xad, 0x47, 0x03, 0x5e, 0x8a, 0x4b, 0x69, 0xa4, 0x88, 0x4b, + 0x99, 0xe4, 0xbe, 0xce, 0x58, 0xca, 0xb2, 0x5d, 0x44})), + std::make_pair( + 144, + std::vector<uint8_t>( + {0x6b, 0x1c, 0x69, 0x46, 0x0b, 0xbd, 0x50, 0xac, 0x2e, 0xd6, 0xf3, + 0x2e, 0x6e, 0x88, 0x7c, 0xfe, 0xd4, 0x07, 0xd4, 0x7d, 0xcf, 0x0a, + 0xaa, 0x60, 0x38, 0x7f, 0xe3, 0x20, 0xd7, 0x80, 0xbd, 0x03, 0xea, + 0xb6, 0xd7, 0xba, 0xeb, 0x2a, 0x07, 0xd1, 0x0c, 0xd5, 0x52, 0xa3, + 0x00, 0x34, 0x13, 0x54, 0xea, 0x9a, 0x5f, 0x03, 0x18, 0x3a, 0x62, + 0x3f, 0x92, 0xa2, 0xd4, 0xd9, 0xf0, 0x09, 0x26, 0xaf})), + std::make_pair( + 145, + std::vector<uint8_t>( + {0x6c, 0xda, 0x20, 0x6c, 0x80, 0xcd, 0xc9, 0xc4, 0x4b, 0xa9, 0x90, + 0xe0, 0x32, 0x8c, 0x31, 0x4f, 0x81, 0x9b, 0x14, 0x2d, 0x00, 0x63, + 0x04, 0x04, 0xc4, 0x8c, 0x05, 0xdc, 0x76, 0xd1, 0xb0, 0x0c, 0xe4, + 0xd7, 0x2f, 0xc6, 0xa4, 0x8e, 0x14, 0x69, 0xdd, 0xef, 0x60, 0x94, + 0x12, 0xc3, 0x64, 0x82, 0x08, 0x54, 0x21, 0x4b, 0x48, 0x69, 0xaf, + 0x09, 0x0f, 0x00, 0xd3, 0xc1, 0xba, 0x44, 0x3e, 0x1b})), + std::make_pair( + 146, + std::vector<uint8_t>( + {0x7f, 0xfc, 0x8c, 0x26, 0xfb, 0xd6, 0xa0, 0xf7, 0xa6, 0x09, 0xe6, + 0xe1, 0x93, 0x9f, 0x6a, 0x9e, 0xdf, 0x1b, 0x0b, 0x06, 0x66, 0x41, + 0xfb, 0x76, 0xc4, 0xf9, 0x60, 0x2e, 0xd7, 0x48, 0xd1, 0x16, 0x02, + 0x49, 0x6b, 0x35, 0x35, 0x5b, 0x1a, 0xa2, 0x55, 0x85, 0x0a, 0x50, + 0x9d, 0x2f, 0x8e, 0xe1, 0x8c, 0x8f, 0x3e, 0x1d, 0x7d, 0xcb, 0xc3, + 0x7a, 0x13, 0x65, 0x98, 0xf5, 0x6a, 0x59, 0xed, 0x17})), + std::make_pair( + 147, + std::vector<uint8_t>( + {0x70, 0xde, 0x1f, 0x08, 0xdd, 0x4e, 0x09, 0xd5, 0xfc, 0x15, 0x1f, + 0x17, 0xfc, 0x99, 0x1a, 0x23, 0xab, 0xfc, 0x05, 0x10, 0x42, 0x90, + 0xd5, 0x04, 0x68, 0x88, 0x2e, 0xfa, 0xf5, 0x82, 0xb6, 0xec, 0x2f, + 0x14, 0xf5, 0x77, 0xc0, 0xd6, 0x8c, 0x3a, 0xd0, 0x66, 0x26, 0x91, + 0x6e, 0x3c, 0x86, 0xe6, 0xda, 0xab, 0x6c, 0x53, 0xe5, 0x16, 0x3e, + 0x82, 0xb6, 0xbd, 0x0c, 0xe4, 0x9f, 0xc0, 0xd8, 0xdf})), + std::make_pair( + 148, + std::vector<uint8_t>( + {0x4f, 0x81, 0x93, 0x57, 0x56, 0xed, 0x35, 0xee, 0x20, 0x58, 0xee, + 0x0c, 0x6a, 0x61, 0x10, 0xd6, 0xfa, 0xc5, 0xcb, 0x6a, 0x4f, 0x46, + 0xaa, 0x94, 0x11, 0x60, 0x3f, 0x99, 0x96, 0x58, 0x23, 0xb6, 0xda, + 0x48, 0x38, 0x27, 0x6c, 0x5c, 0x06, 0xbc, 0x78, 0x80, 0xe3, 0x76, + 0xd9, 0x27, 0x58, 0x36, 0x9e, 0xe7, 0x30, 0x5b, 0xce, 0xc8, 0xd3, + 0xcf, 0xd2, 0x8c, 0xca, 0xbb, 0x7b, 0x4f, 0x05, 0x79})), + std::make_pair( + 149, + std::vector<uint8_t>( + {0xab, 0xcb, 0x61, 0xcb, 0x36, 0x83, 0xd1, 0x8f, 0x27, 0xad, 0x52, + 0x79, 0x08, 0xed, 0x2d, 0x32, 0xa0, 0x42, 0x6c, 0xb7, 0xbb, 0x4b, + 0xf1, 0x80, 0x61, 0x90, 0x3a, 0x7d, 0xc4, 0x2e, 0x7e, 0x76, 0xf9, + 0x82, 0x38, 0x23, 0x04, 0xd1, 0x8a, 0xf8, 0xc8, 0x0d, 0x91, 0xdd, + 0x58, 0xdd, 0x47, 0xaf, 0x76, 0xf8, 0xe2, 0xc3, 0x6e, 0x28, 0xaf, + 0x24, 0x76, 0xb4, 0xbc, 0xcf, 0x82, 0xe8, 0x9f, 0xdf})), + std::make_pair( + 150, + std::vector<uint8_t>( + {0x02, 0xd2, 0x61, 0xad, 0x56, 0xa5, 0x26, 0x33, 0x1b, 0x64, 0x3d, + 0xd2, 0x18, 0x6d, 0xe9, 0xa8, 0x2e, 0x72, 0xa5, 0x82, 0x23, 0xcd, + 0x1e, 0x72, 0x36, 0x86, 0xc5, 0x3d, 0x86, 0x9b, 0x83, 0xb9, 0x46, + 0x32, 0xb7, 0xb6, 0x47, 0xab, 0x2a, 0xfc, 0x0d, 0x52, 0x2e, 0x29, + 0xda, 0x3a, 0x56, 0x15, 0xb7, 0x41, 0xd8, 0x28, 0x52, 0xe0, 0xdf, + 0x41, 0xb6, 0x60, 0x07, 0xdb, 0xcb, 0xa9, 0x05, 0x43})), + std::make_pair( + 151, + std::vector<uint8_t>( + {0xc5, 0x83, 0x27, 0x41, 0xfa, 0x30, 0xc5, 0x43, 0x68, 0x23, 0x01, + 0x53, 0x83, 0xd2, 0x97, 0xff, 0x4c, 0x4a, 0x5d, 0x72, 0x76, 0xc3, + 0xf9, 0x02, 0x12, 0x20, 0x66, 0xe0, 0x4b, 0xe5, 0x43, 0x1b, 0x1a, + 0x85, 0xfa, 0xf7, 0x3b, 0x91, 0x84, 0x34, 0xf9, 0x30, 0x09, 0x63, + 0xd1, 0xde, 0xa9, 0xe8, 0xac, 0x39, 0x24, 0xef, 0x49, 0x02, 0x26, + 0xed, 0xee, 0xa5, 0xf7, 0x43, 0xe4, 0x10, 0x66, 0x9f})), + std::make_pair( + 152, + std::vector<uint8_t>( + {0xcf, 0xae, 0xab, 0x26, 0x8c, 0xd0, 0x75, 0xa5, 0xa6, 0xae, 0xd5, + 0x15, 0x02, 0x3a, 0x03, 0x2d, 0x54, 0xf2, 0xf2, 0xff, 0x73, 0x3c, + 0xe0, 0xcb, 0xc7, 0x8d, 0xb5, 0x1d, 0xb4, 0x50, 0x4d, 0x67, 0x59, + 0x23, 0xf8, 0x27, 0x46, 0xd6, 0x59, 0x46, 0x06, 0xad, 0x5d, 0x67, + 0x73, 0x4b, 0x11, 0xa6, 0x7c, 0xc6, 0xa4, 0x68, 0xc2, 0x03, 0x2e, + 0x43, 0xca, 0x1a, 0x94, 0xc6, 0x27, 0x3a, 0x98, 0x5e})), + std::make_pair( + 153, + std::vector<uint8_t>( + {0x86, 0x08, 0x50, 0xf9, 0x2e, 0xb2, 0x68, 0x27, 0x2b, 0x67, 0xd1, + 0x33, 0x60, 0x9b, 0xd6, 0x4e, 0x34, 0xf6, 0x1b, 0xf0, 0x3f, 0x4c, + 0x17, 0x38, 0x64, 0x5c, 0x17, 0xfe, 0xc8, 0x18, 0x46, 0x5d, 0x7e, + 0xcd, 0x2b, 0xe2, 0x90, 0x76, 0x41, 0x13, 0x00, 0x25, 0xfd, 0xa7, + 0x94, 0x70, 0xab, 0x73, 0x16, 0x46, 0xe7, 0xf6, 0x94, 0x40, 0xe8, + 0x36, 0x7e, 0xa7, 0x6a, 0xc4, 0xce, 0xe8, 0xa1, 0xdf})), + std::make_pair( + 154, + std::vector<uint8_t>( + {0x84, 0xb1, 0x54, 0xed, 0x29, 0xbb, 0xed, 0xef, 0xa6, 0x48, 0x28, + 0x68, 0x39, 0x04, 0x6f, 0x4b, 0x5a, 0xa3, 0x44, 0x30, 0xe2, 0xd6, + 0x7f, 0x74, 0x96, 0xe4, 0xc3, 0x9f, 0x2c, 0x7e, 0xa7, 0x89, 0x95, + 0xf6, 0x9e, 0x12, 0x92, 0x20, 0x00, 0x16, 0xf1, 0x6a, 0xc3, 0xb3, + 0x77, 0x00, 0xe6, 0xc7, 0xe7, 0x86, 0x1a, 0xfc, 0x39, 0x6b, 0x64, + 0xa5, 0x9a, 0x1d, 0xbf, 0x47, 0xa5, 0x5c, 0x4b, 0xbc})), + std::make_pair( + 155, + std::vector<uint8_t>( + {0xae, 0xee, 0xc2, 0x60, 0xa5, 0xd8, 0xef, 0xf5, 0xcc, 0xab, 0x8b, + 0x95, 0xda, 0x43, 0x5a, 0x63, 0xed, 0x7a, 0x21, 0xea, 0x7f, 0xc7, + 0x55, 0x94, 0x13, 0xfd, 0x61, 0x7e, 0x33, 0x60, 0x9f, 0x8c, 0x29, + 0x0e, 0x64, 0xbb, 0xac, 0xc5, 0x28, 0xf6, 0xc0, 0x80, 0x26, 0x22, + 0x88, 0xb0, 0xf0, 0xa3, 0x21, 0x9b, 0xe2, 0x23, 0xc9, 0x91, 0xbe, + 0xe9, 0x2e, 0x72, 0x34, 0x95, 0x93, 0xe6, 0x76, 0x38})), + std::make_pair( + 156, + std::vector<uint8_t>( + {0x8a, 0xd7, 0x8a, 0x9f, 0x26, 0x60, 0x1d, 0x12, 0x7e, 0x8d, 0x2f, + 0x2f, 0x97, 0x6e, 0x63, 0xd1, 0x9a, 0x05, 0x4a, 0x17, 0xdc, 0xf5, + 0x9e, 0x0f, 0x01, 0x3a, 0xb5, 0x4a, 0x68, 0x87, 0xbb, 0xdf, 0xfd, + 0xe7, 0xaa, 0xae, 0x11, 0x7e, 0x0f, 0xbf, 0x32, 0x71, 0x01, 0x65, + 0x95, 0xb9, 0xd9, 0xc7, 0x12, 0xc0, 0x1b, 0x2c, 0x53, 0xe9, 0x65, + 0x5a, 0x38, 0x2b, 0xc4, 0x52, 0x2e, 0x61, 0x66, 0x45})), + std::make_pair( + 157, + std::vector<uint8_t>( + {0x89, 0x34, 0x15, 0x9d, 0xad, 0xe1, 0xac, 0x74, 0x14, 0x7d, 0xfa, + 0x28, 0x2c, 0x75, 0x95, 0x4f, 0xce, 0xf4, 0x43, 0xef, 0x25, 0xf8, + 0x0d, 0xfe, 0x9f, 0xb6, 0xea, 0x63, 0x3b, 0x85, 0x45, 0x11, 0x1d, + 0x08, 0xb3, 0x4e, 0xf4, 0x3f, 0xff, 0x17, 0x02, 0x6c, 0x79, 0x64, + 0xf5, 0xde, 0xac, 0x6d, 0x2b, 0x3c, 0x29, 0xda, 0xcf, 0x27, 0x47, + 0xf0, 0x22, 0xdf, 0x59, 0x67, 0xdf, 0xdc, 0x1a, 0x0a})), + std::make_pair( + 158, + std::vector<uint8_t>( + {0xcd, 0x36, 0xdd, 0x0b, 0x24, 0x06, 0x14, 0xcf, 0x2f, 0xa2, 0xb9, + 0xe9, 0x59, 0x67, 0x9d, 0xcd, 0xd7, 0x2e, 0xc0, 0xcd, 0x58, 0xa4, + 0x3d, 0xa3, 0x79, 0x0a, 0x92, 0xf6, 0xcd, 0xeb, 0x9e, 0x1e, 0x79, + 0x5e, 0x47, 0x8a, 0x0a, 0x47, 0xd3, 0x71, 0x10, 0x0d, 0x34, 0x0c, + 0x5c, 0xed, 0xcd, 0xbb, 0xc9, 0xe6, 0x8b, 0x3f, 0x46, 0x08, 0x18, + 0xe5, 0xbd, 0xff, 0x7b, 0x4c, 0xda, 0x4c, 0x27, 0x44})), + std::make_pair( + 159, + std::vector<uint8_t>( + {0x00, 0xdf, 0x4e, 0x09, 0x9b, 0x80, 0x71, 0x37, 0xa8, 0x59, 0x90, + 0xf4, 0x9d, 0x3a, 0x94, 0x31, 0x5e, 0x5a, 0x5f, 0x7f, 0x7a, 0x60, + 0x76, 0xb3, 0x03, 0xe9, 0x6b, 0x05, 0x6f, 0xb9, 0x38, 0x00, 0x11, + 0x1f, 0x47, 0x96, 0x28, 0xe2, 0xf8, 0xdb, 0x59, 0xae, 0xb6, 0xac, + 0x70, 0xc3, 0xb6, 0x1f, 0x51, 0xf9, 0xb4, 0x6e, 0x80, 0xff, 0xde, + 0xae, 0x25, 0xeb, 0xdd, 0xb4, 0xaf, 0x6c, 0xb4, 0xee})), + std::make_pair( + 160, + std::vector<uint8_t>( + {0x2b, 0x9c, 0x95, 0x5e, 0x6c, 0xae, 0xd4, 0xb7, 0xc9, 0xe2, 0x46, + 0xb8, 0x6f, 0x9a, 0x17, 0x26, 0xe8, 0x10, 0xc5, 0x9d, 0x12, 0x6c, + 0xee, 0x66, 0xed, 0x71, 0xbf, 0x01, 0x5b, 0x83, 0x55, 0x8a, 0x4b, + 0x6d, 0x84, 0xd1, 0x8d, 0xc3, 0xff, 0x46, 0x20, 0xc2, 0xff, 0xb7, + 0x22, 0x35, 0x9f, 0xde, 0xf8, 0x5b, 0xa0, 0xd4, 0xe2, 0xd2, 0x2e, + 0xcb, 0xe0, 0xed, 0x78, 0x4f, 0x99, 0xaf, 0xe5, 0x87})), + std::make_pair( + 161, + std::vector<uint8_t>( + {0x18, 0x1d, 0xf0, 0xa2, 0x61, 0xa2, 0xf7, 0xd2, 0x9e, 0xa5, 0xa1, + 0x57, 0x72, 0x71, 0x51, 0x05, 0xd4, 0x50, 0xa4, 0xb6, 0xc2, 0x36, + 0xf6, 0x99, 0xf4, 0x62, 0xd6, 0x0c, 0xa7, 0x64, 0x87, 0xfe, 0xed, + 0xfc, 0x9f, 0x5e, 0xb9, 0x2d, 0xf8, 0x38, 0xe8, 0xfb, 0x5d, 0xc3, + 0x69, 0x4e, 0x84, 0xc5, 0xe0, 0xf4, 0xa1, 0x0b, 0x76, 0x1f, 0x50, + 0x67, 0x62, 0xbe, 0x05, 0x2c, 0x74, 0x5a, 0x6e, 0xe8})), + std::make_pair( + 162, + std::vector<uint8_t>( + {0x21, 0xfb, 0x20, 0x34, 0x58, 0xbf, 0x3a, 0x7e, 0x9a, 0x80, 0x43, + 0x9f, 0x9a, 0x90, 0x28, 0x99, 0xcd, 0x5d, 0xe0, 0x13, 0x9d, 0xfd, + 0x56, 0xf7, 0x11, 0x0c, 0x9d, 0xec, 0x84, 0x37, 0xb2, 0x6b, 0xda, + 0x63, 0xde, 0x2f, 0x56, 0x59, 0x26, 0xd8, 0x5e, 0xdb, 0x1d, 0x6c, + 0x68, 0x25, 0x66, 0x97, 0x43, 0xdd, 0x99, 0x92, 0x65, 0x3d, 0x13, + 0x97, 0x95, 0x44, 0xd5, 0xdc, 0x82, 0x28, 0xbf, 0xaa})), + std::make_pair( + 163, + std::vector<uint8_t>( + {0xef, 0x02, 0x1f, 0x29, 0xc5, 0xff, 0xb8, 0x30, 0xe6, 0x4b, 0x9a, + 0xa9, 0x05, 0x8d, 0xd6, 0x60, 0xfd, 0x2f, 0xcb, 0x81, 0xc4, 0x97, + 0xa7, 0xe6, 0x98, 0xbc, 0xfb, 0xf5, 0x9d, 0xe5, 0xad, 0x4a, 0x86, + 0xff, 0x93, 0xc1, 0x0a, 0x4b, 0x9d, 0x1a, 0xe5, 0x77, 0x47, 0x25, + 0xf9, 0x07, 0x2d, 0xcd, 0xe9, 0xe1, 0xf1, 0x99, 0xba, 0xb9, 0x1f, + 0x8b, 0xff, 0x92, 0x18, 0x64, 0xaa, 0x50, 0x2e, 0xee})), + std::make_pair( + 164, + std::vector<uint8_t>( + {0xb3, 0xcf, 0xda, 0x40, 0x52, 0x6b, 0x7f, 0x1d, 0x37, 0x56, 0x9b, + 0xdf, 0xcd, 0xf9, 0x11, 0xe5, 0xa6, 0xef, 0xe6, 0xb2, 0xec, 0x90, + 0xa0, 0x45, 0x4c, 0x47, 0xb2, 0xc0, 0x46, 0xbf, 0x13, 0x0f, 0xc3, + 0xb3, 0x52, 0xb3, 0x4d, 0xf4, 0x81, 0x3d, 0x48, 0xd3, 0x3a, 0xb8, + 0xe2, 0x69, 0xb6, 0x9b, 0x07, 0x56, 0x76, 0xcb, 0x6d, 0x00, 0xa8, + 0xdc, 0xf9, 0xe1, 0xf9, 0x67, 0xec, 0x19, 0x1b, 0x2c})), + std::make_pair( + 165, + std::vector<uint8_t>( + {0xb4, 0xc6, 0xc3, 0xb2, 0x67, 0x07, 0x1e, 0xef, 0xb9, 0xc8, 0xc7, + 0x2e, 0x0e, 0x2b, 0x94, 0x12, 0x93, 0x64, 0x1f, 0x86, 0x73, 0xcb, + 0x70, 0xc1, 0xcc, 0x26, 0xad, 0x1e, 0x73, 0xcf, 0x14, 0x17, 0x55, + 0x86, 0x0a, 0xd1, 0x9b, 0x34, 0xc2, 0xf3, 0x4e, 0xd3, 0x5b, 0xb5, + 0x2e, 0xc4, 0x50, 0x7c, 0xc1, 0xfe, 0x59, 0x04, 0x77, 0x43, 0xa5, + 0xf0, 0xc6, 0xfe, 0xbd, 0xe6, 0x25, 0xe2, 0x60, 0x91})), + std::make_pair( + 166, + std::vector<uint8_t>( + {0x57, 0xa3, 0x4f, 0x2b, 0xcc, 0xa6, 0x0d, 0x4b, 0x85, 0x10, 0x3b, + 0x83, 0x0c, 0x9d, 0x79, 0x52, 0xa4, 0x16, 0xbe, 0x52, 0x63, 0xae, + 0x42, 0x9c, 0x9e, 0x5e, 0x53, 0xfe, 0x85, 0x90, 0xa8, 0xf7, 0x8e, + 0xc6, 0x5a, 0x51, 0x10, 0x9e, 0xa8, 0x5d, 0xcd, 0xf7, 0xb6, 0x22, + 0x3f, 0x9f, 0x2b, 0x34, 0x05, 0x39, 0xfa, 0xd8, 0x19, 0x23, 0xdb, + 0xf8, 0xed, 0xab, 0xf9, 0x51, 0x29, 0xe4, 0xdf, 0xf6})), + std::make_pair( + 167, + std::vector<uint8_t>( + {0x9c, 0xf4, 0x66, 0x62, 0xfc, 0xd6, 0x1a, 0x23, 0x22, 0x77, 0xb6, + 0x85, 0x66, 0x3b, 0x8b, 0x5d, 0xa8, 0x32, 0xdf, 0xd9, 0xa3, 0xb8, + 0xcc, 0xfe, 0xec, 0x99, 0x3e, 0xc6, 0xac, 0x41, 0x5a, 0xd0, 0x7e, + 0x04, 0x8a, 0xdf, 0xe4, 0x14, 0xdf, 0x27, 0x27, 0x70, 0xdb, 0xa8, + 0x67, 0xda, 0x5c, 0x12, 0x24, 0xc6, 0xfd, 0x0a, 0xa0, 0xc2, 0x18, + 0x7d, 0x42, 0x6a, 0xc6, 0x47, 0xe9, 0x88, 0x73, 0x61})), + std::make_pair( + 168, + std::vector<uint8_t>( + {0x5c, 0xe1, 0x04, 0x2a, 0xb4, 0xd5, 0x42, 0xc2, 0xf9, 0xee, 0x9d, + 0x17, 0x26, 0x2a, 0xf8, 0x16, 0x40, 0x98, 0x93, 0x5b, 0xef, 0x17, + 0x3d, 0x0e, 0x18, 0x48, 0x9b, 0x04, 0x84, 0x17, 0x46, 0xcd, 0x2f, + 0x2d, 0xf8, 0x66, 0xbd, 0x7d, 0xa6, 0xe5, 0xef, 0x90, 0x24, 0xc6, + 0x48, 0x02, 0x3e, 0xc7, 0x23, 0xab, 0x9c, 0x62, 0xfd, 0x80, 0x28, + 0x57, 0x39, 0xd8, 0x4f, 0x15, 0xd2, 0xab, 0x51, 0x5a})), + std::make_pair( + 169, + std::vector<uint8_t>( + {0x84, 0x88, 0x39, 0x6b, 0xd4, 0xa8, 0x72, 0x9b, 0x7a, 0x47, 0x31, + 0x78, 0xf2, 0x32, 0xda, 0xdf, 0x3f, 0x0f, 0x8e, 0x22, 0x67, 0x8b, + 0xa5, 0xa4, 0x3e, 0x04, 0x1e, 0x72, 0xda, 0x1e, 0x2c, 0xf8, 0x21, + 0x94, 0xc3, 0x07, 0x20, 0x7a, 0x54, 0xcb, 0x81, 0x56, 0x29, 0x33, + 0x39, 0xea, 0xec, 0x69, 0x3f, 0xf6, 0x6b, 0xfc, 0xd5, 0xef, 0xc6, + 0x5e, 0x95, 0xe4, 0xec, 0xaf, 0x54, 0x53, 0x0a, 0xbd})), + std::make_pair( + 170, + std::vector<uint8_t>( + {0xf5, 0x98, 0xda, 0x90, 0x1c, 0x38, 0x35, 0xbc, 0xa5, 0x60, 0x77, + 0x90, 0x37, 0xdf, 0xde, 0x9f, 0x0c, 0x51, 0xdc, 0x61, 0xc0, 0xb7, + 0x60, 0xfc, 0x15, 0x22, 0xd7, 0xb4, 0x70, 0xee, 0x63, 0xf5, 0xbd, + 0xc6, 0x49, 0x84, 0x76, 0xe8, 0x60, 0x49, 0xad, 0x86, 0xe4, 0xe2, + 0x1a, 0xf2, 0x85, 0x4a, 0x98, 0x4c, 0xc9, 0x05, 0x42, 0x7d, 0x2f, + 0x17, 0xf6, 0x6b, 0x1f, 0x41, 0xc3, 0xda, 0x6f, 0x61})), + std::make_pair( + 171, + std::vector<uint8_t>( + {0x5f, 0x93, 0x26, 0x97, 0x98, 0xcf, 0x02, 0x13, 0x21, 0x07, 0x33, + 0x76, 0x60, 0xa8, 0xd7, 0xa1, 0x77, 0x35, 0x4c, 0x02, 0x12, 0xeb, + 0x93, 0xe5, 0x55, 0xe7, 0xc3, 0x7a, 0x08, 0xae, 0xf3, 0xd8, 0xdc, + 0xe0, 0x12, 0x17, 0x01, 0x1c, 0xd9, 0x65, 0xc0, 0x4d, 0xd2, 0xc1, + 0x05, 0xf2, 0xe2, 0xb6, 0xca, 0xe5, 0xe4, 0xe6, 0xbc, 0xaf, 0x09, + 0xdf, 0xbe, 0xe3, 0xe0, 0xa6, 0xa6, 0x35, 0x7c, 0x37})), + std::make_pair( + 172, + std::vector<uint8_t>( + {0x0e, 0xcf, 0x58, 0x1d, 0x47, 0xba, 0xc9, 0x23, 0x09, 0x86, 0xfa, + 0xab, 0xd7, 0x0c, 0x2f, 0x5b, 0x80, 0xe9, 0x10, 0x66, 0xf0, 0xec, + 0x55, 0xa8, 0x42, 0x93, 0x78, 0x82, 0x28, 0x6d, 0x2c, 0xa0, 0x07, + 0xbb, 0x4e, 0x97, 0x3b, 0x0b, 0x09, 0x1d, 0x52, 0x16, 0x7f, 0xf7, + 0xc4, 0x00, 0x9c, 0x7a, 0xb4, 0xad, 0x38, 0xff, 0xf1, 0xdc, 0xea, + 0xcd, 0xb7, 0xbe, 0x81, 0xef, 0x4a, 0x45, 0x29, 0x52})), + std::make_pair( + 173, + std::vector<uint8_t>( + {0x5a, 0xec, 0xa8, 0xab, 0xe1, 0x52, 0x85, 0x82, 0xb2, 0xa3, 0x07, + 0xb4, 0x00, 0x95, 0x85, 0x49, 0x8a, 0x3d, 0x46, 0x7c, 0xa6, 0x10, + 0x1c, 0xb0, 0xc5, 0x12, 0x6f, 0x99, 0x76, 0x05, 0x6e, 0x9f, 0xfc, + 0x12, 0x3c, 0xc2, 0x0c, 0x30, 0x2b, 0x2a, 0x73, 0x7f, 0x49, 0x2c, + 0x75, 0xd2, 0x1f, 0x01, 0x51, 0x2c, 0x90, 0xca, 0x05, 0x41, 0xdf, + 0xa5, 0x6e, 0x95, 0x0a, 0x32, 0x1d, 0xcb, 0x28, 0xd8})), + std::make_pair( + 174, + std::vector<uint8_t>( + {0x73, 0x2f, 0xbf, 0x8f, 0x1c, 0xb2, 0xb8, 0x32, 0x92, 0x63, 0xed, + 0xe2, 0x78, 0x58, 0xfe, 0x46, 0xf8, 0xd3, 0x35, 0x4d, 0x37, 0x6b, + 0xcd, 0xa0, 0x54, 0x8e, 0x7c, 0xe1, 0xfa, 0x9d, 0xd1, 0x1f, 0x85, + 0xeb, 0x66, 0x1f, 0xe9, 0x50, 0xb5, 0x43, 0xaa, 0x63, 0x5c, 0xa4, + 0xd3, 0xf0, 0x4e, 0xde, 0x5b, 0x32, 0xd6, 0xb6, 0x56, 0xe5, 0xce, + 0x1c, 0x44, 0xd3, 0x5c, 0x4a, 0x6c, 0x56, 0xcf, 0xf8})), + std::make_pair( + 175, + std::vector<uint8_t>( + {0xd5, 0xe9, 0x38, 0x73, 0x5d, 0x63, 0x78, 0x8c, 0x80, 0x10, 0x0a, + 0xef, 0xd1, 0x86, 0x48, 0xd1, 0x8c, 0xf2, 0x72, 0xf6, 0x9f, 0x20, + 0xff, 0x24, 0xcf, 0xe2, 0x89, 0x5c, 0x08, 0x8a, 0xd0, 0x8b, 0x01, + 0x04, 0xda, 0x16, 0x72, 0xa4, 0xeb, 0x26, 0xfc, 0x52, 0x54, 0x5c, + 0xc7, 0xd7, 0xa0, 0x1b, 0x26, 0x6c, 0xf5, 0x46, 0xc4, 0x03, 0xc4, + 0x5b, 0xd1, 0x29, 0xeb, 0x41, 0xbd, 0xd9, 0x20, 0x0b})), + std::make_pair( + 176, + std::vector<uint8_t>( + {0x65, 0xa2, 0x45, 0xb4, 0x93, 0x52, 0xee, 0x29, 0x7d, 0x91, 0xaf, + 0x8c, 0x8b, 0xe0, 0x05, 0x28, 0xac, 0x6e, 0x04, 0x6d, 0xd8, 0x3a, + 0xc7, 0xbd, 0x46, 0x5a, 0x98, 0x81, 0x6d, 0xd6, 0x8f, 0x3e, 0x00, + 0xe1, 0xae, 0x8f, 0x89, 0x53, 0x27, 0xa7, 0xe9, 0xa8, 0xc9, 0x32, + 0x65, 0x98, 0x37, 0x9a, 0x29, 0xc9, 0xfc, 0x91, 0xec, 0x0c, 0x6e, + 0xef, 0x08, 0xf3, 0xe2, 0xb2, 0x16, 0xc1, 0x10, 0x08})), + std::make_pair( + 177, + std::vector<uint8_t>( + {0xc9, 0x56, 0x54, 0xb6, 0x30, 0x19, 0x13, 0x0a, 0xb4, 0x5d, 0xd0, + 0xfb, 0x49, 0x41, 0xb9, 0x8a, 0xeb, 0x3a, 0xf2, 0xa1, 0x23, 0x91, + 0x3e, 0xca, 0x2c, 0xe9, 0x9b, 0x3e, 0x97, 0x41, 0x0a, 0x7b, 0xf8, + 0x66, 0x1c, 0xc7, 0xfb, 0xaa, 0x2b, 0xc1, 0xcf, 0x2b, 0x13, 0x11, + 0x3b, 0x1e, 0xd4, 0x0a, 0x01, 0x18, 0xb8, 0x8e, 0x5f, 0xff, 0xc3, + 0x54, 0x27, 0x59, 0xea, 0x00, 0x7e, 0xd4, 0xc5, 0x8d})), + std::make_pair( + 178, + std::vector<uint8_t>( + {0x1e, 0xb2, 0x62, 0xf3, 0x8f, 0xa4, 0x94, 0x43, 0x1f, 0x01, 0x7d, + 0xad, 0x44, 0xc0, 0xdf, 0xb6, 0x93, 0x24, 0xac, 0x03, 0x2f, 0x04, + 0xb6, 0x57, 0xfc, 0x91, 0xa8, 0x86, 0x47, 0xbb, 0x74, 0x76, 0x0f, + 0x24, 0xe7, 0xc9, 0x56, 0x51, 0x4f, 0x0c, 0xf0, 0x02, 0x99, 0x0b, + 0x18, 0x2c, 0x16, 0x42, 0xb9, 0xb2, 0x42, 0x6e, 0x96, 0xa6, 0x11, + 0x87, 0xe4, 0xe0, 0x12, 0xf0, 0x0e, 0x21, 0x7d, 0x84})), + std::make_pair( + 179, + std::vector<uint8_t>( + {0x3b, 0x95, 0x5a, 0xee, 0xbf, 0xa5, 0x15, 0x1a, 0xc1, 0xab, 0x8e, + 0x3f, 0x5c, 0xc1, 0xe3, 0x76, 0x70, 0x84, 0xc8, 0x42, 0xa5, 0x75, + 0xd3, 0x62, 0x69, 0x83, 0x6e, 0x97, 0x35, 0x3d, 0x41, 0x62, 0x2b, + 0x73, 0x1d, 0xdd, 0xcd, 0x5f, 0x26, 0x95, 0x50, 0xa3, 0xa5, 0xb8, + 0x7b, 0xe1, 0xe9, 0x03, 0x26, 0x34, 0x0b, 0x6e, 0x0e, 0x62, 0x55, + 0x58, 0x15, 0xd9, 0x60, 0x05, 0x97, 0xac, 0x6e, 0xf9})), + std::make_pair( + 180, + std::vector<uint8_t>( + {0x68, 0x28, 0x9f, 0x66, 0x05, 0x47, 0x3b, 0xa0, 0xe4, 0xf2, 0x41, + 0xba, 0xf7, 0x47, 0x7a, 0x98, 0x85, 0x42, 0x6a, 0x85, 0x8f, 0x19, + 0xef, 0x2a, 0x18, 0xb0, 0xd4, 0x0e, 0xf8, 0xe4, 0x12, 0x82, 0xed, + 0x55, 0x26, 0xb5, 0x19, 0x79, 0x9e, 0x27, 0x0f, 0x13, 0x88, 0x13, + 0x27, 0x91, 0x82, 0x78, 0x75, 0x57, 0x11, 0x07, 0x1d, 0x85, 0x11, + 0xfe, 0x96, 0x3e, 0x3b, 0x56, 0x06, 0xaa, 0x37, 0x16})), + std::make_pair( + 181, + std::vector<uint8_t>( + {0x80, 0xa3, 0x37, 0x87, 0x54, 0x26, 0x12, 0xc3, 0x8f, 0x6b, 0xcd, + 0x7c, 0xd8, 0x6c, 0xab, 0x46, 0x02, 0x27, 0x50, 0x9b, 0x1c, 0xba, + 0xd5, 0xec, 0x40, 0x8a, 0x91, 0x41, 0x3d, 0x51, 0x15, 0x5a, 0x04, + 0x76, 0xda, 0xdb, 0xf3, 0xa2, 0x51, 0x8e, 0x4a, 0x6e, 0x77, 0xcc, + 0x34, 0x66, 0x22, 0xe3, 0x47, 0xa4, 0x69, 0xbf, 0x8b, 0xaa, 0x5f, + 0x04, 0xeb, 0x2d, 0x98, 0x70, 0x53, 0x55, 0xd0, 0x63})), + std::make_pair( + 182, + std::vector<uint8_t>( + {0x34, 0x62, 0x9b, 0xc6, 0xd8, 0x31, 0x39, 0x1c, 0x4c, 0xdf, 0x8a, + 0xf1, 0xb4, 0xb7, 0xb6, 0xb8, 0xe8, 0xee, 0x17, 0xcf, 0x98, 0xc7, + 0x0e, 0x5d, 0xd5, 0x86, 0xcd, 0x99, 0xf1, 0x4b, 0x11, 0xdf, 0x94, + 0x51, 0x66, 0x23, 0x6a, 0x95, 0x71, 0xe6, 0xd5, 0x91, 0xbb, 0x83, + 0xee, 0x4d, 0x16, 0x4d, 0x46, 0xf6, 0xb9, 0xd8, 0xef, 0x86, 0xff, + 0x86, 0x5a, 0x81, 0xbf, 0xb9, 0x1b, 0x00, 0x42, 0x4b})), + std::make_pair( + 183, + std::vector<uint8_t>( + {0x8b, 0x7c, 0xc3, 0x39, 0x16, 0x38, 0x63, 0xbb, 0x43, 0x83, 0xe5, + 0x42, 0xb0, 0xef, 0x0e, 0x7c, 0xf3, 0x6b, 0x84, 0xad, 0x93, 0x2c, + 0xdf, 0x5a, 0x80, 0x41, 0x9e, 0xc9, 0xad, 0x69, 0x2e, 0x7a, 0x7e, + 0x78, 0x4d, 0x2c, 0x7c, 0xb3, 0x79, 0x6a, 0x18, 0xb8, 0xf8, 0x00, + 0x03, 0x5f, 0x3a, 0xa0, 0x6c, 0x82, 0x41, 0x00, 0x61, 0x11, 0x20, + 0xa7, 0xbd, 0xeb, 0x35, 0x61, 0x8c, 0xcb, 0x81, 0xb7})), + std::make_pair( + 184, + std::vector<uint8_t>( + {0x4f, 0x08, 0x4e, 0x49, 0x39, 0xdd, 0x5a, 0x7f, 0x5a, 0x65, 0x8f, + 0xad, 0x58, 0xa1, 0x8a, 0x15, 0xc2, 0x5c, 0x32, 0xec, 0x1c, 0x7f, + 0xd5, 0xc5, 0xc6, 0xc3, 0xe8, 0x92, 0xb3, 0x97, 0x1a, 0xea, 0xac, + 0x30, 0x83, 0x04, 0xef, 0x17, 0xb1, 0xc4, 0x72, 0x39, 0xea, 0x4b, + 0xb3, 0x98, 0xb3, 0xfd, 0x6d, 0x45, 0x28, 0xd8, 0xde, 0x8e, 0x76, + 0x8a, 0xe0, 0xf1, 0xa5, 0xa5, 0xc6, 0xb5, 0xc2, 0x97})), + std::make_pair( + 185, + std::vector<uint8_t>( + {0x48, 0xf4, 0x07, 0xa1, 0xaf, 0x5b, 0x80, 0x09, 0xb2, 0x05, 0x17, + 0x42, 0xe8, 0xcf, 0x5c, 0xd5, 0x65, 0x66, 0x69, 0xe7, 0xd7, 0x22, + 0xee, 0x8e, 0x7b, 0xd2, 0x02, 0x06, 0x08, 0x49, 0x44, 0x21, 0x68, + 0xd8, 0xfa, 0xcc, 0x11, 0x7c, 0x01, 0x2b, 0xfb, 0x7b, 0xf4, 0x49, + 0xd9, 0x9b, 0xef, 0xff, 0x6a, 0x34, 0xae, 0xa2, 0x03, 0xf1, 0xd8, + 0xd3, 0x52, 0x72, 0x2b, 0xe5, 0x01, 0x4e, 0xc8, 0x18})), + std::make_pair( + 186, + std::vector<uint8_t>( + {0xa6, 0xaa, 0x82, 0xcd, 0x1e, 0x42, 0x6f, 0x9a, 0x73, 0xbf, 0xa3, + 0x9a, 0x29, 0x03, 0x78, 0x76, 0x11, 0x46, 0x55, 0xb8, 0xc2, 0x2d, + 0x6d, 0x3f, 0xf8, 0xb6, 0x38, 0xae, 0x7d, 0xea, 0x6b, 0x17, 0x84, + 0x3e, 0x09, 0xe5, 0x2e, 0xb6, 0x6f, 0xa1, 0xe4, 0x75, 0xe4, 0xa8, + 0xa3, 0xde, 0x42, 0x9b, 0x7d, 0x0f, 0x4a, 0x77, 0x6f, 0xcb, 0x8b, + 0xdc, 0x9b, 0x9f, 0xed, 0xe7, 0xd5, 0x2e, 0x81, 0x5f})), + std::make_pair( + 187, + std::vector<uint8_t>( + {0x58, 0x17, 0x02, 0x7d, 0x6b, 0xdd, 0x00, 0xc5, 0xdd, 0x10, 0xac, + 0x59, 0x3c, 0xd5, 0x60, 0x37, 0x22, 0x70, 0x77, 0x5a, 0x18, 0x52, + 0x6d, 0x7e, 0x6f, 0x13, 0x87, 0x2a, 0x2e, 0x20, 0xea, 0xb6, 0x64, + 0x62, 0x5b, 0xe7, 0x16, 0x8a, 0xc4, 0xbd, 0x7c, 0x9e, 0x0c, 0xe7, + 0xfc, 0x40, 0x99, 0xe0, 0xf4, 0x84, 0x42, 0xe2, 0xc7, 0x67, 0x19, + 0x1c, 0x6e, 0x12, 0x84, 0xe9, 0xb2, 0xcc, 0xea, 0x8c})), + std::make_pair( + 188, + std::vector<uint8_t>( + {0x08, 0xe4, 0x10, 0x28, 0x34, 0x0a, 0x45, 0xc7, 0x4e, 0x40, 0x52, + 0xb3, 0xa8, 0xd6, 0x38, 0x9e, 0x22, 0xe0, 0x43, 0xa1, 0xad, 0xab, + 0x5e, 0x28, 0xd9, 0x76, 0x19, 0x45, 0x0d, 0x72, 0x34, 0x69, 0xb6, + 0x20, 0xca, 0xa5, 0x19, 0xb8, 0x1c, 0x14, 0x52, 0x38, 0x54, 0xf6, + 0x19, 0xfd, 0x30, 0x27, 0xe3, 0x84, 0x7b, 0xd0, 0x32, 0x76, 0xe6, + 0x06, 0x04, 0xa8, 0x0d, 0xdb, 0x4d, 0xe8, 0x76, 0xd6})), + std::make_pair( + 189, + std::vector<uint8_t>( + {0x13, 0x0b, 0x84, 0x20, 0x53, 0x7e, 0xb0, 0x7d, 0x72, 0xab, 0xda, + 0x07, 0xc8, 0x5a, 0xcb, 0xd8, 0xb9, 0xa4, 0x4f, 0x16, 0x32, 0x1d, + 0xd0, 0x42, 0x21, 0x45, 0xf8, 0x09, 0x67, 0x3d, 0x30, 0xf2, 0xb5, + 0x32, 0x13, 0x26, 0xe2, 0xbf, 0xf3, 0x17, 0xef, 0x3f, 0xef, 0x98, + 0x3c, 0x51, 0xc4, 0xf8, 0xab, 0x24, 0xa3, 0x25, 0xd2, 0x98, 0xe3, + 0x4a, 0xfc, 0xe5, 0x69, 0xa8, 0x25, 0x55, 0x77, 0x4c})), + std::make_pair( + 190, + std::vector<uint8_t>( + {0xac, 0x49, 0xb8, 0x44, 0xaf, 0xaa, 0x01, 0x2e, 0x31, 0xc4, 0x74, + 0xca, 0x26, 0x36, 0x48, 0x84, 0x4f, 0xd2, 0xf6, 0x30, 0x79, 0x92, + 0xc2, 0xf7, 0x52, 0xac, 0xa0, 0x2c, 0x38, 0x28, 0x96, 0x51, 0x75, + 0x79, 0x4d, 0xee, 0xe2, 0xd2, 0xee, 0x95, 0xc6, 0x1c, 0xd2, 0x84, + 0xf6, 0xb5, 0xa2, 0xd7, 0x5e, 0x2e, 0xf2, 0xb2, 0x9e, 0xe8, 0x14, + 0x9e, 0x77, 0xfb, 0x81, 0x44, 0x7b, 0x2f, 0xd0, 0x4b})), + std::make_pair( + 191, + std::vector<uint8_t>( + {0xb9, 0xd7, 0xca, 0x81, 0xcc, 0x60, 0xbb, 0x95, 0x78, 0xe4, 0x40, + 0x24, 0xe5, 0xa0, 0xa0, 0xbe, 0x80, 0xf2, 0x73, 0x36, 0xa6, 0xa9, + 0xf4, 0xe5, 0x3d, 0xf3, 0x99, 0x9c, 0xb1, 0x91, 0x28, 0x0b, 0x09, + 0x0e, 0x2a, 0xc2, 0xd2, 0x9c, 0x5b, 0xaa, 0xd9, 0xd7, 0x14, 0x15, + 0xbd, 0xc1, 0x29, 0xe6, 0x9a, 0xa2, 0x66, 0x7a, 0xf6, 0xa7, 0xfd, + 0x5e, 0x18, 0x9f, 0xcc, 0xdc, 0xee, 0x81, 0x73, 0x40})), + std::make_pair( + 192, + std::vector<uint8_t>( + {0xa7, 0x55, 0xe1, 0x13, 0x38, 0x65, 0x72, 0xc7, 0x5c, 0xed, 0x61, + 0xd7, 0x19, 0x70, 0x60, 0x70, 0xb9, 0x14, 0x60, 0x48, 0xe4, 0x2a, + 0x9f, 0x8c, 0xd3, 0x56, 0x67, 0xa0, 0x88, 0xb4, 0x2f, 0x08, 0x80, + 0x8a, 0xbd, 0xf7, 0x7e, 0x61, 0x8a, 0xbd, 0x95, 0x9a, 0xfc, 0x75, + 0x73, 0x79, 0xca, 0x2c, 0x00, 0xbc, 0xc1, 0xa4, 0x83, 0x90, 0xfa, + 0x2b, 0xff, 0x61, 0x8b, 0x1e, 0x00, 0x78, 0xa6, 0x13})), + std::make_pair( + 193, + std::vector<uint8_t>( + {0xa7, 0x3c, 0x7d, 0xeb, 0xed, 0x32, 0x6f, 0x1c, 0x0d, 0xb0, 0x79, + 0x5e, 0xe7, 0xd6, 0xe3, 0x94, 0x68, 0x94, 0xb8, 0x26, 0xb1, 0xf8, + 0x10, 0x1c, 0x56, 0xc8, 0x23, 0xba, 0x17, 0x16, 0x83, 0x12, 0xe7, + 0xf5, 0x3f, 0xc7, 0xdb, 0xe5, 0x2c, 0x3e, 0x11, 0xe6, 0x98, 0x52, + 0xc4, 0x04, 0x85, 0xe2, 0xef, 0x18, 0x24, 0x77, 0x86, 0x2e, 0xa6, + 0xa3, 0x4e, 0xc1, 0x36, 0xe2, 0xdf, 0xee, 0xa6, 0xf4})), + std::make_pair( + 194, + std::vector<uint8_t>( + {0x6c, 0xb8, 0xf9, 0xd5, 0x2c, 0x56, 0xd8, 0x2c, 0xac, 0x28, 0xf3, + 0x9e, 0xa1, 0x59, 0x3e, 0x8b, 0xb2, 0x50, 0x62, 0x93, 0xac, 0x0d, + 0x68, 0x37, 0x6a, 0x17, 0x09, 0xb6, 0x2a, 0x46, 0xdf, 0x14, 0xa4, + 0xae, 0x64, 0xb2, 0xd8, 0xfa, 0xb7, 0x67, 0x33, 0xa1, 0xce, 0xd2, + 0xd5, 0x48, 0xe3, 0xf3, 0xc6, 0xfc, 0xb4, 0x9d, 0x40, 0xc3, 0xd5, + 0x80, 0x8e, 0x44, 0x9c, 0xd8, 0x3d, 0x1c, 0x2a, 0xa2})), + std::make_pair( + 195, + std::vector<uint8_t>( + {0x68, 0x3f, 0xa2, 0xb2, 0x36, 0x9a, 0x10, 0x16, 0x2c, 0x1c, 0x1c, + 0x7b, 0x24, 0xbc, 0x97, 0x0e, 0xe6, 0x7d, 0xa2, 0x20, 0x56, 0x4f, + 0x32, 0x20, 0x3f, 0x62, 0x56, 0x96, 0xc0, 0x35, 0x2a, 0x0b, 0x9a, + 0xd9, 0x66, 0x24, 0x36, 0x2d, 0x95, 0x2d, 0x84, 0x46, 0x3c, 0x11, + 0x06, 0xa2, 0xdb, 0xa7, 0xa0, 0x92, 0x59, 0x98, 0x84, 0xb3, 0x5a, + 0x0b, 0x89, 0xc8, 0xf1, 0xb6, 0xa9, 0xb5, 0xa6, 0x1e})), + std::make_pair( + 196, + std::vector<uint8_t>( + {0xaa, 0xd9, 0xad, 0x44, 0x61, 0x01, 0x18, 0xb7, 0x7d, 0x50, 0x8a, + 0xeb, 0x1b, 0xbc, 0xd1, 0xc1, 0xb7, 0xd0, 0x17, 0x13, 0x97, 0xfb, + 0x51, 0x0a, 0x40, 0x1b, 0xbc, 0x0e, 0xc3, 0x46, 0x23, 0x67, 0x0d, + 0x86, 0xa2, 0xdc, 0x3c, 0x8f, 0x3a, 0xb5, 0xa2, 0x04, 0x4d, 0xf7, + 0x30, 0x25, 0x67, 0x27, 0x54, 0x5f, 0x08, 0x60, 0xce, 0x21, 0xa1, + 0xea, 0xc7, 0x17, 0xdf, 0xc4, 0x8f, 0x5d, 0x22, 0x8e})), + std::make_pair( + 197, + std::vector<uint8_t>( + {0xc4, 0x25, 0x78, 0xde, 0x23, 0xb4, 0xc9, 0x87, 0xd5, 0xe1, 0xac, + 0x4d, 0x68, 0x9e, 0xd5, 0xde, 0x4b, 0x04, 0x17, 0xf9, 0x70, 0x4b, + 0xc6, 0xbc, 0xe9, 0x69, 0xfa, 0x13, 0x47, 0x15, 0x85, 0xd6, 0x2c, + 0x2c, 0xb1, 0x21, 0x2a, 0x94, 0x4f, 0x39, 0x7f, 0xc9, 0xca, 0x2c, + 0x37, 0x47, 0xc3, 0xbe, 0xb6, 0x94, 0xec, 0x4c, 0x5b, 0xe6, 0x88, + 0x28, 0xdd, 0xa5, 0x3e, 0xf4, 0x3f, 0xae, 0xc6, 0xc0})), + std::make_pair( + 198, + std::vector<uint8_t>( + {0x47, 0x0f, 0x00, 0x84, 0x1e, 0xe8, 0x24, 0x4e, 0x63, 0xed, 0x2c, + 0x7e, 0xa3, 0x0e, 0x2e, 0x41, 0x98, 0x97, 0xc1, 0x97, 0x46, 0x2e, + 0xcc, 0xce, 0xcf, 0x71, 0x3b, 0x42, 0xa5, 0x06, 0x5f, 0xff, 0x59, + 0x14, 0xbc, 0x9b, 0x79, 0xaf, 0xfe, 0x8f, 0x6b, 0x65, 0x78, 0x75, + 0xe7, 0x89, 0xae, 0x21, 0x3b, 0xd9, 0x14, 0xcd, 0x35, 0xbd, 0x17, + 0x4d, 0x46, 0xe9, 0xd1, 0x8b, 0xd8, 0x43, 0x77, 0x3d})), + std::make_pair( + 199, + std::vector<uint8_t>( + {0x34, 0xfc, 0x42, 0x13, 0x73, 0x0f, 0x47, 0xa5, 0xe9, 0xa3, 0x58, + 0x0f, 0x64, 0x3e, 0x12, 0x94, 0x5c, 0xfc, 0xb3, 0x1b, 0xf2, 0x06, + 0xf6, 0xad, 0x45, 0x0c, 0xe5, 0x28, 0xda, 0x3f, 0xa4, 0x32, 0xe0, + 0x05, 0xd6, 0xb0, 0xec, 0xce, 0x10, 0xdc, 0xa7, 0xc5, 0x99, 0x5f, + 0x6a, 0xac, 0xc5, 0x15, 0x0e, 0x1b, 0x00, 0x9e, 0x19, 0x75, 0x1e, + 0x83, 0x09, 0xf8, 0x85, 0x95, 0x31, 0x84, 0x43, 0x74})), + std::make_pair( + 200, + std::vector<uint8_t>( + {0xfb, 0x3c, 0x1f, 0x0f, 0x56, 0xa5, 0x6f, 0x8e, 0x31, 0x6f, 0xdf, + 0x5d, 0x85, 0x3c, 0x8c, 0x87, 0x2c, 0x39, 0x63, 0x5d, 0x08, 0x36, + 0x34, 0xc3, 0x90, 0x4f, 0xc3, 0xac, 0x07, 0xd1, 0xb5, 0x78, 0xe8, + 0x5f, 0xf0, 0xe4, 0x80, 0xe9, 0x2d, 0x44, 0xad, 0xe3, 0x3b, 0x62, + 0xe8, 0x93, 0xee, 0x32, 0x34, 0x3e, 0x79, 0xdd, 0xf6, 0xef, 0x29, + 0x2e, 0x89, 0xb5, 0x82, 0xd3, 0x12, 0x50, 0x23, 0x14})), + std::make_pair( + 201, + std::vector<uint8_t>( + {0xc7, 0xc9, 0x7f, 0xc6, 0x5d, 0xd2, 0xb9, 0xe3, 0xd3, 0xd6, 0x07, + 0xd3, 0x15, 0x98, 0xd3, 0xf8, 0x42, 0x61, 0xe9, 0x91, 0x92, 0x51, + 0xe9, 0xc8, 0xe5, 0x7b, 0xb5, 0xf8, 0x29, 0x37, 0x7d, 0x5f, 0x73, + 0xea, 0xbb, 0xed, 0x55, 0xc6, 0xc3, 0x81, 0x18, 0x0f, 0x29, 0xad, + 0x02, 0xe5, 0xbe, 0x79, 0x7f, 0xfe, 0xc7, 0xe5, 0x7b, 0xde, 0xcb, + 0xc5, 0x0a, 0xd3, 0xd0, 0x62, 0xf0, 0x99, 0x3a, 0xb0})), + std::make_pair( + 202, + std::vector<uint8_t>( + {0xa5, 0x7a, 0x49, 0xcd, 0xbe, 0x67, 0xae, 0x7d, 0x9f, 0x79, 0x7b, + 0xb5, 0xcc, 0x7e, 0xfc, 0x2d, 0xf0, 0x7f, 0x4e, 0x1b, 0x15, 0x95, + 0x5f, 0x85, 0xda, 0xe7, 0x4b, 0x76, 0xe2, 0xec, 0xb8, 0x5a, 0xfb, + 0x6c, 0xd9, 0xee, 0xed, 0x88, 0x88, 0xd5, 0xca, 0x3e, 0xc5, 0xab, + 0x65, 0xd2, 0x7a, 0x7b, 0x19, 0xe5, 0x78, 0x47, 0x57, 0x60, 0xa0, + 0x45, 0xac, 0x3c, 0x92, 0xe1, 0x3a, 0x93, 0x8e, 0x77})), + std::make_pair( + 203, + std::vector<uint8_t>( + {0xc7, 0x14, 0x3f, 0xce, 0x96, 0x14, 0xa1, 0x7f, 0xd6, 0x53, 0xae, + 0xb1, 0x40, 0x72, 0x6d, 0xc9, 0xc3, 0xdb, 0xb1, 0xde, 0x6c, 0xc5, + 0x81, 0xb2, 0x72, 0x68, 0x97, 0xec, 0x24, 0xb7, 0xa5, 0x03, 0x59, + 0xad, 0x49, 0x22, 0x43, 0xbe, 0x66, 0xd9, 0xed, 0xd8, 0xc9, 0x33, + 0xb5, 0xb8, 0x0e, 0x0b, 0x91, 0xbb, 0x61, 0xea, 0x98, 0x05, 0x60, + 0x06, 0x51, 0x69, 0x76, 0xfa, 0xe8, 0xd9, 0x9a, 0x35})), + std::make_pair( + 204, + std::vector<uint8_t>( + {0x65, 0xbb, 0x58, 0xd0, 0x7f, 0x93, 0x7e, 0x2d, 0x3c, 0x7e, 0x65, + 0x38, 0x5f, 0x9c, 0x54, 0x73, 0x0b, 0x70, 0x41, 0x05, 0xcc, 0xdb, + 0x69, 0x1f, 0x6e, 0x14, 0x6d, 0x4e, 0xe8, 0xf6, 0xc0, 0x86, 0xf4, + 0x95, 0x11, 0x03, 0x51, 0x10, 0xa9, 0xad, 0x60, 0x31, 0xfd, 0xce, + 0xb9, 0x43, 0xe0, 0xf9, 0x61, 0x3b, 0xcb, 0x27, 0x6d, 0xd4, 0x0f, + 0x06, 0x24, 0xef, 0x0f, 0x92, 0x4f, 0x80, 0x97, 0x83})), + std::make_pair( + 205, + std::vector<uint8_t>( + {0xe5, 0x40, 0x27, 0x7f, 0x68, 0x3b, 0x11, 0x86, 0xdd, 0x3b, 0x5b, + 0x3f, 0x61, 0x43, 0x33, 0x96, 0x58, 0x1a, 0x35, 0xfe, 0xb1, 0x20, + 0x02, 0xbe, 0x8c, 0x6a, 0x62, 0x31, 0xfc, 0x40, 0xff, 0xa7, 0x0f, + 0x08, 0x08, 0x1b, 0xc5, 0x8b, 0x2d, 0x94, 0xf7, 0x64, 0x95, 0x43, + 0x61, 0x4a, 0x43, 0x5f, 0xaa, 0x2d, 0x62, 0x11, 0x0e, 0x13, 0xda, + 0xbc, 0x7b, 0x86, 0x62, 0x9b, 0x63, 0xaf, 0x9c, 0x24})), + std::make_pair( + 206, + std::vector<uint8_t>( + {0x41, 0x85, 0x00, 0x87, 0x8c, 0x5f, 0xbc, 0xb5, 0x84, 0xc4, 0x32, + 0xf4, 0x28, 0x5e, 0x05, 0xe4, 0x9f, 0x2e, 0x3e, 0x07, 0x53, 0x99, + 0xa0, 0xdb, 0xfc, 0xf8, 0x74, 0xeb, 0xf8, 0xc0, 0x3d, 0x02, 0xbf, + 0x16, 0xbc, 0x69, 0x89, 0xd1, 0x61, 0xc7, 0x7c, 0xa0, 0x78, 0x6b, + 0x05, 0x05, 0x3c, 0x6c, 0x70, 0x94, 0x33, 0x71, 0x23, 0x19, 0x19, + 0x21, 0x28, 0x83, 0x5c, 0xf0, 0xb6, 0x60, 0x59, 0x5b})), + std::make_pair( + 207, + std::vector<uint8_t>( + {0x88, 0x90, 0x90, 0xdb, 0xb1, 0x94, 0x4b, 0xdc, 0x94, 0x33, 0xee, + 0x5e, 0xf1, 0x01, 0x0c, 0x7a, 0x4a, 0x24, 0xa8, 0xe7, 0x1e, 0xce, + 0xa8, 0xe1, 0x2a, 0x31, 0x31, 0x8c, 0xe4, 0x9d, 0xca, 0xb0, 0xac, + 0xa5, 0xc3, 0x80, 0x23, 0x34, 0xaa, 0xb2, 0xcc, 0x84, 0xb1, 0x4c, + 0x6b, 0x93, 0x21, 0xfe, 0x58, 0x6b, 0xf3, 0xf8, 0x76, 0xf1, 0x9c, + 0xd4, 0x06, 0xeb, 0x11, 0x27, 0xfb, 0x94, 0x48, 0x01})), + std::make_pair( + 208, + std::vector<uint8_t>( + {0x53, 0xb6, 0xa2, 0x89, 0x10, 0xaa, 0x92, 0xe2, 0x7e, 0x53, 0x6f, + 0xb5, 0x49, 0xcf, 0x9b, 0x99, 0x18, 0x79, 0x10, 0x60, 0x89, 0x8e, + 0x0b, 0x9f, 0xe1, 0x83, 0x57, 0x7f, 0xf4, 0x3b, 0x5e, 0x9c, 0x76, + 0x89, 0xc7, 0x45, 0xb3, 0x2e, 0x41, 0x22, 0x69, 0x83, 0x7c, 0x31, + 0xb8, 0x9e, 0x6c, 0xc1, 0x2b, 0xf7, 0x6e, 0x13, 0xca, 0xd3, 0x66, + 0xb7, 0x4e, 0xce, 0x48, 0xbb, 0x85, 0xfd, 0x09, 0xe9})), + std::make_pair( + 209, + std::vector<uint8_t>( + {0x7c, 0x09, 0x20, 0x80, 0xc6, 0xa8, 0x0d, 0x67, 0x24, 0x09, 0xd0, + 0x81, 0xd3, 0xd1, 0x77, 0x10, 0x6b, 0xcd, 0x63, 0x56, 0x77, 0x85, + 0x14, 0x07, 0x19, 0x49, 0x09, 0x50, 0xae, 0x07, 0xae, 0x8f, 0xca, + 0xab, 0xba, 0xaa, 0xb3, 0x30, 0xcf, 0xbc, 0xf7, 0x37, 0x44, 0x82, + 0xc2, 0x20, 0xaf, 0x2e, 0xad, 0xee, 0xb7, 0x3d, 0xcb, 0xb3, 0x5e, + 0xd8, 0x23, 0x34, 0x4e, 0x14, 0x4e, 0x7d, 0x48, 0x99})), + std::make_pair( + 210, + std::vector<uint8_t>( + {0x9c, 0xcd, 0xe5, 0x66, 0xd2, 0x40, 0x05, 0x09, 0x18, 0x11, 0x11, + 0xf3, 0x2d, 0xde, 0x4c, 0xd6, 0x32, 0x09, 0xfe, 0x59, 0xa3, 0x0c, + 0x11, 0x45, 0x46, 0xad, 0x27, 0x76, 0xd8, 0x89, 0xa4, 0x1b, 0xad, + 0x8f, 0xa1, 0xbb, 0x46, 0x8c, 0xb2, 0xf9, 0xd4, 0x2c, 0xa9, 0x92, + 0x8a, 0x77, 0x70, 0xfe, 0xf8, 0xe8, 0xba, 0x4d, 0x0c, 0x81, 0x2d, + 0x9a, 0x1e, 0x75, 0xc3, 0xd8, 0xd2, 0xcc, 0xd7, 0x5a})), + std::make_pair( + 211, + std::vector<uint8_t>( + {0x6e, 0x29, 0x3b, 0xf5, 0xd0, 0x3f, 0xe4, 0x39, 0x77, 0xcf, 0xe3, + 0xf5, 0x7c, 0xcd, 0xb3, 0xae, 0x28, 0x2a, 0x85, 0x45, 0x5d, 0xca, + 0x33, 0xf3, 0x7f, 0x4b, 0x74, 0xf8, 0x39, 0x8c, 0xc6, 0x12, 0x43, + 0x3d, 0x75, 0x5c, 0xbe, 0xc4, 0x12, 0xf8, 0xf8, 0x2a, 0x3b, 0xd3, + 0xbc, 0x4a, 0x27, 0x8f, 0x7e, 0xcd, 0x0d, 0xfa, 0x9b, 0xbd, 0xc4, + 0x0b, 0xe7, 0xa7, 0x87, 0xc8, 0xf1, 0x59, 0xb2, 0xdf})), + std::make_pair( + 212, + std::vector<uint8_t>( + {0xc5, 0x65, 0x46, 0xfb, 0x21, 0x78, 0x45, 0x6f, 0x33, 0x61, 0x64, + 0xc1, 0x8b, 0x90, 0xde, 0xff, 0xc8, 0x3a, 0xe2, 0xb5, 0xa3, 0xac, + 0xa7, 0x7b, 0x68, 0x84, 0xd3, 0x6d, 0x2c, 0x1d, 0xb3, 0x95, 0x01, + 0xb3, 0xe6, 0x5e, 0x36, 0xc7, 0x58, 0xc6, 0x6e, 0x31, 0x88, 0x45, + 0x1f, 0xdb, 0x35, 0x15, 0xee, 0x16, 0x2c, 0x00, 0x1f, 0x06, 0xc3, + 0xe8, 0xcb, 0x57, 0x3a, 0xdf, 0x30, 0xf7, 0xa1, 0x01})), + std::make_pair( + 213, + std::vector<uint8_t>( + {0x6f, 0x82, 0xf8, 0x9f, 0x29, 0x9e, 0xbc, 0xa2, 0xfe, 0x01, 0x4b, + 0x59, 0xbf, 0xfe, 0x1a, 0xa8, 0x4e, 0x88, 0xb1, 0x91, 0x5f, 0xe2, + 0x56, 0xaf, 0xb6, 0x46, 0xfd, 0x84, 0x48, 0xaf, 0x2b, 0x88, 0x91, + 0xa7, 0xfa, 0xb3, 0x7a, 0x4e, 0xa6, 0xf9, 0xa5, 0x0e, 0x6c, 0x31, + 0x70, 0x39, 0xd8, 0xcf, 0x87, 0x8f, 0x4c, 0x8e, 0x1a, 0x0d, 0xd4, + 0x64, 0xf0, 0xb4, 0xd6, 0xff, 0x1c, 0x7e, 0xa8, 0x53})), + std::make_pair( + 214, + std::vector<uint8_t>( + {0x2b, 0x85, 0x99, 0xff, 0x9c, 0x3d, 0x61, 0x98, 0x63, 0x7a, 0xd5, + 0x1e, 0x57, 0xd1, 0x99, 0x8b, 0x0d, 0x75, 0x31, 0x3f, 0xe2, 0xdd, + 0x61, 0xa5, 0x33, 0xc9, 0x64, 0xa6, 0xdd, 0x96, 0x07, 0xc6, 0xf7, + 0x23, 0xe9, 0x45, 0x2c, 0xe4, 0x6e, 0x01, 0x4b, 0x1c, 0x1d, 0x6d, + 0xe7, 0x7b, 0xa5, 0xb8, 0x8c, 0x91, 0x4d, 0x1c, 0x59, 0x7b, 0xf1, + 0xea, 0xe1, 0x34, 0x74, 0xb4, 0x29, 0x0e, 0x89, 0xb2})), + std::make_pair( + 215, + std::vector<uint8_t>( + {0x08, 0xbf, 0x34, 0x6d, 0x38, 0xe1, 0xdf, 0x06, 0xc8, 0x26, 0x0e, + 0xdb, 0x1d, 0xa7, 0x55, 0x79, 0x27, 0x59, 0x48, 0xd5, 0xc0, 0xa0, + 0xaa, 0x9e, 0xd2, 0x88, 0x6f, 0x88, 0x56, 0xde, 0x54, 0x17, 0xa1, + 0x56, 0x99, 0x87, 0x58, 0xf5, 0xb1, 0x7e, 0x52, 0xf1, 0x01, 0xca, + 0x95, 0x7a, 0x71, 0x13, 0x74, 0x73, 0xdf, 0xd1, 0x8d, 0x7d, 0x20, + 0x9c, 0x4c, 0x10, 0xd9, 0x23, 0x3c, 0x93, 0x69, 0x1d})), + std::make_pair( + 216, + std::vector<uint8_t>( + {0x6d, 0xf2, 0x15, 0x6d, 0x77, 0x31, 0x14, 0xd3, 0x10, 0xb6, 0x3d, + 0xb9, 0xee, 0x53, 0x50, 0xd7, 0x7e, 0x6b, 0xcf, 0x25, 0xb0, 0x5f, + 0xcd, 0x91, 0x0f, 0x9b, 0x31, 0xbc, 0x42, 0xbb, 0x13, 0xfe, 0x82, + 0x25, 0xeb, 0xcb, 0x2a, 0x23, 0xa6, 0x22, 0x80, 0x77, 0x7b, 0x6b, + 0xf7, 0x4e, 0x2c, 0xd0, 0x91, 0x7c, 0x76, 0x40, 0xb4, 0x3d, 0xef, + 0xe4, 0x68, 0xcd, 0x1e, 0x18, 0xc9, 0x43, 0xc6, 0x6a})), + std::make_pair( + 217, + std::vector<uint8_t>( + {0x7c, 0x70, 0x38, 0xbc, 0x13, 0xa9, 0x11, 0x51, 0x82, 0x8a, 0x5b, + 0xa8, 0x2b, 0x4a, 0x96, 0x04, 0x0f, 0x25, 0x8a, 0x4d, 0xfb, 0x1b, + 0x13, 0x73, 0xf0, 0xd3, 0x59, 0x16, 0x8a, 0xfb, 0x05, 0x17, 0xa2, + 0x0b, 0x28, 0xa1, 0x2d, 0x36, 0x44, 0x04, 0x6b, 0xe6, 0x6b, 0x8d, + 0x08, 0xd8, 0xae, 0x7f, 0x6a, 0x92, 0x3e, 0xa1, 0xc0, 0x01, 0x87, + 0xc6, 0xd1, 0x1d, 0xc5, 0x02, 0xba, 0xc7, 0x13, 0x05})), + std::make_pair( + 218, + std::vector<uint8_t>( + {0xbc, 0xd1, 0xb3, 0x0d, 0x80, 0x8f, 0xb7, 0x39, 0xb9, 0x87, 0xcb, + 0xf1, 0x54, 0xbe, 0xa0, 0x0d, 0xa9, 0xd4, 0x03, 0x80, 0xb8, 0x61, + 0xd4, 0xc1, 0xd6, 0x37, 0x71, 0x22, 0xda, 0xdd, 0x61, 0xc0, 0xe5, + 0x90, 0x18, 0xb7, 0x19, 0x41, 0xcf, 0xb6, 0x2e, 0x00, 0xdc, 0xd7, + 0x0a, 0xeb, 0x9a, 0xbf, 0x04, 0x73, 0xe8, 0x0f, 0x0a, 0x7e, 0xca, + 0x6b, 0x6d, 0xea, 0x24, 0x6a, 0xb2, 0x29, 0xdd, 0x2b})), + std::make_pair( + 219, + std::vector<uint8_t>( + {0x7e, 0xd4, 0x46, 0x8d, 0x96, 0x85, 0x30, 0xfe, 0x7a, 0xb2, 0xc3, + 0x35, 0x40, 0xb2, 0x6d, 0x8c, 0x3b, 0xd3, 0xed, 0x44, 0xb3, 0x4f, + 0xbe, 0x8c, 0x2a, 0x9d, 0x7f, 0x80, 0x5b, 0x5a, 0xda, 0x0e, 0xa2, + 0x52, 0xee, 0xad, 0xe4, 0xfc, 0xe9, 0x7f, 0x89, 0x72, 0x8a, 0xd8, + 0x5b, 0xc8, 0xbb, 0x24, 0x30, 0xb1, 0xbe, 0xf2, 0xcd, 0xdd, 0x32, + 0xc8, 0x44, 0x6e, 0x59, 0xb8, 0xe8, 0xba, 0x3c, 0x67})), + std::make_pair( + 220, + std::vector<uint8_t>( + {0x6d, 0x30, 0xb7, 0xc6, 0xce, 0x8a, 0x32, 0x36, 0xc0, 0xca, 0x2f, + 0x8d, 0x72, 0x8b, 0x10, 0x88, 0xca, 0x06, 0x98, 0x3a, 0x80, 0x43, + 0xe6, 0x21, 0xd5, 0xdc, 0xf0, 0xc5, 0x37, 0xd1, 0x3b, 0x08, 0x79, + 0x1e, 0xde, 0xb0, 0x1a, 0x3c, 0xf0, 0x94, 0x3e, 0xc1, 0xc8, 0x90, + 0xab, 0x6e, 0x29, 0xb1, 0x46, 0xa2, 0x36, 0xcd, 0x46, 0xbc, 0xb9, + 0xd9, 0x3b, 0xf5, 0x16, 0xfb, 0x67, 0xc6, 0x3f, 0xe5})), + std::make_pair( + 221, + std::vector<uint8_t>( + {0x97, 0xfe, 0x03, 0xce, 0xf3, 0x14, 0x38, 0x50, 0x89, 0x11, 0xbd, + 0xed, 0x97, 0x59, 0x80, 0xa6, 0x60, 0x29, 0x30, 0x5d, 0xc5, 0xe3, + 0xfa, 0x8a, 0xd1, 0xb4, 0xfb, 0x22, 0xfc, 0xdf, 0x5a, 0x19, 0xa7, + 0x33, 0x32, 0x03, 0x27, 0xd8, 0xf7, 0x1c, 0xcf, 0x49, 0x6c, 0xb3, + 0xa4, 0x4a, 0x77, 0xaf, 0x56, 0xe3, 0xdd, 0xe7, 0x3d, 0x3a, 0x5f, + 0x17, 0x68, 0x96, 0xcc, 0x57, 0xc9, 0xa5, 0xad, 0x99})), + std::make_pair( + 222, + std::vector<uint8_t>( + {0x78, 0x5a, 0x9d, 0x0f, 0xbd, 0x21, 0x13, 0x6d, 0xbc, 0xe8, 0xfa, + 0x7e, 0xaf, 0xd6, 0x3c, 0x9d, 0xad, 0x22, 0x00, 0x52, 0x97, 0x84, + 0x16, 0xb3, 0x1d, 0x97, 0x53, 0xea, 0xa1, 0x49, 0x09, 0x78, 0x47, + 0xed, 0x9b, 0x30, 0xa6, 0x5c, 0x70, 0x50, 0x7e, 0xff, 0x01, 0x87, + 0x91, 0x49, 0xed, 0x5c, 0xf0, 0x47, 0x1d, 0x37, 0x79, 0x8e, 0xdc, + 0x05, 0xab, 0xd5, 0x6a, 0xd4, 0xa2, 0xcc, 0xcb, 0x1d})), + std::make_pair( + 223, + std::vector<uint8_t>( + {0xad, 0x40, 0x8d, 0x2a, 0xbd, 0xdf, 0xd3, 0x7b, 0x3b, 0xf3, 0x47, + 0x94, 0xc1, 0xa3, 0x37, 0x1d, 0x92, 0x8e, 0xd7, 0xfc, 0x8d, 0x96, + 0x62, 0x25, 0x33, 0x35, 0x84, 0xc5, 0x66, 0x58, 0x17, 0x83, 0x2a, + 0x37, 0xc0, 0x7f, 0x0d, 0xc7, 0xcb, 0x5a, 0xa8, 0x74, 0xcd, 0x7d, + 0x20, 0xfe, 0x8f, 0xab, 0x8e, 0xab, 0xcb, 0x9b, 0x33, 0xd2, 0xe0, + 0x84, 0x1f, 0x6e, 0x20, 0x09, 0x60, 0x89, 0x9d, 0x95})), + std::make_pair( + 224, + std::vector<uint8_t>( + {0x97, 0x66, 0x8f, 0x74, 0x5b, 0x60, 0x32, 0xfc, 0x81, 0x5d, 0x95, + 0x79, 0x32, 0x27, 0x69, 0xdc, 0xcd, 0x95, 0x01, 0xa5, 0x08, 0x00, + 0x29, 0xb8, 0xae, 0x82, 0x6b, 0xef, 0xb6, 0x74, 0x23, 0x31, 0xbd, + 0x9f, 0x76, 0xef, 0xeb, 0x3e, 0x2b, 0x8e, 0x81, 0xa9, 0x78, 0x6b, + 0x28, 0x2f, 0x50, 0x68, 0xa3, 0xa2, 0x42, 0x46, 0x97, 0xa7, 0x7c, + 0x41, 0x87, 0x6b, 0x7e, 0x75, 0x3f, 0x4c, 0x77, 0x67})), + std::make_pair( + 225, + std::vector<uint8_t>( + {0x26, 0xbb, 0x98, 0x5f, 0x47, 0xe7, 0xfe, 0xe0, 0xcf, 0xd2, 0x52, + 0xd4, 0xef, 0x96, 0xbe, 0xd4, 0x2b, 0x9c, 0x37, 0x0c, 0x1c, 0x6a, + 0x3e, 0x8c, 0x9e, 0xb0, 0x4e, 0xf7, 0xf7, 0x81, 0x8b, 0x83, 0x3a, + 0x0d, 0x1f, 0x04, 0x3e, 0xba, 0xfb, 0x91, 0x1d, 0xc7, 0x79, 0xe0, + 0x27, 0x40, 0xa0, 0x2a, 0x44, 0xd3, 0xa1, 0xea, 0x45, 0xed, 0x4a, + 0xd5, 0x5e, 0x68, 0x6c, 0x92, 0x7c, 0xaf, 0xe9, 0x7e})), + std::make_pair( + 226, + std::vector<uint8_t>( + {0x5b, 0xfe, 0x2b, 0x1d, 0xcf, 0x7f, 0xe9, 0xb9, 0x50, 0x88, 0xac, + 0xed, 0xb5, 0x75, 0xc1, 0x90, 0x16, 0xc7, 0x43, 0xb2, 0xe7, 0x63, + 0xbf, 0x58, 0x51, 0xac, 0x40, 0x7c, 0x9e, 0xda, 0x43, 0x71, 0x5e, + 0xdf, 0xa4, 0x8b, 0x48, 0x25, 0x49, 0x2c, 0x51, 0x79, 0x59, 0x3f, + 0xff, 0x21, 0x35, 0x1b, 0x76, 0xe8, 0xb7, 0xe0, 0x34, 0xe4, 0xc5, + 0x3c, 0x79, 0xf6, 0x1f, 0x29, 0xc4, 0x79, 0xbd, 0x08})), + std::make_pair( + 227, + std::vector<uint8_t>( + {0xc7, 0x65, 0x09, 0xef, 0x72, 0xf4, 0xa6, 0xf9, 0xc9, 0xc4, 0x06, + 0x18, 0xed, 0x52, 0xb2, 0x08, 0x4f, 0x83, 0x50, 0x22, 0x32, 0xe0, + 0xac, 0x8b, 0xda, 0xf3, 0x26, 0x43, 0x68, 0xe4, 0xd0, 0x18, 0x0f, + 0x68, 0x54, 0xc4, 0xab, 0xf4, 0xf6, 0x50, 0x9c, 0x79, 0xca, 0xaf, + 0xc4, 0x4c, 0xf3, 0x19, 0x4a, 0xfc, 0x57, 0xbd, 0x07, 0x7b, 0xd7, + 0xb3, 0xc9, 0xbd, 0xa3, 0xd4, 0xb8, 0x77, 0x58, 0x16})), + std::make_pair( + 228, + std::vector<uint8_t>( + {0xd6, 0x6f, 0x2b, 0xea, 0xb9, 0x90, 0xe3, 0x54, 0xcc, 0xb9, 0x10, + 0xe4, 0xe9, 0xc7, 0xac, 0x61, 0x8c, 0x7b, 0x63, 0xef, 0x29, 0x2a, + 0x96, 0xb5, 0x52, 0x34, 0x1d, 0xe7, 0x8d, 0xc4, 0x6d, 0x3e, 0xc8, + 0xcf, 0xab, 0xc6, 0x99, 0xb5, 0x0a, 0xf4, 0x1f, 0xda, 0x39, 0xcf, + 0x1b, 0x01, 0x73, 0x66, 0x09, 0x23, 0x51, 0x0a, 0xd6, 0x7f, 0xae, + 0xde, 0xf5, 0x20, 0x7c, 0xff, 0xe8, 0x64, 0x1d, 0x20})), + std::make_pair( + 229, + std::vector<uint8_t>( + {0x7d, 0x8f, 0x06, 0x72, 0x99, 0x2b, 0x79, 0xbe, 0x3a, 0x36, 0x4d, + 0x8e, 0x59, 0x04, 0xf4, 0xab, 0x71, 0x3b, 0xbc, 0x8a, 0xb0, 0x1b, + 0x4f, 0x30, 0x9a, 0xd8, 0xcc, 0xf2, 0x23, 0xce, 0x10, 0x34, 0xa8, + 0x60, 0xdc, 0xb0, 0xb0, 0x05, 0x50, 0x61, 0x2c, 0xc2, 0xfa, 0x17, + 0xf2, 0x96, 0x9e, 0x18, 0xf2, 0x2e, 0x14, 0x27, 0xd2, 0x54, 0xb4, + 0xa8, 0x2b, 0x3a, 0x03, 0xa3, 0xeb, 0x39, 0x4a, 0xdf})), + std::make_pair( + 230, + std::vector<uint8_t>( + {0xa5, 0x6d, 0x67, 0x25, 0xbf, 0xb3, 0xde, 0x47, 0xc1, 0x41, 0x4a, + 0xdf, 0x25, 0xfc, 0x8f, 0x0f, 0xc9, 0x84, 0x6f, 0x69, 0x87, 0x72, + 0x2b, 0xc0, 0x63, 0x66, 0xd5, 0xca, 0x4e, 0x89, 0x72, 0x29, 0x25, + 0xeb, 0xbc, 0x88, 0x14, 0x18, 0x84, 0x40, 0x75, 0x39, 0x7a, 0x0c, + 0xa8, 0x98, 0x42, 0xc7, 0xb9, 0xe9, 0xe0, 0x7e, 0x1d, 0x9d, 0x18, + 0x3e, 0xbe, 0xb3, 0x9e, 0x12, 0x0b, 0x48, 0x3b, 0xf7})), + std::make_pair( + 231, + std::vector<uint8_t>( + {0xaf, 0x5e, 0x03, 0xd7, 0xfe, 0x60, 0xc6, 0x7e, 0x10, 0x31, 0x33, + 0x44, 0x43, 0x4e, 0x79, 0x48, 0x5a, 0x03, 0xa7, 0x58, 0xd6, 0xdc, + 0xe9, 0x85, 0x57, 0x47, 0x45, 0x76, 0x3c, 0x1c, 0x5c, 0x77, 0xd4, + 0xfb, 0x3e, 0x6f, 0xb1, 0x22, 0x30, 0x36, 0x83, 0x70, 0x99, 0x3b, + 0xf9, 0x0f, 0xee, 0xd0, 0xc5, 0xd1, 0x60, 0x75, 0x24, 0x56, 0x2d, + 0x7c, 0x09, 0xc0, 0xc2, 0x10, 0xed, 0x39, 0x3d, 0x7c})), + std::make_pair( + 232, + std::vector<uint8_t>( + {0x7a, 0x20, 0x54, 0x0c, 0xc0, 0x7b, 0xf7, 0x2b, 0x58, 0x24, 0x21, + 0xfc, 0x34, 0x2e, 0x82, 0xf5, 0x21, 0x34, 0xb6, 0x98, 0x41, 0xec, + 0x28, 0xed, 0x18, 0x9e, 0x2e, 0xa6, 0xa2, 0x9d, 0xd2, 0xf8, 0x2a, + 0x64, 0x03, 0x52, 0xd2, 0x22, 0xb5, 0x2f, 0x29, 0x11, 0xdc, 0x72, + 0xa7, 0xda, 0xb3, 0x1c, 0xaa, 0xdd, 0x80, 0xc6, 0x11, 0x8f, 0x13, + 0xc5, 0x6b, 0x2a, 0x1e, 0x43, 0x73, 0xbe, 0x0e, 0xa3})), + std::make_pair( + 233, + std::vector<uint8_t>( + {0x48, 0x6f, 0x02, 0xc6, 0x3e, 0x54, 0x67, 0xea, 0x1f, 0xdd, 0xe7, + 0xe8, 0x2b, 0xfa, 0xcc, 0x2c, 0x1b, 0xa5, 0xd6, 0x36, 0xd9, 0xf3, + 0xd0, 0x8b, 0x21, 0x0d, 0xa3, 0xf3, 0x72, 0xf7, 0x06, 0xec, 0x21, + 0x8c, 0xc1, 0x7f, 0xf6, 0x0a, 0xef, 0x70, 0x3b, 0xbe, 0x0c, 0x15, + 0xc3, 0x8a, 0xe5, 0x5d, 0x28, 0x6a, 0x68, 0x4f, 0x86, 0x4c, 0x78, + 0x21, 0x1c, 0xca, 0xb4, 0x17, 0x8c, 0x92, 0xad, 0xba})), + std::make_pair( + 234, + std::vector<uint8_t>( + {0x1c, 0x7a, 0x5c, 0x1d, 0xed, 0xcd, 0x04, 0xa9, 0x21, 0x78, 0x8f, + 0x7e, 0xb2, 0x33, 0x61, 0xca, 0x19, 0x53, 0xb0, 0x4b, 0x9c, 0x7a, + 0xec, 0x35, 0xd6, 0x5e, 0xa3, 0xe4, 0x99, 0x6d, 0xb2, 0x6f, 0x28, + 0x12, 0x78, 0xea, 0x4a, 0xe6, 0x66, 0xad, 0x81, 0x02, 0x7d, 0x98, + 0xaf, 0x57, 0x26, 0x2c, 0xdb, 0xfa, 0x4c, 0x08, 0x5f, 0x42, 0x10, + 0x56, 0x8c, 0x7e, 0x15, 0xee, 0xc7, 0x80, 0x51, 0x14})), + std::make_pair( + 235, + std::vector<uint8_t>( + {0x9c, 0xe3, 0xfa, 0x9a, 0x86, 0x0b, 0xdb, 0xd5, 0x37, 0x8f, 0xd6, + 0xd7, 0xb8, 0xb6, 0x71, 0xc6, 0xcb, 0x76, 0x92, 0x91, 0x0c, 0xe8, + 0xf9, 0xb6, 0xcb, 0x41, 0x22, 0xcb, 0xcb, 0xe6, 0xac, 0x06, 0xca, + 0x04, 0x22, 0xce, 0xf1, 0x22, 0x59, 0x35, 0x05, 0x3b, 0x7d, 0x19, + 0x3a, 0x81, 0xb9, 0xe9, 0x72, 0xeb, 0x85, 0xa1, 0xd3, 0x07, 0x4f, + 0x14, 0xcb, 0xb5, 0xec, 0x9f, 0x05, 0x73, 0x89, 0x2d})), + std::make_pair( + 236, + std::vector<uint8_t>( + {0xa9, 0x11, 0x87, 0xbe, 0x5c, 0x37, 0x1c, 0x42, 0x65, 0xc1, 0x74, + 0xfd, 0x46, 0x53, 0xb8, 0xab, 0x70, 0x85, 0x51, 0xf8, 0x3d, 0x1f, + 0xee, 0x1c, 0xc1, 0x47, 0x95, 0x81, 0xbc, 0x00, 0x6d, 0x6f, 0xb7, + 0x8f, 0xcc, 0x9a, 0x5d, 0xee, 0x1d, 0xb3, 0x66, 0x6f, 0x50, 0x8f, + 0x97, 0x80, 0xa3, 0x75, 0x93, 0xeb, 0xcc, 0xcf, 0x5f, 0xbe, 0xd3, + 0x96, 0x67, 0xdc, 0x63, 0x61, 0xe9, 0x21, 0xf7, 0x79})), + std::make_pair( + 237, + std::vector<uint8_t>( + {0x46, 0x25, 0x76, 0x7d, 0x7b, 0x1d, 0x3d, 0x3e, 0xd2, 0xfb, 0xc6, + 0x74, 0xaf, 0x14, 0xe0, 0x24, 0x41, 0x52, 0xf2, 0xa4, 0x02, 0x1f, + 0xcf, 0x33, 0x11, 0x50, 0x5d, 0x89, 0xbd, 0x81, 0xe2, 0xf9, 0xf9, + 0xa5, 0x00, 0xc3, 0xb1, 0x99, 0x91, 0x4d, 0xb4, 0x95, 0x00, 0xb3, + 0xc9, 0x8d, 0x03, 0xea, 0x93, 0x28, 0x67, 0x51, 0xa6, 0x86, 0xa3, + 0xb8, 0x75, 0xda, 0xab, 0x0c, 0xcd, 0x63, 0xb4, 0x4f})), + std::make_pair( + 238, + std::vector<uint8_t>( + {0x43, 0xdf, 0xdf, 0xe1, 0xb0, 0x14, 0xfe, 0xd3, 0xa2, 0xac, 0xab, + 0xb7, 0xf3, 0xe9, 0xa1, 0x82, 0xf2, 0xaa, 0x18, 0x01, 0x9d, 0x27, + 0xe3, 0xe6, 0xcd, 0xcf, 0x31, 0xa1, 0x5b, 0x42, 0x8e, 0x91, 0xe7, + 0xb0, 0x8c, 0xf5, 0xe5, 0xc3, 0x76, 0xfc, 0xe2, 0xd8, 0xa2, 0x8f, + 0xf8, 0x5a, 0xb0, 0xa0, 0xa1, 0x65, 0x6e, 0xdb, 0x4a, 0x0a, 0x91, + 0x53, 0x26, 0x20, 0x09, 0x6d, 0x9a, 0x5a, 0x65, 0x2d})), + std::make_pair( + 239, + std::vector<uint8_t>( + {0x27, 0x9e, 0x32, 0x02, 0xbe, 0x39, 0x89, 0xba, 0x31, 0x12, 0x77, + 0x25, 0x85, 0x17, 0x74, 0x87, 0xe4, 0xfe, 0x3e, 0xe3, 0xea, 0xb4, + 0x9c, 0x2f, 0x7f, 0xa7, 0xfe, 0x87, 0xcf, 0xe7, 0xb8, 0x0d, 0x3e, + 0x03, 0x55, 0xed, 0xff, 0x6d, 0x03, 0x1e, 0x6c, 0x96, 0xc7, 0x95, + 0xdb, 0x1c, 0x6f, 0x04, 0x18, 0x80, 0xec, 0x38, 0x24, 0xde, 0xfa, + 0xcf, 0x92, 0x63, 0x82, 0x0a, 0x8e, 0x73, 0x27, 0xde})), + std::make_pair( + 240, + std::vector<uint8_t>( + {0xea, 0x2d, 0x06, 0x6a, 0xc2, 0x29, 0xd4, 0xd4, 0xb6, 0x16, 0xa8, + 0xbe, 0xde, 0xc7, 0x34, 0x32, 0x52, 0x24, 0xe4, 0xb4, 0xe5, 0x8f, + 0x1a, 0xe6, 0xda, 0xd7, 0xe4, 0x0c, 0x2d, 0xa2, 0x91, 0x96, 0xc3, + 0xb1, 0xea, 0x95, 0x71, 0xda, 0xcc, 0x81, 0xe8, 0x73, 0x28, 0xca, + 0xa0, 0x21, 0x1e, 0x09, 0x02, 0x7b, 0x05, 0x24, 0xaa, 0x3f, 0x4a, + 0x84, 0x99, 0x17, 0xb3, 0x58, 0x67, 0x47, 0xeb, 0xbb})), + std::make_pair( + 241, + std::vector<uint8_t>( + {0x49, 0xf0, 0x14, 0xf5, 0xc6, 0x18, 0x22, 0xc8, 0x99, 0xab, 0x5c, + 0xae, 0x51, 0xbe, 0x40, 0x44, 0xa4, 0x49, 0x5e, 0x77, 0x7d, 0xeb, + 0x7d, 0xa9, 0xb6, 0xd8, 0x49, 0x0e, 0xfb, 0xb8, 0x75, 0x30, 0xad, + 0xf2, 0x93, 0xda, 0xf0, 0x79, 0xf9, 0x4c, 0x33, 0xb7, 0x04, 0x4e, + 0xf6, 0x2e, 0x2e, 0x5b, 0xb3, 0xeb, 0x11, 0xe1, 0x73, 0x04, 0xf8, + 0x45, 0x3e, 0xe6, 0xce, 0x24, 0xf0, 0x33, 0xdd, 0xb0})), + std::make_pair( + 242, + std::vector<uint8_t>( + {0x92, 0x33, 0x49, 0x03, 0x44, 0xe5, 0xb0, 0xdc, 0x59, 0x12, 0x67, + 0x1b, 0x7a, 0xe5, 0x4c, 0xee, 0x77, 0x30, 0xdb, 0xe1, 0xf4, 0xc7, + 0xd9, 0x2a, 0x4d, 0x3e, 0x3a, 0xab, 0x50, 0x57, 0x17, 0x08, 0xdb, + 0x51, 0xdc, 0xf9, 0xc2, 0x94, 0x45, 0x91, 0xdb, 0x65, 0x1d, 0xb3, + 0x2d, 0x22, 0x93, 0x5b, 0x86, 0x94, 0x49, 0x69, 0xbe, 0x77, 0xd5, + 0xb5, 0xfe, 0xae, 0x6c, 0x38, 0x40, 0xa8, 0xdb, 0x26})), + std::make_pair( + 243, + std::vector<uint8_t>( + {0xb6, 0xe7, 0x5e, 0x6f, 0x4c, 0x7f, 0x45, 0x3b, 0x74, 0x65, 0xd2, + 0x5b, 0x5a, 0xc8, 0xc7, 0x19, 0x69, 0x02, 0xea, 0xa9, 0x53, 0x87, + 0x52, 0x28, 0xc8, 0x63, 0x4e, 0x16, 0xe2, 0xae, 0x1f, 0x38, 0xbc, + 0x32, 0x75, 0x30, 0x43, 0x35, 0xf5, 0x98, 0x9e, 0xcc, 0xc1, 0xe3, + 0x41, 0x67, 0xd4, 0xe6, 0x8d, 0x77, 0x19, 0x96, 0x8f, 0xba, 0x8e, + 0x2f, 0xe6, 0x79, 0x47, 0xc3, 0x5c, 0x48, 0xe8, 0x06})), + std::make_pair( + 244, + std::vector<uint8_t>( + {0xcc, 0x14, 0xca, 0x66, 0x5a, 0xf1, 0x48, 0x3e, 0xfb, 0xc3, 0xaf, + 0x80, 0x08, 0x0e, 0x65, 0x0d, 0x50, 0x46, 0xa3, 0x93, 0x2f, 0x4f, + 0x51, 0xf3, 0xfe, 0x90, 0xa0, 0x70, 0x5e, 0xc2, 0x51, 0x04, 0xad, + 0xf0, 0x78, 0x39, 0x26, 0x5d, 0xc5, 0x1d, 0x43, 0x40, 0x14, 0x11, + 0x24, 0x6e, 0x47, 0x4f, 0x0d, 0x5e, 0x56, 0x37, 0xaf, 0x94, 0x76, + 0x72, 0x83, 0xd5, 0x3e, 0x06, 0x17, 0xe9, 0x81, 0xf4})), + std::make_pair( + 245, + std::vector<uint8_t>( + {0x23, 0x0a, 0x1c, 0x85, 0x7c, 0xb2, 0xe7, 0x85, 0x2e, 0x41, 0xb6, + 0x47, 0xe9, 0x0e, 0x45, 0x85, 0xd2, 0xd8, 0x81, 0xe1, 0x73, 0x4d, + 0xc3, 0x89, 0x55, 0x35, 0x6e, 0x8d, 0xd7, 0xbf, 0xf3, 0x90, 0x53, + 0x09, 0x2c, 0x6b, 0x38, 0xe2, 0x36, 0xe1, 0x89, 0x95, 0x25, 0x64, + 0x70, 0x73, 0xdd, 0xdf, 0x68, 0x95, 0xd6, 0x42, 0x06, 0x32, 0x5e, + 0x76, 0x47, 0xf2, 0x75, 0x56, 0x7b, 0x25, 0x59, 0x09})), + std::make_pair( + 246, + std::vector<uint8_t>( + {0xcb, 0xb6, 0x53, 0x21, 0xac, 0x43, 0x6e, 0x2f, 0xfd, 0xab, 0x29, + 0x36, 0x35, 0x9c, 0xe4, 0x90, 0x23, 0xf7, 0xde, 0xe7, 0x61, 0x4e, + 0xf2, 0x8d, 0x17, 0x3c, 0x3d, 0x27, 0xc5, 0xd1, 0xbf, 0xfa, 0x51, + 0x55, 0x3d, 0x43, 0x3f, 0x8e, 0xe3, 0xc9, 0xe4, 0x9c, 0x05, 0xa2, + 0xb8, 0x83, 0xcc, 0xe9, 0x54, 0xc9, 0xa8, 0x09, 0x3b, 0x80, 0x61, + 0x2a, 0x0c, 0xdd, 0x47, 0x32, 0xe0, 0x41, 0xf9, 0x95})), + std::make_pair( + 247, + std::vector<uint8_t>( + {0x3e, 0x7e, 0x57, 0x00, 0x74, 0x33, 0x72, 0x75, 0xef, 0xb5, 0x13, + 0x15, 0x58, 0x80, 0x34, 0xc3, 0xcf, 0x0d, 0xdd, 0xca, 0x20, 0xb4, + 0x61, 0x2e, 0x0b, 0xd5, 0xb8, 0x81, 0xe7, 0xe5, 0x47, 0x6d, 0x31, + 0x9c, 0xe4, 0xfe, 0x9f, 0x19, 0x18, 0x6e, 0x4c, 0x08, 0x26, 0xf4, + 0x4f, 0x13, 0x1e, 0xb0, 0x48, 0xe6, 0x5b, 0xe2, 0x42, 0xb1, 0x17, + 0x2c, 0x63, 0xba, 0xdb, 0x12, 0x3a, 0xb0, 0xcb, 0xe8})), + std::make_pair( + 248, + std::vector<uint8_t>( + {0xd3, 0x2e, 0x9e, 0xc0, 0x2d, 0x38, 0xd4, 0xe1, 0xb8, 0x24, 0x9d, + 0xf8, 0xdc, 0xb0, 0x0c, 0x5b, 0x9c, 0x68, 0xeb, 0x89, 0x22, 0x67, + 0x2e, 0x35, 0x05, 0x39, 0x3b, 0x6a, 0x21, 0x0b, 0xa5, 0x6f, 0x94, + 0x96, 0xe5, 0xee, 0x04, 0x90, 0xef, 0x38, 0x7c, 0x3c, 0xde, 0xc0, + 0x61, 0xf0, 0x6b, 0xc0, 0x38, 0x2d, 0x93, 0x04, 0xca, 0xfb, 0xb8, + 0xe0, 0xcd, 0x33, 0xd5, 0x70, 0x29, 0xe6, 0x2d, 0xf2})), + std::make_pair( + 249, + std::vector<uint8_t>( + {0x8c, 0x15, 0x12, 0x46, 0x60, 0x89, 0xf0, 0x5b, 0x37, 0x75, 0xc2, + 0x62, 0xb6, 0x2d, 0x22, 0xb8, 0x38, 0x54, 0xa8, 0x32, 0x18, 0x13, + 0x0b, 0x4e, 0xc9, 0x1b, 0x3c, 0xcb, 0xd2, 0x93, 0xd2, 0xa5, 0x43, + 0x02, 0xce, 0xca, 0xab, 0x9b, 0x10, 0x0c, 0x68, 0xd1, 0xe6, 0xdd, + 0xc8, 0xf0, 0x7c, 0xdd, 0xbd, 0xfe, 0x6f, 0xda, 0xaa, 0xf0, 0x99, + 0xcc, 0x09, 0xd6, 0xb7, 0x25, 0x87, 0x9c, 0x63, 0x69})), + std::make_pair( + 250, + std::vector<uint8_t>( + {0x91, 0xa7, 0xf6, 0x1c, 0x97, 0xc2, 0x91, 0x1e, 0x4c, 0x81, 0x2e, + 0xf7, 0x1d, 0x78, 0x0a, 0xd8, 0xfa, 0x78, 0x87, 0x94, 0x56, 0x1d, + 0x08, 0x30, 0x3f, 0xd1, 0xc1, 0xcb, 0x60, 0x8a, 0x46, 0xa1, 0x25, + 0x63, 0x08, 0x6e, 0xc5, 0xb3, 0x9d, 0x47, 0x1a, 0xed, 0x94, 0xfb, + 0x0f, 0x6c, 0x67, 0x8a, 0x43, 0xb8, 0x79, 0x29, 0x32, 0xf9, 0x02, + 0x8d, 0x77, 0x2a, 0x22, 0x76, 0x8e, 0xa2, 0x3a, 0x9b})), + std::make_pair( + 251, + std::vector<uint8_t>( + {0x4f, 0x6b, 0xb2, 0x22, 0xa3, 0x95, 0xe8, 0xb1, 0x8f, 0x6b, 0xa1, + 0x55, 0x47, 0x7a, 0xed, 0x3f, 0x07, 0x29, 0xac, 0x9e, 0x83, 0xe1, + 0x6d, 0x31, 0xa2, 0xa8, 0xbc, 0x65, 0x54, 0x22, 0xb8, 0x37, 0xc8, + 0x91, 0xc6, 0x19, 0x9e, 0x6f, 0x0d, 0x75, 0x79, 0x9e, 0x3b, 0x69, + 0x15, 0x25, 0xc5, 0x81, 0x95, 0x35, 0x17, 0xf2, 0x52, 0xc4, 0xb9, + 0xe3, 0xa2, 0x7a, 0x28, 0xfb, 0xaf, 0x49, 0x64, 0x4c})), + std::make_pair( + 252, + std::vector<uint8_t>( + {0x5d, 0x06, 0xc0, 0x7e, 0x7a, 0x64, 0x6c, 0x41, 0x3a, 0x50, 0x1c, + 0x3f, 0x4b, 0xb2, 0xfc, 0x38, 0x12, 0x7d, 0xe7, 0x50, 0x9b, 0x70, + 0x77, 0xc4, 0xd9, 0xb5, 0x61, 0x32, 0x01, 0xc1, 0xaa, 0x02, 0xfd, + 0x5f, 0x79, 0xd2, 0x74, 0x59, 0x15, 0xdd, 0x57, 0xfb, 0xcb, 0x4c, + 0xe0, 0x86, 0x95, 0xf6, 0xef, 0xc0, 0xcb, 0x3d, 0x2d, 0x33, 0x0e, + 0x19, 0xb4, 0xb0, 0xe6, 0x00, 0x4e, 0xa6, 0x47, 0x1e})), + std::make_pair( + 253, + std::vector<uint8_t>( + {0xb9, 0x67, 0x56, 0xe5, 0x79, 0x09, 0x96, 0x8f, 0x14, 0xb7, 0x96, + 0xa5, 0xd3, 0x0f, 0x4c, 0x9d, 0x67, 0x14, 0x72, 0xcf, 0x82, 0xc8, + 0xcf, 0xb2, 0xca, 0xca, 0x7a, 0xc7, 0xa4, 0x4c, 0xa0, 0xa1, 0x4c, + 0x98, 0x42, 0xd0, 0x0c, 0x82, 0xe3, 0x37, 0x50, 0x2c, 0x94, 0xd5, + 0x96, 0x0a, 0xca, 0x4c, 0x49, 0x2e, 0xa7, 0xb0, 0xdf, 0x91, 0x9d, + 0xdf, 0x1a, 0xad, 0xa2, 0xa2, 0x75, 0xbb, 0x10, 0xd4})), + std::make_pair( + 254, + std::vector<uint8_t>( + {0xff, 0x0a, 0x01, 0x5e, 0x98, 0xdb, 0x9c, 0x99, 0xf0, 0x39, 0x77, + 0x71, 0x0a, 0xac, 0x3e, 0x65, 0x8c, 0x0d, 0x89, 0x6f, 0x6d, 0x71, + 0xd6, 0x18, 0xba, 0x79, 0xdc, 0x6c, 0xf7, 0x2a, 0xc7, 0x5b, 0x7c, + 0x03, 0x8e, 0xb6, 0x86, 0x2d, 0xed, 0xe4, 0x54, 0x3e, 0x14, 0x54, + 0x13, 0xa6, 0x36, 0x8d, 0x69, 0xf5, 0x72, 0x2c, 0x82, 0x7b, 0xa3, + 0xef, 0x25, 0xb6, 0xae, 0x64, 0x40, 0xd3, 0x92, 0x76})), + std::make_pair( + 255, + std::vector<uint8_t>( + {0x5b, 0x21, 0xc5, 0xfd, 0x88, 0x68, 0x36, 0x76, 0x12, 0x47, 0x4f, + 0xa2, 0xe7, 0x0e, 0x9c, 0xfa, 0x22, 0x01, 0xff, 0xee, 0xe8, 0xfa, + 0xfa, 0xb5, 0x79, 0x7a, 0xd5, 0x8f, 0xef, 0xa1, 0x7c, 0x9b, 0x5b, + 0x10, 0x7d, 0xa4, 0xa3, 0xdb, 0x63, 0x20, 0xba, 0xaf, 0x2c, 0x86, + 0x17, 0xd5, 0xa5, 0x1d, 0xf9, 0x14, 0xae, 0x88, 0xda, 0x38, 0x67, + 0xc2, 0xd4, 0x1f, 0x0c, 0xc1, 0x4f, 0xa6, 0x79, 0x28}))}; + +std::vector<std::pair<int, std::vector<uint8_t>>> TestcasesKeyed = { + std::make_pair( + 0, + std::vector<uint8_t>( + {0x10, 0xeb, 0xb6, 0x77, 0x00, 0xb1, 0x86, 0x8e, 0xfb, 0x44, 0x17, + 0x98, 0x7a, 0xcf, 0x46, 0x90, 0xae, 0x9d, 0x97, 0x2f, 0xb7, 0xa5, + 0x90, 0xc2, 0xf0, 0x28, 0x71, 0x79, 0x9a, 0xaa, 0x47, 0x86, 0xb5, + 0xe9, 0x96, 0xe8, 0xf0, 0xf4, 0xeb, 0x98, 0x1f, 0xc2, 0x14, 0xb0, + 0x05, 0xf4, 0x2d, 0x2f, 0xf4, 0x23, 0x34, 0x99, 0x39, 0x16, 0x53, + 0xdf, 0x7a, 0xef, 0xcb, 0xc1, 0x3f, 0xc5, 0x15, 0x68})), + std::make_pair( + 1, + std::vector<uint8_t>( + {0x96, 0x1f, 0x6d, 0xd1, 0xe4, 0xdd, 0x30, 0xf6, 0x39, 0x01, 0x69, + 0x0c, 0x51, 0x2e, 0x78, 0xe4, 0xb4, 0x5e, 0x47, 0x42, 0xed, 0x19, + 0x7c, 0x3c, 0x5e, 0x45, 0xc5, 0x49, 0xfd, 0x25, 0xf2, 0xe4, 0x18, + 0x7b, 0x0b, 0xc9, 0xfe, 0x30, 0x49, 0x2b, 0x16, 0xb0, 0xd0, 0xbc, + 0x4e, 0xf9, 0xb0, 0xf3, 0x4c, 0x70, 0x03, 0xfa, 0xc0, 0x9a, 0x5e, + 0xf1, 0x53, 0x2e, 0x69, 0x43, 0x02, 0x34, 0xce, 0xbd})), + std::make_pair( + 2, + std::vector<uint8_t>( + {0xda, 0x2c, 0xfb, 0xe2, 0xd8, 0x40, 0x9a, 0x0f, 0x38, 0x02, 0x61, + 0x13, 0x88, 0x4f, 0x84, 0xb5, 0x01, 0x56, 0x37, 0x1a, 0xe3, 0x04, + 0xc4, 0x43, 0x01, 0x73, 0xd0, 0x8a, 0x99, 0xd9, 0xfb, 0x1b, 0x98, + 0x31, 0x64, 0xa3, 0x77, 0x07, 0x06, 0xd5, 0x37, 0xf4, 0x9e, 0x0c, + 0x91, 0x6d, 0x9f, 0x32, 0xb9, 0x5c, 0xc3, 0x7a, 0x95, 0xb9, 0x9d, + 0x85, 0x74, 0x36, 0xf0, 0x23, 0x2c, 0x88, 0xa9, 0x65})), + std::make_pair( + 3, + std::vector<uint8_t>( + {0x33, 0xd0, 0x82, 0x5d, 0xdd, 0xf7, 0xad, 0xa9, 0x9b, 0x0e, 0x7e, + 0x30, 0x71, 0x04, 0xad, 0x07, 0xca, 0x9c, 0xfd, 0x96, 0x92, 0x21, + 0x4f, 0x15, 0x61, 0x35, 0x63, 0x15, 0xe7, 0x84, 0xf3, 0xe5, 0xa1, + 0x7e, 0x36, 0x4a, 0xe9, 0xdb, 0xb1, 0x4c, 0xb2, 0x03, 0x6d, 0xf9, + 0x32, 0xb7, 0x7f, 0x4b, 0x29, 0x27, 0x61, 0x36, 0x5f, 0xb3, 0x28, + 0xde, 0x7a, 0xfd, 0xc6, 0xd8, 0x99, 0x8f, 0x5f, 0xc1})), + std::make_pair( + 4, + std::vector<uint8_t>( + {0xbe, 0xaa, 0x5a, 0x3d, 0x08, 0xf3, 0x80, 0x71, 0x43, 0xcf, 0x62, + 0x1d, 0x95, 0xcd, 0x69, 0x05, 0x14, 0xd0, 0xb4, 0x9e, 0xff, 0xf9, + 0xc9, 0x1d, 0x24, 0xb5, 0x92, 0x41, 0xec, 0x0e, 0xef, 0xa5, 0xf6, + 0x01, 0x96, 0xd4, 0x07, 0x04, 0x8b, 0xba, 0x8d, 0x21, 0x46, 0x82, + 0x8e, 0xbc, 0xb0, 0x48, 0x8d, 0x88, 0x42, 0xfd, 0x56, 0xbb, 0x4f, + 0x6d, 0xf8, 0xe1, 0x9c, 0x4b, 0x4d, 0xaa, 0xb8, 0xac})), + std::make_pair( + 5, + std::vector<uint8_t>( + {0x09, 0x80, 0x84, 0xb5, 0x1f, 0xd1, 0x3d, 0xea, 0xe5, 0xf4, 0x32, + 0x0d, 0xe9, 0x4a, 0x68, 0x8e, 0xe0, 0x7b, 0xae, 0xa2, 0x80, 0x04, + 0x86, 0x68, 0x9a, 0x86, 0x36, 0x11, 0x7b, 0x46, 0xc1, 0xf4, 0xc1, + 0xf6, 0xaf, 0x7f, 0x74, 0xae, 0x7c, 0x85, 0x76, 0x00, 0x45, 0x6a, + 0x58, 0xa3, 0xaf, 0x25, 0x1d, 0xc4, 0x72, 0x3a, 0x64, 0xcc, 0x7c, + 0x0a, 0x5a, 0xb6, 0xd9, 0xca, 0xc9, 0x1c, 0x20, 0xbb})), + std::make_pair( + 6, + std::vector<uint8_t>( + {0x60, 0x44, 0x54, 0x0d, 0x56, 0x08, 0x53, 0xeb, 0x1c, 0x57, 0xdf, + 0x00, 0x77, 0xdd, 0x38, 0x10, 0x94, 0x78, 0x1c, 0xdb, 0x90, 0x73, + 0xe5, 0xb1, 0xb3, 0xd3, 0xf6, 0xc7, 0x82, 0x9e, 0x12, 0x06, 0x6b, + 0xba, 0xca, 0x96, 0xd9, 0x89, 0xa6, 0x90, 0xde, 0x72, 0xca, 0x31, + 0x33, 0xa8, 0x36, 0x52, 0xba, 0x28, 0x4a, 0x6d, 0x62, 0x94, 0x2b, + 0x27, 0x1f, 0xfa, 0x26, 0x20, 0xc9, 0xe7, 0x5b, 0x1f})), + std::make_pair( + 7, + std::vector<uint8_t>( + {0x7a, 0x8c, 0xfe, 0x9b, 0x90, 0xf7, 0x5f, 0x7e, 0xcb, 0x3a, 0xcc, + 0x05, 0x3a, 0xae, 0xd6, 0x19, 0x31, 0x12, 0xb6, 0xf6, 0xa4, 0xae, + 0xeb, 0x3f, 0x65, 0xd3, 0xde, 0x54, 0x19, 0x42, 0xde, 0xb9, 0xe2, + 0x22, 0x81, 0x52, 0xa3, 0xc4, 0xbb, 0xbe, 0x72, 0xfc, 0x3b, 0x12, + 0x62, 0x95, 0x28, 0xcf, 0xbb, 0x09, 0xfe, 0x63, 0x0f, 0x04, 0x74, + 0x33, 0x9f, 0x54, 0xab, 0xf4, 0x53, 0xe2, 0xed, 0x52})), + std::make_pair( + 8, + std::vector<uint8_t>( + {0x38, 0x0b, 0xea, 0xf6, 0xea, 0x7c, 0xc9, 0x36, 0x5e, 0x27, 0x0e, + 0xf0, 0xe6, 0xf3, 0xa6, 0x4f, 0xb9, 0x02, 0xac, 0xae, 0x51, 0xdd, + 0x55, 0x12, 0xf8, 0x42, 0x59, 0xad, 0x2c, 0x91, 0xf4, 0xbc, 0x41, + 0x08, 0xdb, 0x73, 0x19, 0x2a, 0x5b, 0xbf, 0xb0, 0xcb, 0xcf, 0x71, + 0xe4, 0x6c, 0x3e, 0x21, 0xae, 0xe1, 0xc5, 0xe8, 0x60, 0xdc, 0x96, + 0xe8, 0xeb, 0x0b, 0x7b, 0x84, 0x26, 0xe6, 0xab, 0xe9})), + std::make_pair( + 9, + std::vector<uint8_t>( + {0x60, 0xfe, 0x3c, 0x45, 0x35, 0xe1, 0xb5, 0x9d, 0x9a, 0x61, 0xea, + 0x85, 0x00, 0xbf, 0xac, 0x41, 0xa6, 0x9d, 0xff, 0xb1, 0xce, 0xad, + 0xd9, 0xac, 0xa3, 0x23, 0xe9, 0xa6, 0x25, 0xb6, 0x4d, 0xa5, 0x76, + 0x3b, 0xad, 0x72, 0x26, 0xda, 0x02, 0xb9, 0xc8, 0xc4, 0xf1, 0xa5, + 0xde, 0x14, 0x0a, 0xc5, 0xa6, 0xc1, 0x12, 0x4e, 0x4f, 0x71, 0x8c, + 0xe0, 0xb2, 0x8e, 0xa4, 0x73, 0x93, 0xaa, 0x66, 0x37})), + std::make_pair( + 10, + std::vector<uint8_t>( + {0x4f, 0xe1, 0x81, 0xf5, 0x4a, 0xd6, 0x3a, 0x29, 0x83, 0xfe, 0xaa, + 0xf7, 0x7d, 0x1e, 0x72, 0x35, 0xc2, 0xbe, 0xb1, 0x7f, 0xa3, 0x28, + 0xb6, 0xd9, 0x50, 0x5b, 0xda, 0x32, 0x7d, 0xf1, 0x9f, 0xc3, 0x7f, + 0x02, 0xc4, 0xb6, 0xf0, 0x36, 0x8c, 0xe2, 0x31, 0x47, 0x31, 0x3a, + 0x8e, 0x57, 0x38, 0xb5, 0xfa, 0x2a, 0x95, 0xb2, 0x9d, 0xe1, 0xc7, + 0xf8, 0x26, 0x4e, 0xb7, 0x7b, 0x69, 0xf5, 0x85, 0xcd})), + std::make_pair( + 11, + std::vector<uint8_t>( + {0xf2, 0x28, 0x77, 0x3c, 0xe3, 0xf3, 0xa4, 0x2b, 0x5f, 0x14, 0x4d, + 0x63, 0x23, 0x7a, 0x72, 0xd9, 0x96, 0x93, 0xad, 0xb8, 0x83, 0x7d, + 0x0e, 0x11, 0x2a, 0x8a, 0x0f, 0x8f, 0xff, 0xf2, 0xc3, 0x62, 0x85, + 0x7a, 0xc4, 0x9c, 0x11, 0xec, 0x74, 0x0d, 0x15, 0x00, 0x74, 0x9d, + 0xac, 0x9b, 0x1f, 0x45, 0x48, 0x10, 0x8b, 0xf3, 0x15, 0x57, 0x94, + 0xdc, 0xc9, 0xe4, 0x08, 0x28, 0x49, 0xe2, 0xb8, 0x5b})), + std::make_pair( + 12, + std::vector<uint8_t>( + {0x96, 0x24, 0x52, 0xa8, 0x45, 0x5c, 0xc5, 0x6c, 0x85, 0x11, 0x31, + 0x7e, 0x3b, 0x1f, 0x3b, 0x2c, 0x37, 0xdf, 0x75, 0xf5, 0x88, 0xe9, + 0x43, 0x25, 0xfd, 0xd7, 0x70, 0x70, 0x35, 0x9c, 0xf6, 0x3a, 0x9a, + 0xe6, 0xe9, 0x30, 0x93, 0x6f, 0xdf, 0x8e, 0x1e, 0x08, 0xff, 0xca, + 0x44, 0x0c, 0xfb, 0x72, 0xc2, 0x8f, 0x06, 0xd8, 0x9a, 0x21, 0x51, + 0xd1, 0xc4, 0x6c, 0xd5, 0xb2, 0x68, 0xef, 0x85, 0x63})), + std::make_pair( + 13, + std::vector<uint8_t>( + {0x43, 0xd4, 0x4b, 0xfa, 0x18, 0x76, 0x8c, 0x59, 0x89, 0x6b, 0xf7, + 0xed, 0x17, 0x65, 0xcb, 0x2d, 0x14, 0xaf, 0x8c, 0x26, 0x02, 0x66, + 0x03, 0x90, 0x99, 0xb2, 0x5a, 0x60, 0x3e, 0x4d, 0xdc, 0x50, 0x39, + 0xd6, 0xef, 0x3a, 0x91, 0x84, 0x7d, 0x10, 0x88, 0xd4, 0x01, 0xc0, + 0xc7, 0xe8, 0x47, 0x78, 0x1a, 0x8a, 0x59, 0x0d, 0x33, 0xa3, 0xc6, + 0xcb, 0x4d, 0xf0, 0xfa, 0xb1, 0xc2, 0xf2, 0x23, 0x55})), + std::make_pair( + 14, + std::vector<uint8_t>( + {0xdc, 0xff, 0xa9, 0xd5, 0x8c, 0x2a, 0x4c, 0xa2, 0xcd, 0xbb, 0x0c, + 0x7a, 0xa4, 0xc4, 0xc1, 0xd4, 0x51, 0x65, 0x19, 0x00, 0x89, 0xf4, + 0xe9, 0x83, 0xbb, 0x1c, 0x2c, 0xab, 0x4a, 0xae, 0xff, 0x1f, 0xa2, + 0xb5, 0xee, 0x51, 0x6f, 0xec, 0xd7, 0x80, 0x54, 0x02, 0x40, 0xbf, + 0x37, 0xe5, 0x6c, 0x8b, 0xcc, 0xa7, 0xfa, 0xb9, 0x80, 0xe1, 0xe6, + 0x1c, 0x94, 0x00, 0xd8, 0xa9, 0xa5, 0xb1, 0x4a, 0xc6})), + std::make_pair( + 15, + std::vector<uint8_t>( + {0x6f, 0xbf, 0x31, 0xb4, 0x5a, 0xb0, 0xc0, 0xb8, 0xda, 0xd1, 0xc0, + 0xf5, 0xf4, 0x06, 0x13, 0x79, 0x91, 0x2d, 0xde, 0x5a, 0xa9, 0x22, + 0x09, 0x9a, 0x03, 0x0b, 0x72, 0x5c, 0x73, 0x34, 0x6c, 0x52, 0x42, + 0x91, 0xad, 0xef, 0x89, 0xd2, 0xf6, 0xfd, 0x8d, 0xfc, 0xda, 0x6d, + 0x07, 0xda, 0xd8, 0x11, 0xa9, 0x31, 0x45, 0x36, 0xc2, 0x91, 0x5e, + 0xd4, 0x5d, 0xa3, 0x49, 0x47, 0xe8, 0x3d, 0xe3, 0x4e})), + std::make_pair( + 16, + std::vector<uint8_t>( + {0xa0, 0xc6, 0x5b, 0xdd, 0xde, 0x8a, 0xde, 0xf5, 0x72, 0x82, 0xb0, + 0x4b, 0x11, 0xe7, 0xbc, 0x8a, 0xab, 0x10, 0x5b, 0x99, 0x23, 0x1b, + 0x75, 0x0c, 0x02, 0x1f, 0x4a, 0x73, 0x5c, 0xb1, 0xbc, 0xfa, 0xb8, + 0x75, 0x53, 0xbb, 0xa3, 0xab, 0xb0, 0xc3, 0xe6, 0x4a, 0x0b, 0x69, + 0x55, 0x28, 0x51, 0x85, 0xa0, 0xbd, 0x35, 0xfb, 0x8c, 0xfd, 0xe5, + 0x57, 0x32, 0x9b, 0xeb, 0xb1, 0xf6, 0x29, 0xee, 0x93})), + std::make_pair( + 17, + std::vector<uint8_t>( + {0xf9, 0x9d, 0x81, 0x55, 0x50, 0x55, 0x8e, 0x81, 0xec, 0xa2, 0xf9, + 0x67, 0x18, 0xae, 0xd1, 0x0d, 0x86, 0xf3, 0xf1, 0xcf, 0xb6, 0x75, + 0xcc, 0xe0, 0x6b, 0x0e, 0xff, 0x02, 0xf6, 0x17, 0xc5, 0xa4, 0x2c, + 0x5a, 0xa7, 0x60, 0x27, 0x0f, 0x26, 0x79, 0xda, 0x26, 0x77, 0xc5, + 0xae, 0xb9, 0x4f, 0x11, 0x42, 0x27, 0x7f, 0x21, 0xc7, 0xf7, 0x9f, + 0x3c, 0x4f, 0x0c, 0xce, 0x4e, 0xd8, 0xee, 0x62, 0xb1})), + std::make_pair( + 18, + std::vector<uint8_t>( + {0x95, 0x39, 0x1d, 0xa8, 0xfc, 0x7b, 0x91, 0x7a, 0x20, 0x44, 0xb3, + 0xd6, 0xf5, 0x37, 0x4e, 0x1c, 0xa0, 0x72, 0xb4, 0x14, 0x54, 0xd5, + 0x72, 0xc7, 0x35, 0x6c, 0x05, 0xfd, 0x4b, 0xc1, 0xe0, 0xf4, 0x0b, + 0x8b, 0xb8, 0xb4, 0xa9, 0xf6, 0xbc, 0xe9, 0xbe, 0x2c, 0x46, 0x23, + 0xc3, 0x99, 0xb0, 0xdc, 0xa0, 0xda, 0xb0, 0x5c, 0xb7, 0x28, 0x1b, + 0x71, 0xa2, 0x1b, 0x0e, 0xbc, 0xd9, 0xe5, 0x56, 0x70})), + std::make_pair( + 19, + std::vector<uint8_t>( + {0x04, 0xb9, 0xcd, 0x3d, 0x20, 0xd2, 0x21, 0xc0, 0x9a, 0xc8, 0x69, + 0x13, 0xd3, 0xdc, 0x63, 0x04, 0x19, 0x89, 0xa9, 0xa1, 0xe6, 0x94, + 0xf1, 0xe6, 0x39, 0xa3, 0xba, 0x7e, 0x45, 0x18, 0x40, 0xf7, 0x50, + 0xc2, 0xfc, 0x19, 0x1d, 0x56, 0xad, 0x61, 0xf2, 0xe7, 0x93, 0x6b, + 0xc0, 0xac, 0x8e, 0x09, 0x4b, 0x60, 0xca, 0xee, 0xd8, 0x78, 0xc1, + 0x87, 0x99, 0x04, 0x54, 0x02, 0xd6, 0x1c, 0xea, 0xf9})), + std::make_pair( + 20, + std::vector<uint8_t>( + {0xec, 0x0e, 0x0e, 0xf7, 0x07, 0xe4, 0xed, 0x6c, 0x0c, 0x66, 0xf9, + 0xe0, 0x89, 0xe4, 0x95, 0x4b, 0x05, 0x80, 0x30, 0xd2, 0xdd, 0x86, + 0x39, 0x8f, 0xe8, 0x40, 0x59, 0x63, 0x1f, 0x9e, 0xe5, 0x91, 0xd9, + 0xd7, 0x73, 0x75, 0x35, 0x51, 0x49, 0x17, 0x8c, 0x0c, 0xf8, 0xf8, + 0xe7, 0xc4, 0x9e, 0xd2, 0xa5, 0xe4, 0xf9, 0x54, 0x88, 0xa2, 0x24, + 0x70, 0x67, 0xc2, 0x08, 0x51, 0x0f, 0xad, 0xc4, 0x4c})), + std::make_pair( + 21, + std::vector<uint8_t>( + {0x9a, 0x37, 0xcc, 0xe2, 0x73, 0xb7, 0x9c, 0x09, 0x91, 0x36, 0x77, + 0x51, 0x0e, 0xaf, 0x76, 0x88, 0xe8, 0x9b, 0x33, 0x14, 0xd3, 0x53, + 0x2f, 0xd2, 0x76, 0x4c, 0x39, 0xde, 0x02, 0x2a, 0x29, 0x45, 0xb5, + 0x71, 0x0d, 0x13, 0x51, 0x7a, 0xf8, 0xdd, 0xc0, 0x31, 0x66, 0x24, + 0xe7, 0x3b, 0xec, 0x1c, 0xe6, 0x7d, 0xf1, 0x52, 0x28, 0x30, 0x20, + 0x36, 0xf3, 0x30, 0xab, 0x0c, 0xb4, 0xd2, 0x18, 0xdd})), + std::make_pair( + 22, + std::vector<uint8_t>( + {0x4c, 0xf9, 0xbb, 0x8f, 0xb3, 0xd4, 0xde, 0x8b, 0x38, 0xb2, 0xf2, + 0x62, 0xd3, 0xc4, 0x0f, 0x46, 0xdf, 0xe7, 0x47, 0xe8, 0xfc, 0x0a, + 0x41, 0x4c, 0x19, 0x3d, 0x9f, 0xcf, 0x75, 0x31, 0x06, 0xce, 0x47, + 0xa1, 0x8f, 0x17, 0x2f, 0x12, 0xe8, 0xa2, 0xf1, 0xc2, 0x67, 0x26, + 0x54, 0x53, 0x58, 0xe5, 0xee, 0x28, 0xc9, 0xe2, 0x21, 0x3a, 0x87, + 0x87, 0xaa, 0xfb, 0xc5, 0x16, 0xd2, 0x34, 0x31, 0x52})), + std::make_pair( + 23, + std::vector<uint8_t>( + {0x64, 0xe0, 0xc6, 0x3a, 0xf9, 0xc8, 0x08, 0xfd, 0x89, 0x31, 0x37, + 0x12, 0x98, 0x67, 0xfd, 0x91, 0x93, 0x9d, 0x53, 0xf2, 0xaf, 0x04, + 0xbe, 0x4f, 0xa2, 0x68, 0x00, 0x61, 0x00, 0x06, 0x9b, 0x2d, 0x69, + 0xda, 0xa5, 0xc5, 0xd8, 0xed, 0x7f, 0xdd, 0xcb, 0x2a, 0x70, 0xee, + 0xec, 0xdf, 0x2b, 0x10, 0x5d, 0xd4, 0x6a, 0x1e, 0x3b, 0x73, 0x11, + 0x72, 0x8f, 0x63, 0x9a, 0xb4, 0x89, 0x32, 0x6b, 0xc9})), + std::make_pair( + 24, + std::vector<uint8_t>( + {0x5e, 0x9c, 0x93, 0x15, 0x8d, 0x65, 0x9b, 0x2d, 0xef, 0x06, 0xb0, + 0xc3, 0xc7, 0x56, 0x50, 0x45, 0x54, 0x26, 0x62, 0xd6, 0xee, 0xe8, + 0xa9, 0x6a, 0x89, 0xb7, 0x8a, 0xde, 0x09, 0xfe, 0x8b, 0x3d, 0xcc, + 0x09, 0x6d, 0x4f, 0xe4, 0x88, 0x15, 0xd8, 0x8d, 0x8f, 0x82, 0x62, + 0x01, 0x56, 0x60, 0x2a, 0xf5, 0x41, 0x95, 0x5e, 0x1f, 0x6c, 0xa3, + 0x0d, 0xce, 0x14, 0xe2, 0x54, 0xc3, 0x26, 0xb8, 0x8f})), + std::make_pair( + 25, + std::vector<uint8_t>( + {0x77, 0x75, 0xdf, 0xf8, 0x89, 0x45, 0x8d, 0xd1, 0x1a, 0xef, 0x41, + 0x72, 0x76, 0x85, 0x3e, 0x21, 0x33, 0x5e, 0xb8, 0x8e, 0x4d, 0xec, + 0x9c, 0xfb, 0x4e, 0x9e, 0xdb, 0x49, 0x82, 0x00, 0x88, 0x55, 0x1a, + 0x2c, 0xa6, 0x03, 0x39, 0xf1, 0x20, 0x66, 0x10, 0x11, 0x69, 0xf0, + 0xdf, 0xe8, 0x4b, 0x09, 0x8f, 0xdd, 0xb1, 0x48, 0xd9, 0xda, 0x6b, + 0x3d, 0x61, 0x3d, 0xf2, 0x63, 0x88, 0x9a, 0xd6, 0x4b})), + std::make_pair( + 26, + std::vector<uint8_t>( + {0xf0, 0xd2, 0x80, 0x5a, 0xfb, 0xb9, 0x1f, 0x74, 0x39, 0x51, 0x35, + 0x1a, 0x6d, 0x02, 0x4f, 0x93, 0x53, 0xa2, 0x3c, 0x7c, 0xe1, 0xfc, + 0x2b, 0x05, 0x1b, 0x3a, 0x8b, 0x96, 0x8c, 0x23, 0x3f, 0x46, 0xf5, + 0x0f, 0x80, 0x6e, 0xcb, 0x15, 0x68, 0xff, 0xaa, 0x0b, 0x60, 0x66, + 0x1e, 0x33, 0x4b, 0x21, 0xdd, 0xe0, 0x4f, 0x8f, 0xa1, 0x55, 0xac, + 0x74, 0x0e, 0xeb, 0x42, 0xe2, 0x0b, 0x60, 0xd7, 0x64})), + std::make_pair( + 27, + std::vector<uint8_t>( + {0x86, 0xa2, 0xaf, 0x31, 0x6e, 0x7d, 0x77, 0x54, 0x20, 0x1b, 0x94, + 0x2e, 0x27, 0x53, 0x64, 0xac, 0x12, 0xea, 0x89, 0x62, 0xab, 0x5b, + 0xd8, 0xd7, 0xfb, 0x27, 0x6d, 0xc5, 0xfb, 0xff, 0xc8, 0xf9, 0xa2, + 0x8c, 0xae, 0x4e, 0x48, 0x67, 0xdf, 0x67, 0x80, 0xd9, 0xb7, 0x25, + 0x24, 0x16, 0x09, 0x27, 0xc8, 0x55, 0xda, 0x5b, 0x60, 0x78, 0xe0, + 0xb5, 0x54, 0xaa, 0x91, 0xe3, 0x1c, 0xb9, 0xca, 0x1d})), + std::make_pair( + 28, + std::vector<uint8_t>( + {0x10, 0xbd, 0xf0, 0xca, 0xa0, 0x80, 0x27, 0x05, 0xe7, 0x06, 0x36, + 0x9b, 0xaf, 0x8a, 0x3f, 0x79, 0xd7, 0x2c, 0x0a, 0x03, 0xa8, 0x06, + 0x75, 0xa7, 0xbb, 0xb0, 0x0b, 0xe3, 0xa4, 0x5e, 0x51, 0x64, 0x24, + 0xd1, 0xee, 0x88, 0xef, 0xb5, 0x6f, 0x6d, 0x57, 0x77, 0x54, 0x5a, + 0xe6, 0xe2, 0x77, 0x65, 0xc3, 0xa8, 0xf5, 0xe4, 0x93, 0xfc, 0x30, + 0x89, 0x15, 0x63, 0x89, 0x33, 0xa1, 0xdf, 0xee, 0x55})), + std::make_pair( + 29, + std::vector<uint8_t>( + {0xb0, 0x17, 0x81, 0x09, 0x2b, 0x17, 0x48, 0x45, 0x9e, 0x2e, 0x4e, + 0xc1, 0x78, 0x69, 0x66, 0x27, 0xbf, 0x4e, 0xba, 0xfe, 0xbb, 0xa7, + 0x74, 0xec, 0xf0, 0x18, 0xb7, 0x9a, 0x68, 0xae, 0xb8, 0x49, 0x17, + 0xbf, 0x0b, 0x84, 0xbb, 0x79, 0xd1, 0x7b, 0x74, 0x31, 0x51, 0x14, + 0x4c, 0xd6, 0x6b, 0x7b, 0x33, 0xa4, 0xb9, 0xe5, 0x2c, 0x76, 0xc4, + 0xe1, 0x12, 0x05, 0x0f, 0xf5, 0x38, 0x5b, 0x7f, 0x0b})), + std::make_pair( + 30, + std::vector<uint8_t>( + {0xc6, 0xdb, 0xc6, 0x1d, 0xec, 0x6e, 0xae, 0xac, 0x81, 0xe3, 0xd5, + 0xf7, 0x55, 0x20, 0x3c, 0x8e, 0x22, 0x05, 0x51, 0x53, 0x4a, 0x0b, + 0x2f, 0xd1, 0x05, 0xa9, 0x18, 0x89, 0x94, 0x5a, 0x63, 0x85, 0x50, + 0x20, 0x4f, 0x44, 0x09, 0x3d, 0xd9, 0x98, 0xc0, 0x76, 0x20, 0x5d, + 0xff, 0xad, 0x70, 0x3a, 0x0e, 0x5c, 0xd3, 0xc7, 0xf4, 0x38, 0xa7, + 0xe6, 0x34, 0xcd, 0x59, 0xfe, 0xde, 0xdb, 0x53, 0x9e})), + std::make_pair( + 31, + std::vector<uint8_t>( + {0xeb, 0xa5, 0x1a, 0xcf, 0xfb, 0x4c, 0xea, 0x31, 0xdb, 0x4b, 0x8d, + 0x87, 0xe9, 0xbf, 0x7d, 0xd4, 0x8f, 0xe9, 0x7b, 0x02, 0x53, 0xae, + 0x67, 0xaa, 0x58, 0x0f, 0x9a, 0xc4, 0xa9, 0xd9, 0x41, 0xf2, 0xbe, + 0xa5, 0x18, 0xee, 0x28, 0x68, 0x18, 0xcc, 0x9f, 0x63, 0x3f, 0x2a, + 0x3b, 0x9f, 0xb6, 0x8e, 0x59, 0x4b, 0x48, 0xcd, 0xd6, 0xd5, 0x15, + 0xbf, 0x1d, 0x52, 0xba, 0x6c, 0x85, 0xa2, 0x03, 0xa7})), + std::make_pair( + 32, + std::vector<uint8_t>( + {0x86, 0x22, 0x1f, 0x3a, 0xda, 0x52, 0x03, 0x7b, 0x72, 0x22, 0x4f, + 0x10, 0x5d, 0x79, 0x99, 0x23, 0x1c, 0x5e, 0x55, 0x34, 0xd0, 0x3d, + 0xa9, 0xd9, 0xc0, 0xa1, 0x2a, 0xcb, 0x68, 0x46, 0x0c, 0xd3, 0x75, + 0xda, 0xf8, 0xe2, 0x43, 0x86, 0x28, 0x6f, 0x96, 0x68, 0xf7, 0x23, + 0x26, 0xdb, 0xf9, 0x9b, 0xa0, 0x94, 0x39, 0x24, 0x37, 0xd3, 0x98, + 0xe9, 0x5b, 0xb8, 0x16, 0x1d, 0x71, 0x7f, 0x89, 0x91})), + std::make_pair( + 33, + std::vector<uint8_t>( + {0x55, 0x95, 0xe0, 0x5c, 0x13, 0xa7, 0xec, 0x4d, 0xc8, 0xf4, 0x1f, + 0xb7, 0x0c, 0xb5, 0x0a, 0x71, 0xbc, 0xe1, 0x7c, 0x02, 0x4f, 0xf6, + 0xde, 0x7a, 0xf6, 0x18, 0xd0, 0xcc, 0x4e, 0x9c, 0x32, 0xd9, 0x57, + 0x0d, 0x6d, 0x3e, 0xa4, 0x5b, 0x86, 0x52, 0x54, 0x91, 0x03, 0x0c, + 0x0d, 0x8f, 0x2b, 0x18, 0x36, 0xd5, 0x77, 0x8c, 0x1c, 0xe7, 0x35, + 0xc1, 0x77, 0x07, 0xdf, 0x36, 0x4d, 0x05, 0x43, 0x47})), + std::make_pair( + 34, + std::vector<uint8_t>( + {0xce, 0x0f, 0x4f, 0x6a, 0xca, 0x89, 0x59, 0x0a, 0x37, 0xfe, 0x03, + 0x4d, 0xd7, 0x4d, 0xd5, 0xfa, 0x65, 0xeb, 0x1c, 0xbd, 0x0a, 0x41, + 0x50, 0x8a, 0xad, 0xdc, 0x09, 0x35, 0x1a, 0x3c, 0xea, 0x6d, 0x18, + 0xcb, 0x21, 0x89, 0xc5, 0x4b, 0x70, 0x0c, 0x00, 0x9f, 0x4c, 0xbf, + 0x05, 0x21, 0xc7, 0xea, 0x01, 0xbe, 0x61, 0xc5, 0xae, 0x09, 0xcb, + 0x54, 0xf2, 0x7b, 0xc1, 0xb4, 0x4d, 0x65, 0x8c, 0x82})), + std::make_pair( + 35, + std::vector<uint8_t>( + {0x7e, 0xe8, 0x0b, 0x06, 0xa2, 0x15, 0xa3, 0xbc, 0xa9, 0x70, 0xc7, + 0x7c, 0xda, 0x87, 0x61, 0x82, 0x2b, 0xc1, 0x03, 0xd4, 0x4f, 0xa4, + 0xb3, 0x3f, 0x4d, 0x07, 0xdc, 0xb9, 0x97, 0xe3, 0x6d, 0x55, 0x29, + 0x8b, 0xce, 0xae, 0x12, 0x24, 0x1b, 0x3f, 0xa0, 0x7f, 0xa6, 0x3b, + 0xe5, 0x57, 0x60, 0x68, 0xda, 0x38, 0x7b, 0x8d, 0x58, 0x59, 0xae, + 0xab, 0x70, 0x13, 0x69, 0x84, 0x8b, 0x17, 0x6d, 0x42})), + std::make_pair( + 36, + std::vector<uint8_t>( + {0x94, 0x0a, 0x84, 0xb6, 0xa8, 0x4d, 0x10, 0x9a, 0xab, 0x20, 0x8c, + 0x02, 0x4c, 0x6c, 0xe9, 0x64, 0x76, 0x76, 0xba, 0x0a, 0xaa, 0x11, + 0xf8, 0x6d, 0xbb, 0x70, 0x18, 0xf9, 0xfd, 0x22, 0x20, 0xa6, 0xd9, + 0x01, 0xa9, 0x02, 0x7f, 0x9a, 0xbc, 0xf9, 0x35, 0x37, 0x27, 0x27, + 0xcb, 0xf0, 0x9e, 0xbd, 0x61, 0xa2, 0xa2, 0xee, 0xb8, 0x76, 0x53, + 0xe8, 0xec, 0xad, 0x1b, 0xab, 0x85, 0xdc, 0x83, 0x27})), + std::make_pair( + 37, + std::vector<uint8_t>( + {0x20, 0x20, 0xb7, 0x82, 0x64, 0xa8, 0x2d, 0x9f, 0x41, 0x51, 0x14, + 0x1a, 0xdb, 0xa8, 0xd4, 0x4b, 0xf2, 0x0c, 0x5e, 0xc0, 0x62, 0xee, + 0xe9, 0xb5, 0x95, 0xa1, 0x1f, 0x9e, 0x84, 0x90, 0x1b, 0xf1, 0x48, + 0xf2, 0x98, 0xe0, 0xc9, 0xf8, 0x77, 0x7d, 0xcd, 0xbc, 0x7c, 0xc4, + 0x67, 0x0a, 0xac, 0x35, 0x6c, 0xc2, 0xad, 0x8c, 0xcb, 0x16, 0x29, + 0xf1, 0x6f, 0x6a, 0x76, 0xbc, 0xef, 0xbe, 0xe7, 0x60})), + std::make_pair( + 38, + std::vector<uint8_t>( + {0xd1, 0xb8, 0x97, 0xb0, 0xe0, 0x75, 0xba, 0x68, 0xab, 0x57, 0x2a, + 0xdf, 0x9d, 0x9c, 0x43, 0x66, 0x63, 0xe4, 0x3e, 0xb3, 0xd8, 0xe6, + 0x2d, 0x92, 0xfc, 0x49, 0xc9, 0xbe, 0x21, 0x4e, 0x6f, 0x27, 0x87, + 0x3f, 0xe2, 0x15, 0xa6, 0x51, 0x70, 0xe6, 0xbe, 0xa9, 0x02, 0x40, + 0x8a, 0x25, 0xb4, 0x95, 0x06, 0xf4, 0x7b, 0xab, 0xd0, 0x7c, 0xec, + 0xf7, 0x11, 0x3e, 0xc1, 0x0c, 0x5d, 0xd3, 0x12, 0x52})), + std::make_pair( + 39, + std::vector<uint8_t>( + {0xb1, 0x4d, 0x0c, 0x62, 0xab, 0xfa, 0x46, 0x9a, 0x35, 0x71, 0x77, + 0xe5, 0x94, 0xc1, 0x0c, 0x19, 0x42, 0x43, 0xed, 0x20, 0x25, 0xab, + 0x8a, 0xa5, 0xad, 0x2f, 0xa4, 0x1a, 0xd3, 0x18, 0xe0, 0xff, 0x48, + 0xcd, 0x5e, 0x60, 0xbe, 0xc0, 0x7b, 0x13, 0x63, 0x4a, 0x71, 0x1d, + 0x23, 0x26, 0xe4, 0x88, 0xa9, 0x85, 0xf3, 0x1e, 0x31, 0x15, 0x33, + 0x99, 0xe7, 0x30, 0x88, 0xef, 0xc8, 0x6a, 0x5c, 0x55})), + std::make_pair( + 40, + std::vector<uint8_t>( + {0x41, 0x69, 0xc5, 0xcc, 0x80, 0x8d, 0x26, 0x97, 0xdc, 0x2a, 0x82, + 0x43, 0x0d, 0xc2, 0x3e, 0x3c, 0xd3, 0x56, 0xdc, 0x70, 0xa9, 0x45, + 0x66, 0x81, 0x05, 0x02, 0xb8, 0xd6, 0x55, 0xb3, 0x9a, 0xbf, 0x9e, + 0x7f, 0x90, 0x2f, 0xe7, 0x17, 0xe0, 0x38, 0x92, 0x19, 0x85, 0x9e, + 0x19, 0x45, 0xdf, 0x1a, 0xf6, 0xad, 0xa4, 0x2e, 0x4c, 0xcd, 0xa5, + 0x5a, 0x19, 0x7b, 0x71, 0x00, 0xa3, 0x0c, 0x30, 0xa1})), + std::make_pair( + 41, + std::vector<uint8_t>( + {0x25, 0x8a, 0x4e, 0xdb, 0x11, 0x3d, 0x66, 0xc8, 0x39, 0xc8, 0xb1, + 0xc9, 0x1f, 0x15, 0xf3, 0x5a, 0xde, 0x60, 0x9f, 0x11, 0xcd, 0x7f, + 0x86, 0x81, 0xa4, 0x04, 0x5b, 0x9f, 0xef, 0x7b, 0x0b, 0x24, 0xc8, + 0x2c, 0xda, 0x06, 0xa5, 0xf2, 0x06, 0x7b, 0x36, 0x88, 0x25, 0xe3, + 0x91, 0x4e, 0x53, 0xd6, 0x94, 0x8e, 0xde, 0x92, 0xef, 0xd6, 0xe8, + 0x38, 0x7f, 0xa2, 0xe5, 0x37, 0x23, 0x9b, 0x5b, 0xee})), + std::make_pair( + 42, + std::vector<uint8_t>( + {0x79, 0xd2, 0xd8, 0x69, 0x6d, 0x30, 0xf3, 0x0f, 0xb3, 0x46, 0x57, + 0x76, 0x11, 0x71, 0xa1, 0x1e, 0x6c, 0x3f, 0x1e, 0x64, 0xcb, 0xe7, + 0xbe, 0xbe, 0xe1, 0x59, 0xcb, 0x95, 0xbf, 0xaf, 0x81, 0x2b, 0x4f, + 0x41, 0x1e, 0x2f, 0x26, 0xd9, 0xc4, 0x21, 0xdc, 0x2c, 0x28, 0x4a, + 0x33, 0x42, 0xd8, 0x23, 0xec, 0x29, 0x38, 0x49, 0xe4, 0x2d, 0x1e, + 0x46, 0xb0, 0xa4, 0xac, 0x1e, 0x3c, 0x86, 0xab, 0xaa})), + std::make_pair( + 43, + std::vector<uint8_t>( + {0x8b, 0x94, 0x36, 0x01, 0x0d, 0xc5, 0xde, 0xe9, 0x92, 0xae, 0x38, + 0xae, 0xa9, 0x7f, 0x2c, 0xd6, 0x3b, 0x94, 0x6d, 0x94, 0xfe, 0xdd, + 0x2e, 0xc9, 0x67, 0x1d, 0xcd, 0xe3, 0xbd, 0x4c, 0xe9, 0x56, 0x4d, + 0x55, 0x5c, 0x66, 0xc1, 0x5b, 0xb2, 0xb9, 0x00, 0xdf, 0x72, 0xed, + 0xb6, 0xb8, 0x91, 0xeb, 0xca, 0xdf, 0xef, 0xf6, 0x3c, 0x9e, 0xa4, + 0x03, 0x6a, 0x99, 0x8b, 0xe7, 0x97, 0x39, 0x81, 0xe7})), + std::make_pair( + 44, + std::vector<uint8_t>( + {0xc8, 0xf6, 0x8e, 0x69, 0x6e, 0xd2, 0x82, 0x42, 0xbf, 0x99, 0x7f, + 0x5b, 0x3b, 0x34, 0x95, 0x95, 0x08, 0xe4, 0x2d, 0x61, 0x38, 0x10, + 0xf1, 0xe2, 0xa4, 0x35, 0xc9, 0x6e, 0xd2, 0xff, 0x56, 0x0c, 0x70, + 0x22, 0xf3, 0x61, 0xa9, 0x23, 0x4b, 0x98, 0x37, 0xfe, 0xee, 0x90, + 0xbf, 0x47, 0x92, 0x2e, 0xe0, 0xfd, 0x5f, 0x8d, 0xdf, 0x82, 0x37, + 0x18, 0xd8, 0x6d, 0x1e, 0x16, 0xc6, 0x09, 0x00, 0x71})), + std::make_pair( + 45, + std::vector<uint8_t>( + {0xb0, 0x2d, 0x3e, 0xee, 0x48, 0x60, 0xd5, 0x86, 0x8b, 0x2c, 0x39, + 0xce, 0x39, 0xbf, 0xe8, 0x10, 0x11, 0x29, 0x05, 0x64, 0xdd, 0x67, + 0x8c, 0x85, 0xe8, 0x78, 0x3f, 0x29, 0x30, 0x2d, 0xfc, 0x13, 0x99, + 0xba, 0x95, 0xb6, 0xb5, 0x3c, 0xd9, 0xeb, 0xbf, 0x40, 0x0c, 0xca, + 0x1d, 0xb0, 0xab, 0x67, 0xe1, 0x9a, 0x32, 0x5f, 0x2d, 0x11, 0x58, + 0x12, 0xd2, 0x5d, 0x00, 0x97, 0x8a, 0xd1, 0xbc, 0xa4})), + std::make_pair( + 46, + std::vector<uint8_t>( + {0x76, 0x93, 0xea, 0x73, 0xaf, 0x3a, 0xc4, 0xda, 0xd2, 0x1c, 0xa0, + 0xd8, 0xda, 0x85, 0xb3, 0x11, 0x8a, 0x7d, 0x1c, 0x60, 0x24, 0xcf, + 0xaf, 0x55, 0x76, 0x99, 0x86, 0x82, 0x17, 0xbc, 0x0c, 0x2f, 0x44, + 0xa1, 0x99, 0xbc, 0x6c, 0x0e, 0xdd, 0x51, 0x97, 0x98, 0xba, 0x05, + 0xbd, 0x5b, 0x1b, 0x44, 0x84, 0x34, 0x6a, 0x47, 0xc2, 0xca, 0xdf, + 0x6b, 0xf3, 0x0b, 0x78, 0x5c, 0xc8, 0x8b, 0x2b, 0xaf})), + std::make_pair( + 47, + std::vector<uint8_t>( + {0xa0, 0xe5, 0xc1, 0xc0, 0x03, 0x1c, 0x02, 0xe4, 0x8b, 0x7f, 0x09, + 0xa5, 0xe8, 0x96, 0xee, 0x9a, 0xef, 0x2f, 0x17, 0xfc, 0x9e, 0x18, + 0xe9, 0x97, 0xd7, 0xf6, 0xca, 0xc7, 0xae, 0x31, 0x64, 0x22, 0xc2, + 0xb1, 0xe7, 0x79, 0x84, 0xe5, 0xf3, 0xa7, 0x3c, 0xb4, 0x5d, 0xee, + 0xd5, 0xd3, 0xf8, 0x46, 0x00, 0x10, 0x5e, 0x6e, 0xe3, 0x8f, 0x2d, + 0x09, 0x0c, 0x7d, 0x04, 0x42, 0xea, 0x34, 0xc4, 0x6d})), + std::make_pair( + 48, + std::vector<uint8_t>( + {0x41, 0xda, 0xa6, 0xad, 0xcf, 0xdb, 0x69, 0xf1, 0x44, 0x0c, 0x37, + 0xb5, 0x96, 0x44, 0x01, 0x65, 0xc1, 0x5a, 0xda, 0x59, 0x68, 0x13, + 0xe2, 0xe2, 0x2f, 0x06, 0x0f, 0xcd, 0x55, 0x1f, 0x24, 0xde, 0xe8, + 0xe0, 0x4b, 0xa6, 0x89, 0x03, 0x87, 0x88, 0x6c, 0xee, 0xc4, 0xa7, + 0xa0, 0xd7, 0xfc, 0x6b, 0x44, 0x50, 0x63, 0x92, 0xec, 0x38, 0x22, + 0xc0, 0xd8, 0xc1, 0xac, 0xfc, 0x7d, 0x5a, 0xeb, 0xe8})), + std::make_pair( + 49, + std::vector<uint8_t>( + {0x14, 0xd4, 0xd4, 0x0d, 0x59, 0x84, 0xd8, 0x4c, 0x5c, 0xf7, 0x52, + 0x3b, 0x77, 0x98, 0xb2, 0x54, 0xe2, 0x75, 0xa3, 0xa8, 0xcc, 0x0a, + 0x1b, 0xd0, 0x6e, 0xbc, 0x0b, 0xee, 0x72, 0x68, 0x56, 0xac, 0xc3, + 0xcb, 0xf5, 0x16, 0xff, 0x66, 0x7c, 0xda, 0x20, 0x58, 0xad, 0x5c, + 0x34, 0x12, 0x25, 0x44, 0x60, 0xa8, 0x2c, 0x92, 0x18, 0x70, 0x41, + 0x36, 0x3c, 0xc7, 0x7a, 0x4d, 0xc2, 0x15, 0xe4, 0x87})), + std::make_pair( + 50, + std::vector<uint8_t>( + {0xd0, 0xe7, 0xa1, 0xe2, 0xb9, 0xa4, 0x47, 0xfe, 0xe8, 0x3e, 0x22, + 0x77, 0xe9, 0xff, 0x80, 0x10, 0xc2, 0xf3, 0x75, 0xae, 0x12, 0xfa, + 0x7a, 0xaa, 0x8c, 0xa5, 0xa6, 0x31, 0x78, 0x68, 0xa2, 0x6a, 0x36, + 0x7a, 0x0b, 0x69, 0xfb, 0xc1, 0xcf, 0x32, 0xa5, 0x5d, 0x34, 0xeb, + 0x37, 0x06, 0x63, 0x01, 0x6f, 0x3d, 0x21, 0x10, 0x23, 0x0e, 0xba, + 0x75, 0x40, 0x28, 0xa5, 0x6f, 0x54, 0xac, 0xf5, 0x7c})), + std::make_pair( + 51, + std::vector<uint8_t>( + {0xe7, 0x71, 0xaa, 0x8d, 0xb5, 0xa3, 0xe0, 0x43, 0xe8, 0x17, 0x8f, + 0x39, 0xa0, 0x85, 0x7b, 0xa0, 0x4a, 0x3f, 0x18, 0xe4, 0xaa, 0x05, + 0x74, 0x3c, 0xf8, 0xd2, 0x22, 0xb0, 0xb0, 0x95, 0x82, 0x53, 0x50, + 0xba, 0x42, 0x2f, 0x63, 0x38, 0x2a, 0x23, 0xd9, 0x2e, 0x41, 0x49, + 0x07, 0x4e, 0x81, 0x6a, 0x36, 0xc1, 0xcd, 0x28, 0x28, 0x4d, 0x14, + 0x62, 0x67, 0x94, 0x0b, 0x31, 0xf8, 0x81, 0x8e, 0xa2})), + std::make_pair( + 52, + std::vector<uint8_t>( + {0xfe, 0xb4, 0xfd, 0x6f, 0x9e, 0x87, 0xa5, 0x6b, 0xef, 0x39, 0x8b, + 0x32, 0x84, 0xd2, 0xbd, 0xa5, 0xb5, 0xb0, 0xe1, 0x66, 0x58, 0x3a, + 0x66, 0xb6, 0x1e, 0x53, 0x84, 0x57, 0xff, 0x05, 0x84, 0x87, 0x2c, + 0x21, 0xa3, 0x29, 0x62, 0xb9, 0x92, 0x8f, 0xfa, 0xb5, 0x8d, 0xe4, + 0xaf, 0x2e, 0xdd, 0x4e, 0x15, 0xd8, 0xb3, 0x55, 0x70, 0x52, 0x32, + 0x07, 0xff, 0x4e, 0x2a, 0x5a, 0xa7, 0x75, 0x4c, 0xaa})), + std::make_pair( + 53, + std::vector<uint8_t>( + {0x46, 0x2f, 0x17, 0xbf, 0x00, 0x5f, 0xb1, 0xc1, 0xb9, 0xe6, 0x71, + 0x77, 0x9f, 0x66, 0x52, 0x09, 0xec, 0x28, 0x73, 0xe3, 0xe4, 0x11, + 0xf9, 0x8d, 0xab, 0xf2, 0x40, 0xa1, 0xd5, 0xec, 0x3f, 0x95, 0xce, + 0x67, 0x96, 0xb6, 0xfc, 0x23, 0xfe, 0x17, 0x19, 0x03, 0xb5, 0x02, + 0x02, 0x34, 0x67, 0xde, 0xc7, 0x27, 0x3f, 0xf7, 0x48, 0x79, 0xb9, + 0x29, 0x67, 0xa2, 0xa4, 0x3a, 0x5a, 0x18, 0x3d, 0x33})), + std::make_pair( + 54, + std::vector<uint8_t>( + {0xd3, 0x33, 0x81, 0x93, 0xb6, 0x45, 0x53, 0xdb, 0xd3, 0x8d, 0x14, + 0x4b, 0xea, 0x71, 0xc5, 0x91, 0x5b, 0xb1, 0x10, 0xe2, 0xd8, 0x81, + 0x80, 0xdb, 0xc5, 0xdb, 0x36, 0x4f, 0xd6, 0x17, 0x1d, 0xf3, 0x17, + 0xfc, 0x72, 0x68, 0x83, 0x1b, 0x5a, 0xef, 0x75, 0xe4, 0x34, 0x2b, + 0x2f, 0xad, 0x87, 0x97, 0xba, 0x39, 0xed, 0xdc, 0xef, 0x80, 0xe6, + 0xec, 0x08, 0x15, 0x93, 0x50, 0xb1, 0xad, 0x69, 0x6d})), + std::make_pair( + 55, + std::vector<uint8_t>( + {0xe1, 0x59, 0x0d, 0x58, 0x5a, 0x3d, 0x39, 0xf7, 0xcb, 0x59, 0x9a, + 0xbd, 0x47, 0x90, 0x70, 0x96, 0x64, 0x09, 0xa6, 0x84, 0x6d, 0x43, + 0x77, 0xac, 0xf4, 0x47, 0x1d, 0x06, 0x5d, 0x5d, 0xb9, 0x41, 0x29, + 0xcc, 0x9b, 0xe9, 0x25, 0x73, 0xb0, 0x5e, 0xd2, 0x26, 0xbe, 0x1e, + 0x9b, 0x7c, 0xb0, 0xca, 0xbe, 0x87, 0x91, 0x85, 0x89, 0xf8, 0x0d, + 0xad, 0xd4, 0xef, 0x5e, 0xf2, 0x5a, 0x93, 0xd2, 0x8e})), + std::make_pair( + 56, + std::vector<uint8_t>( + {0xf8, 0xf3, 0x72, 0x6a, 0xc5, 0xa2, 0x6c, 0xc8, 0x01, 0x32, 0x49, + 0x3a, 0x6f, 0xed, 0xcb, 0x0e, 0x60, 0x76, 0x0c, 0x09, 0xcf, 0xc8, + 0x4c, 0xad, 0x17, 0x81, 0x75, 0x98, 0x68, 0x19, 0x66, 0x5e, 0x76, + 0x84, 0x2d, 0x7b, 0x9f, 0xed, 0xf7, 0x6d, 0xdd, 0xeb, 0xf5, 0xd3, + 0xf5, 0x6f, 0xaa, 0xad, 0x44, 0x77, 0x58, 0x7a, 0xf2, 0x16, 0x06, + 0xd3, 0x96, 0xae, 0x57, 0x0d, 0x8e, 0x71, 0x9a, 0xf2})), + std::make_pair( + 57, + std::vector<uint8_t>( + {0x30, 0x18, 0x60, 0x55, 0xc0, 0x79, 0x49, 0x94, 0x81, 0x83, 0xc8, + 0x50, 0xe9, 0xa7, 0x56, 0xcc, 0x09, 0x93, 0x7e, 0x24, 0x7d, 0x9d, + 0x92, 0x8e, 0x86, 0x9e, 0x20, 0xba, 0xfc, 0x3c, 0xd9, 0x72, 0x17, + 0x19, 0xd3, 0x4e, 0x04, 0xa0, 0x89, 0x9b, 0x92, 0xc7, 0x36, 0x08, + 0x45, 0x50, 0x18, 0x68, 0x86, 0xef, 0xba, 0x2e, 0x79, 0x0d, 0x8b, + 0xe6, 0xeb, 0xf0, 0x40, 0xb2, 0x09, 0xc4, 0x39, 0xa4})), + std::make_pair( + 58, + std::vector<uint8_t>( + {0xf3, 0xc4, 0x27, 0x6c, 0xb8, 0x63, 0x63, 0x77, 0x12, 0xc2, 0x41, + 0xc4, 0x44, 0xc5, 0xcc, 0x1e, 0x35, 0x54, 0xe0, 0xfd, 0xdb, 0x17, + 0x4d, 0x03, 0x58, 0x19, 0xdd, 0x83, 0xeb, 0x70, 0x0b, 0x4c, 0xe8, + 0x8d, 0xf3, 0xab, 0x38, 0x41, 0xba, 0x02, 0x08, 0x5e, 0x1a, 0x99, + 0xb4, 0xe1, 0x73, 0x10, 0xc5, 0x34, 0x10, 0x75, 0xc0, 0x45, 0x8b, + 0xa3, 0x76, 0xc9, 0x5a, 0x68, 0x18, 0xfb, 0xb3, 0xe2})), + std::make_pair( + 59, + std::vector<uint8_t>( + {0x0a, 0xa0, 0x07, 0xc4, 0xdd, 0x9d, 0x58, 0x32, 0x39, 0x30, 0x40, + 0xa1, 0x58, 0x3c, 0x93, 0x0b, 0xca, 0x7d, 0xc5, 0xe7, 0x7e, 0xa5, + 0x3a, 0xdd, 0x7e, 0x2b, 0x3f, 0x7c, 0x8e, 0x23, 0x13, 0x68, 0x04, + 0x35, 0x20, 0xd4, 0xa3, 0xef, 0x53, 0xc9, 0x69, 0xb6, 0xbb, 0xfd, + 0x02, 0x59, 0x46, 0xf6, 0x32, 0xbd, 0x7f, 0x76, 0x5d, 0x53, 0xc2, + 0x10, 0x03, 0xb8, 0xf9, 0x83, 0xf7, 0x5e, 0x2a, 0x6a})), + std::make_pair( + 60, + std::vector<uint8_t>( + {0x08, 0xe9, 0x46, 0x47, 0x20, 0x53, 0x3b, 0x23, 0xa0, 0x4e, 0xc2, + 0x4f, 0x7a, 0xe8, 0xc1, 0x03, 0x14, 0x5f, 0x76, 0x53, 0x87, 0xd7, + 0x38, 0x77, 0x7d, 0x3d, 0x34, 0x34, 0x77, 0xfd, 0x1c, 0x58, 0xdb, + 0x05, 0x21, 0x42, 0xca, 0xb7, 0x54, 0xea, 0x67, 0x43, 0x78, 0xe1, + 0x87, 0x66, 0xc5, 0x35, 0x42, 0xf7, 0x19, 0x70, 0x17, 0x1c, 0xc4, + 0xf8, 0x16, 0x94, 0x24, 0x6b, 0x71, 0x7d, 0x75, 0x64})), + std::make_pair( + 61, + std::vector<uint8_t>( + {0xd3, 0x7f, 0xf7, 0xad, 0x29, 0x79, 0x93, 0xe7, 0xec, 0x21, 0xe0, + 0xf1, 0xb4, 0xb5, 0xae, 0x71, 0x9c, 0xdc, 0x83, 0xc5, 0xdb, 0x68, + 0x75, 0x27, 0xf2, 0x75, 0x16, 0xcb, 0xff, 0xa8, 0x22, 0x88, 0x8a, + 0x68, 0x10, 0xee, 0x5c, 0x1c, 0xa7, 0xbf, 0xe3, 0x32, 0x11, 0x19, + 0xbe, 0x1a, 0xb7, 0xbf, 0xa0, 0xa5, 0x02, 0x67, 0x1c, 0x83, 0x29, + 0x49, 0x4d, 0xf7, 0xad, 0x6f, 0x52, 0x2d, 0x44, 0x0f})), + std::make_pair( + 62, + std::vector<uint8_t>( + {0xdd, 0x90, 0x42, 0xf6, 0xe4, 0x64, 0xdc, 0xf8, 0x6b, 0x12, 0x62, + 0xf6, 0xac, 0xcf, 0xaf, 0xbd, 0x8c, 0xfd, 0x90, 0x2e, 0xd3, 0xed, + 0x89, 0xab, 0xf7, 0x8f, 0xfa, 0x48, 0x2d, 0xbd, 0xee, 0xb6, 0x96, + 0x98, 0x42, 0x39, 0x4c, 0x9a, 0x11, 0x68, 0xae, 0x3d, 0x48, 0x1a, + 0x01, 0x78, 0x42, 0xf6, 0x60, 0x00, 0x2d, 0x42, 0x44, 0x7c, 0x6b, + 0x22, 0xf7, 0xb7, 0x2f, 0x21, 0xaa, 0xe0, 0x21, 0xc9})), + std::make_pair( + 63, + std::vector<uint8_t>( + {0xbd, 0x96, 0x5b, 0xf3, 0x1e, 0x87, 0xd7, 0x03, 0x27, 0x53, 0x6f, + 0x2a, 0x34, 0x1c, 0xeb, 0xc4, 0x76, 0x8e, 0xca, 0x27, 0x5f, 0xa0, + 0x5e, 0xf9, 0x8f, 0x7f, 0x1b, 0x71, 0xa0, 0x35, 0x12, 0x98, 0xde, + 0x00, 0x6f, 0xba, 0x73, 0xfe, 0x67, 0x33, 0xed, 0x01, 0xd7, 0x58, + 0x01, 0xb4, 0xa9, 0x28, 0xe5, 0x42, 0x31, 0xb3, 0x8e, 0x38, 0xc5, + 0x62, 0xb2, 0xe3, 0x3e, 0xa1, 0x28, 0x49, 0x92, 0xfa})), + std::make_pair( + 64, + std::vector<uint8_t>( + {0x65, 0x67, 0x6d, 0x80, 0x06, 0x17, 0x97, 0x2f, 0xbd, 0x87, 0xe4, + 0xb9, 0x51, 0x4e, 0x1c, 0x67, 0x40, 0x2b, 0x7a, 0x33, 0x10, 0x96, + 0xd3, 0xbf, 0xac, 0x22, 0xf1, 0xab, 0xb9, 0x53, 0x74, 0xab, 0xc9, + 0x42, 0xf1, 0x6e, 0x9a, 0xb0, 0xea, 0xd3, 0x3b, 0x87, 0xc9, 0x19, + 0x68, 0xa6, 0xe5, 0x09, 0xe1, 0x19, 0xff, 0x07, 0x78, 0x7b, 0x3e, + 0xf4, 0x83, 0xe1, 0xdc, 0xdc, 0xcf, 0x6e, 0x30, 0x22})), + std::make_pair( + 65, + std::vector<uint8_t>( + {0x93, 0x9f, 0xa1, 0x89, 0x69, 0x9c, 0x5d, 0x2c, 0x81, 0xdd, 0xd1, + 0xff, 0xc1, 0xfa, 0x20, 0x7c, 0x97, 0x0b, 0x6a, 0x36, 0x85, 0xbb, + 0x29, 0xce, 0x1d, 0x3e, 0x99, 0xd4, 0x2f, 0x2f, 0x74, 0x42, 0xda, + 0x53, 0xe9, 0x5a, 0x72, 0x90, 0x73, 0x14, 0xf4, 0x58, 0x83, 0x99, + 0xa3, 0xff, 0x5b, 0x0a, 0x92, 0xbe, 0xb3, 0xf6, 0xbe, 0x26, 0x94, + 0xf9, 0xf8, 0x6e, 0xcf, 0x29, 0x52, 0xd5, 0xb4, 0x1c})), + std::make_pair( + 66, + std::vector<uint8_t>( + {0xc5, 0x16, 0x54, 0x17, 0x01, 0x86, 0x3f, 0x91, 0x00, 0x5f, 0x31, + 0x41, 0x08, 0xce, 0xec, 0xe3, 0xc6, 0x43, 0xe0, 0x4f, 0xc8, 0xc4, + 0x2f, 0xd2, 0xff, 0x55, 0x62, 0x20, 0xe6, 0x16, 0xaa, 0xa6, 0xa4, + 0x8a, 0xeb, 0x97, 0xa8, 0x4b, 0xad, 0x74, 0x78, 0x2e, 0x8d, 0xff, + 0x96, 0xa1, 0xa2, 0xfa, 0x94, 0x93, 0x39, 0xd7, 0x22, 0xed, 0xca, + 0xa3, 0x2b, 0x57, 0x06, 0x70, 0x41, 0xdf, 0x88, 0xcc})), + std::make_pair( + 67, + std::vector<uint8_t>( + {0x98, 0x7f, 0xd6, 0xe0, 0xd6, 0x85, 0x7c, 0x55, 0x3e, 0xae, 0xbb, + 0x3d, 0x34, 0x97, 0x0a, 0x2c, 0x2f, 0x6e, 0x89, 0xa3, 0x54, 0x8f, + 0x49, 0x25, 0x21, 0x72, 0x2b, 0x80, 0xa1, 0xc2, 0x1a, 0x15, 0x38, + 0x92, 0x34, 0x6d, 0x2c, 0xba, 0x64, 0x44, 0x21, 0x2d, 0x56, 0xda, + 0x9a, 0x26, 0xe3, 0x24, 0xdc, 0xcb, 0xc0, 0xdc, 0xde, 0x85, 0xd4, + 0xd2, 0xee, 0x43, 0x99, 0xee, 0xc5, 0xa6, 0x4e, 0x8f})), + std::make_pair( + 68, + std::vector<uint8_t>( + {0xae, 0x56, 0xde, 0xb1, 0xc2, 0x32, 0x8d, 0x9c, 0x40, 0x17, 0x70, + 0x6b, 0xce, 0x6e, 0x99, 0xd4, 0x13, 0x49, 0x05, 0x3b, 0xa9, 0xd3, + 0x36, 0xd6, 0x77, 0xc4, 0xc2, 0x7d, 0x9f, 0xd5, 0x0a, 0xe6, 0xae, + 0xe1, 0x7e, 0x85, 0x31, 0x54, 0xe1, 0xf4, 0xfe, 0x76, 0x72, 0x34, + 0x6d, 0xa2, 0xea, 0xa3, 0x1e, 0xea, 0x53, 0xfc, 0xf2, 0x4a, 0x22, + 0x80, 0x4f, 0x11, 0xd0, 0x3d, 0xa6, 0xab, 0xfc, 0x2b})), + std::make_pair( + 69, + std::vector<uint8_t>( + {0x49, 0xd6, 0xa6, 0x08, 0xc9, 0xbd, 0xe4, 0x49, 0x18, 0x70, 0x49, + 0x85, 0x72, 0xac, 0x31, 0xaa, 0xc3, 0xfa, 0x40, 0x93, 0x8b, 0x38, + 0xa7, 0x81, 0x8f, 0x72, 0x38, 0x3e, 0xb0, 0x40, 0xad, 0x39, 0x53, + 0x2b, 0xc0, 0x65, 0x71, 0xe1, 0x3d, 0x76, 0x7e, 0x69, 0x45, 0xab, + 0x77, 0xc0, 0xbd, 0xc3, 0xb0, 0x28, 0x42, 0x53, 0x34, 0x3f, 0x9f, + 0x6c, 0x12, 0x44, 0xeb, 0xf2, 0xff, 0x0d, 0xf8, 0x66})), + std::make_pair( + 70, + std::vector<uint8_t>( + {0xda, 0x58, 0x2a, 0xd8, 0xc5, 0x37, 0x0b, 0x44, 0x69, 0xaf, 0x86, + 0x2a, 0xa6, 0x46, 0x7a, 0x22, 0x93, 0xb2, 0xb2, 0x8b, 0xd8, 0x0a, + 0xe0, 0xe9, 0x1f, 0x42, 0x5a, 0xd3, 0xd4, 0x72, 0x49, 0xfd, 0xf9, + 0x88, 0x25, 0xcc, 0x86, 0xf1, 0x40, 0x28, 0xc3, 0x30, 0x8c, 0x98, + 0x04, 0xc7, 0x8b, 0xfe, 0xee, 0xee, 0x46, 0x14, 0x44, 0xce, 0x24, + 0x36, 0x87, 0xe1, 0xa5, 0x05, 0x22, 0x45, 0x6a, 0x1d})), + std::make_pair( + 71, + std::vector<uint8_t>( + {0xd5, 0x26, 0x6a, 0xa3, 0x33, 0x11, 0x94, 0xae, 0xf8, 0x52, 0xee, + 0xd8, 0x6d, 0x7b, 0x5b, 0x26, 0x33, 0xa0, 0xaf, 0x1c, 0x73, 0x59, + 0x06, 0xf2, 0xe1, 0x32, 0x79, 0xf1, 0x49, 0x31, 0xa9, 0xfc, 0x3b, + 0x0e, 0xac, 0x5c, 0xe9, 0x24, 0x52, 0x73, 0xbd, 0x1a, 0xa9, 0x29, + 0x05, 0xab, 0xe1, 0x62, 0x78, 0xef, 0x7e, 0xfd, 0x47, 0x69, 0x47, + 0x89, 0xa7, 0x28, 0x3b, 0x77, 0xda, 0x3c, 0x70, 0xf8})), + std::make_pair( + 72, + std::vector<uint8_t>( + {0x29, 0x62, 0x73, 0x4c, 0x28, 0x25, 0x21, 0x86, 0xa9, 0xa1, 0x11, + 0x1c, 0x73, 0x2a, 0xd4, 0xde, 0x45, 0x06, 0xd4, 0xb4, 0x48, 0x09, + 0x16, 0x30, 0x3e, 0xb7, 0x99, 0x1d, 0x65, 0x9c, 0xcd, 0xa0, 0x7a, + 0x99, 0x11, 0x91, 0x4b, 0xc7, 0x5c, 0x41, 0x8a, 0xb7, 0xa4, 0x54, + 0x17, 0x57, 0xad, 0x05, 0x47, 0x96, 0xe2, 0x67, 0x97, 0xfe, 0xaf, + 0x36, 0xe9, 0xf6, 0xad, 0x43, 0xf1, 0x4b, 0x35, 0xa4})), + std::make_pair( + 73, + std::vector<uint8_t>( + {0xe8, 0xb7, 0x9e, 0xc5, 0xd0, 0x6e, 0x11, 0x1b, 0xdf, 0xaf, 0xd7, + 0x1e, 0x9f, 0x57, 0x60, 0xf0, 0x0a, 0xc8, 0xac, 0x5d, 0x8b, 0xf7, + 0x68, 0xf9, 0xff, 0x6f, 0x08, 0xb8, 0xf0, 0x26, 0x09, 0x6b, 0x1c, + 0xc3, 0xa4, 0xc9, 0x73, 0x33, 0x30, 0x19, 0xf1, 0xe3, 0x55, 0x3e, + 0x77, 0xda, 0x3f, 0x98, 0xcb, 0x9f, 0x54, 0x2e, 0x0a, 0x90, 0xe5, + 0xf8, 0xa9, 0x40, 0xcc, 0x58, 0xe5, 0x98, 0x44, 0xb3})), + std::make_pair( + 74, + std::vector<uint8_t>( + {0xdf, 0xb3, 0x20, 0xc4, 0x4f, 0x9d, 0x41, 0xd1, 0xef, 0xdc, 0xc0, + 0x15, 0xf0, 0x8d, 0xd5, 0x53, 0x9e, 0x52, 0x6e, 0x39, 0xc8, 0x7d, + 0x50, 0x9a, 0xe6, 0x81, 0x2a, 0x96, 0x9e, 0x54, 0x31, 0xbf, 0x4f, + 0xa7, 0xd9, 0x1f, 0xfd, 0x03, 0xb9, 0x81, 0xe0, 0xd5, 0x44, 0xcf, + 0x72, 0xd7, 0xb1, 0xc0, 0x37, 0x4f, 0x88, 0x01, 0x48, 0x2e, 0x6d, + 0xea, 0x2e, 0xf9, 0x03, 0x87, 0x7e, 0xba, 0x67, 0x5e})), + std::make_pair( + 75, + std::vector<uint8_t>( + {0xd8, 0x86, 0x75, 0x11, 0x8f, 0xdb, 0x55, 0xa5, 0xfb, 0x36, 0x5a, + 0xc2, 0xaf, 0x1d, 0x21, 0x7b, 0xf5, 0x26, 0xce, 0x1e, 0xe9, 0xc9, + 0x4b, 0x2f, 0x00, 0x90, 0xb2, 0xc5, 0x8a, 0x06, 0xca, 0x58, 0x18, + 0x7d, 0x7f, 0xe5, 0x7c, 0x7b, 0xed, 0x9d, 0x26, 0xfc, 0xa0, 0x67, + 0xb4, 0x11, 0x0e, 0xef, 0xcd, 0x9a, 0x0a, 0x34, 0x5d, 0xe8, 0x72, + 0xab, 0xe2, 0x0d, 0xe3, 0x68, 0x00, 0x1b, 0x07, 0x45})), + std::make_pair( + 76, + std::vector<uint8_t>( + {0xb8, 0x93, 0xf2, 0xfc, 0x41, 0xf7, 0xb0, 0xdd, 0x6e, 0x2f, 0x6a, + 0xa2, 0xe0, 0x37, 0x0c, 0x0c, 0xff, 0x7d, 0xf0, 0x9e, 0x3a, 0xcf, + 0xcc, 0x0e, 0x92, 0x0b, 0x6e, 0x6f, 0xad, 0x0e, 0xf7, 0x47, 0xc4, + 0x06, 0x68, 0x41, 0x7d, 0x34, 0x2b, 0x80, 0xd2, 0x35, 0x1e, 0x8c, + 0x17, 0x5f, 0x20, 0x89, 0x7a, 0x06, 0x2e, 0x97, 0x65, 0xe6, 0xc6, + 0x7b, 0x53, 0x9b, 0x6b, 0xa8, 0xb9, 0x17, 0x05, 0x45})), + std::make_pair( + 77, + std::vector<uint8_t>( + {0x6c, 0x67, 0xec, 0x56, 0x97, 0xac, 0xcd, 0x23, 0x5c, 0x59, 0xb4, + 0x86, 0xd7, 0xb7, 0x0b, 0xae, 0xed, 0xcb, 0xd4, 0xaa, 0x64, 0xeb, + 0xd4, 0xee, 0xf3, 0xc7, 0xea, 0xc1, 0x89, 0x56, 0x1a, 0x72, 0x62, + 0x50, 0xae, 0xc4, 0xd4, 0x8c, 0xad, 0xca, 0xfb, 0xbe, 0x2c, 0xe3, + 0xc1, 0x6c, 0xe2, 0xd6, 0x91, 0xa8, 0xcc, 0xe0, 0x6e, 0x88, 0x79, + 0x55, 0x6d, 0x44, 0x83, 0xed, 0x71, 0x65, 0xc0, 0x63})), + std::make_pair( + 78, + std::vector<uint8_t>( + {0xf1, 0xaa, 0x2b, 0x04, 0x4f, 0x8f, 0x0c, 0x63, 0x8a, 0x3f, 0x36, + 0x2e, 0x67, 0x7b, 0x5d, 0x89, 0x1d, 0x6f, 0xd2, 0xab, 0x07, 0x65, + 0xf6, 0xee, 0x1e, 0x49, 0x87, 0xde, 0x05, 0x7e, 0xad, 0x35, 0x78, + 0x83, 0xd9, 0xb4, 0x05, 0xb9, 0xd6, 0x09, 0xee, 0xa1, 0xb8, 0x69, + 0xd9, 0x7f, 0xb1, 0x6d, 0x9b, 0x51, 0x01, 0x7c, 0x55, 0x3f, 0x3b, + 0x93, 0xc0, 0xa1, 0xe0, 0xf1, 0x29, 0x6f, 0xed, 0xcd})), + std::make_pair( + 79, + std::vector<uint8_t>( + {0xcb, 0xaa, 0x25, 0x95, 0x72, 0xd4, 0xae, 0xbf, 0xc1, 0x91, 0x7a, + 0xcd, 0xdc, 0x58, 0x2b, 0x9f, 0x8d, 0xfa, 0xa9, 0x28, 0xa1, 0x98, + 0xca, 0x7a, 0xcd, 0x0f, 0x2a, 0xa7, 0x6a, 0x13, 0x4a, 0x90, 0x25, + 0x2e, 0x62, 0x98, 0xa6, 0x5b, 0x08, 0x18, 0x6a, 0x35, 0x0d, 0x5b, + 0x76, 0x26, 0x69, 0x9f, 0x8c, 0xb7, 0x21, 0xa3, 0xea, 0x59, 0x21, + 0xb7, 0x53, 0xae, 0x3a, 0x2d, 0xce, 0x24, 0xba, 0x3a})), + std::make_pair( + 80, + std::vector<uint8_t>( + {0xfa, 0x15, 0x49, 0xc9, 0x79, 0x6c, 0xd4, 0xd3, 0x03, 0xdc, 0xf4, + 0x52, 0xc1, 0xfb, 0xd5, 0x74, 0x4f, 0xd9, 0xb9, 0xb4, 0x70, 0x03, + 0xd9, 0x20, 0xb9, 0x2d, 0xe3, 0x48, 0x39, 0xd0, 0x7e, 0xf2, 0xa2, + 0x9d, 0xed, 0x68, 0xf6, 0xfc, 0x9e, 0x6c, 0x45, 0xe0, 0x71, 0xa2, + 0xe4, 0x8b, 0xd5, 0x0c, 0x50, 0x84, 0xe9, 0x6b, 0x65, 0x7d, 0xd0, + 0x40, 0x40, 0x45, 0xa1, 0xdd, 0xef, 0xe2, 0x82, 0xed})), + std::make_pair( + 81, + std::vector<uint8_t>( + {0x5c, 0xf2, 0xac, 0x89, 0x7a, 0xb4, 0x44, 0xdc, 0xb5, 0xc8, 0xd8, + 0x7c, 0x49, 0x5d, 0xbd, 0xb3, 0x4e, 0x18, 0x38, 0xb6, 0xb6, 0x29, + 0x42, 0x7c, 0xaa, 0x51, 0x70, 0x2a, 0xd0, 0xf9, 0x68, 0x85, 0x25, + 0xf1, 0x3b, 0xec, 0x50, 0x3a, 0x3c, 0x3a, 0x2c, 0x80, 0xa6, 0x5e, + 0x0b, 0x57, 0x15, 0xe8, 0xaf, 0xab, 0x00, 0xff, 0xa5, 0x6e, 0xc4, + 0x55, 0xa4, 0x9a, 0x1a, 0xd3, 0x0a, 0xa2, 0x4f, 0xcd})), + std::make_pair( + 82, + std::vector<uint8_t>( + {0x9a, 0xaf, 0x80, 0x20, 0x7b, 0xac, 0xe1, 0x7b, 0xb7, 0xab, 0x14, + 0x57, 0x57, 0xd5, 0x69, 0x6b, 0xde, 0x32, 0x40, 0x6e, 0xf2, 0x2b, + 0x44, 0x29, 0x2e, 0xf6, 0x5d, 0x45, 0x19, 0xc3, 0xbb, 0x2a, 0xd4, + 0x1a, 0x59, 0xb6, 0x2c, 0xc3, 0xe9, 0x4b, 0x6f, 0xa9, 0x6d, 0x32, + 0xa7, 0xfa, 0xad, 0xae, 0x28, 0xaf, 0x7d, 0x35, 0x09, 0x72, 0x19, + 0xaa, 0x3f, 0xd8, 0xcd, 0xa3, 0x1e, 0x40, 0xc2, 0x75})), + std::make_pair( + 83, + std::vector<uint8_t>( + {0xaf, 0x88, 0xb1, 0x63, 0x40, 0x2c, 0x86, 0x74, 0x5c, 0xb6, 0x50, + 0xc2, 0x98, 0x8f, 0xb9, 0x52, 0x11, 0xb9, 0x4b, 0x03, 0xef, 0x29, + 0x0e, 0xed, 0x96, 0x62, 0x03, 0x42, 0x41, 0xfd, 0x51, 0xcf, 0x39, + 0x8f, 0x80, 0x73, 0xe3, 0x69, 0x35, 0x4c, 0x43, 0xea, 0xe1, 0x05, + 0x2f, 0x9b, 0x63, 0xb0, 0x81, 0x91, 0xca, 0xa1, 0x38, 0xaa, 0x54, + 0xfe, 0xa8, 0x89, 0xcc, 0x70, 0x24, 0x23, 0x68, 0x97})), + std::make_pair( + 84, + std::vector<uint8_t>( + {0x48, 0xfa, 0x7d, 0x64, 0xe1, 0xce, 0xee, 0x27, 0xb9, 0x86, 0x4d, + 0xb5, 0xad, 0xa4, 0xb5, 0x3d, 0x00, 0xc9, 0xbc, 0x76, 0x26, 0x55, + 0x58, 0x13, 0xd3, 0xcd, 0x67, 0x30, 0xab, 0x3c, 0xc0, 0x6f, 0xf3, + 0x42, 0xd7, 0x27, 0x90, 0x5e, 0x33, 0x17, 0x1b, 0xde, 0x6e, 0x84, + 0x76, 0xe7, 0x7f, 0xb1, 0x72, 0x08, 0x61, 0xe9, 0x4b, 0x73, 0xa2, + 0xc5, 0x38, 0xd2, 0x54, 0x74, 0x62, 0x85, 0xf4, 0x30})), + std::make_pair( + 85, + std::vector<uint8_t>( + {0x0e, 0x6f, 0xd9, 0x7a, 0x85, 0xe9, 0x04, 0xf8, 0x7b, 0xfe, 0x85, + 0xbb, 0xeb, 0x34, 0xf6, 0x9e, 0x1f, 0x18, 0x10, 0x5c, 0xf4, 0xed, + 0x4f, 0x87, 0xae, 0xc3, 0x6c, 0x6e, 0x8b, 0x5f, 0x68, 0xbd, 0x2a, + 0x6f, 0x3d, 0xc8, 0xa9, 0xec, 0xb2, 0xb6, 0x1d, 0xb4, 0xee, 0xdb, + 0x6b, 0x2e, 0xa1, 0x0b, 0xf9, 0xcb, 0x02, 0x51, 0xfb, 0x0f, 0x8b, + 0x34, 0x4a, 0xbf, 0x7f, 0x36, 0x6b, 0x6d, 0xe5, 0xab})), + std::make_pair( + 86, + std::vector<uint8_t>( + {0x06, 0x62, 0x2d, 0xa5, 0x78, 0x71, 0x76, 0x28, 0x7f, 0xdc, 0x8f, + 0xed, 0x44, 0x0b, 0xad, 0x18, 0x7d, 0x83, 0x00, 0x99, 0xc9, 0x4e, + 0x6d, 0x04, 0xc8, 0xe9, 0xc9, 0x54, 0xcd, 0xa7, 0x0c, 0x8b, 0xb9, + 0xe1, 0xfc, 0x4a, 0x6d, 0x0b, 0xaa, 0x83, 0x1b, 0x9b, 0x78, 0xef, + 0x66, 0x48, 0x68, 0x1a, 0x48, 0x67, 0xa1, 0x1d, 0xa9, 0x3e, 0xe3, + 0x6e, 0x5e, 0x6a, 0x37, 0xd8, 0x7f, 0xc6, 0x3f, 0x6f})), + std::make_pair( + 87, + std::vector<uint8_t>( + {0x1d, 0xa6, 0x77, 0x2b, 0x58, 0xfa, 0xbf, 0x9c, 0x61, 0xf6, 0x8d, + 0x41, 0x2c, 0x82, 0xf1, 0x82, 0xc0, 0x23, 0x6d, 0x7d, 0x57, 0x5e, + 0xf0, 0xb5, 0x8d, 0xd2, 0x24, 0x58, 0xd6, 0x43, 0xcd, 0x1d, 0xfc, + 0x93, 0xb0, 0x38, 0x71, 0xc3, 0x16, 0xd8, 0x43, 0x0d, 0x31, 0x29, + 0x95, 0xd4, 0x19, 0x7f, 0x08, 0x74, 0xc9, 0x91, 0x72, 0xba, 0x00, + 0x4a, 0x01, 0xee, 0x29, 0x5a, 0xba, 0xc2, 0x4e, 0x46})), + std::make_pair( + 88, + std::vector<uint8_t>( + {0x3c, 0xd2, 0xd9, 0x32, 0x0b, 0x7b, 0x1d, 0x5f, 0xb9, 0xaa, 0xb9, + 0x51, 0xa7, 0x60, 0x23, 0xfa, 0x66, 0x7b, 0xe1, 0x4a, 0x91, 0x24, + 0xe3, 0x94, 0x51, 0x39, 0x18, 0xa3, 0xf4, 0x40, 0x96, 0xae, 0x49, + 0x04, 0xba, 0x0f, 0xfc, 0x15, 0x0b, 0x63, 0xbc, 0x7a, 0xb1, 0xee, + 0xb9, 0xa6, 0xe2, 0x57, 0xe5, 0xc8, 0xf0, 0x00, 0xa7, 0x03, 0x94, + 0xa5, 0xaf, 0xd8, 0x42, 0x71, 0x5d, 0xe1, 0x5f, 0x29})), + std::make_pair( + 89, + std::vector<uint8_t>( + {0x04, 0xcd, 0xc1, 0x4f, 0x74, 0x34, 0xe0, 0xb4, 0xbe, 0x70, 0xcb, + 0x41, 0xdb, 0x4c, 0x77, 0x9a, 0x88, 0xea, 0xef, 0x6a, 0xcc, 0xeb, + 0xcb, 0x41, 0xf2, 0xd4, 0x2f, 0xff, 0xe7, 0xf3, 0x2a, 0x8e, 0x28, + 0x1b, 0x5c, 0x10, 0x3a, 0x27, 0x02, 0x1d, 0x0d, 0x08, 0x36, 0x22, + 0x50, 0x75, 0x3c, 0xdf, 0x70, 0x29, 0x21, 0x95, 0xa5, 0x3a, 0x48, + 0x72, 0x8c, 0xeb, 0x58, 0x44, 0xc2, 0xd9, 0x8b, 0xab})), + std::make_pair( + 90, + std::vector<uint8_t>( + {0x90, 0x71, 0xb7, 0xa8, 0xa0, 0x75, 0xd0, 0x09, 0x5b, 0x8f, 0xb3, + 0xae, 0x51, 0x13, 0x78, 0x57, 0x35, 0xab, 0x98, 0xe2, 0xb5, 0x2f, + 0xaf, 0x91, 0xd5, 0xb8, 0x9e, 0x44, 0xaa, 0xc5, 0xb5, 0xd4, 0xeb, + 0xbf, 0x91, 0x22, 0x3b, 0x0f, 0xf4, 0xc7, 0x19, 0x05, 0xda, 0x55, + 0x34, 0x2e, 0x64, 0x65, 0x5d, 0x6e, 0xf8, 0xc8, 0x9a, 0x47, 0x68, + 0xc3, 0xf9, 0x3a, 0x6d, 0xc0, 0x36, 0x6b, 0x5b, 0xc8})), + std::make_pair( + 91, + std::vector<uint8_t>( + {0xeb, 0xb3, 0x02, 0x40, 0xdd, 0x96, 0xc7, 0xbc, 0x8d, 0x0a, 0xbe, + 0x49, 0xaa, 0x4e, 0xdc, 0xbb, 0x4a, 0xfd, 0xc5, 0x1f, 0xf9, 0xaa, + 0xf7, 0x20, 0xd3, 0xf9, 0xe7, 0xfb, 0xb0, 0xf9, 0xc6, 0xd6, 0x57, + 0x13, 0x50, 0x50, 0x17, 0x69, 0xfc, 0x4e, 0xbd, 0x0b, 0x21, 0x41, + 0x24, 0x7f, 0xf4, 0x00, 0xd4, 0xfd, 0x4b, 0xe4, 0x14, 0xed, 0xf3, + 0x77, 0x57, 0xbb, 0x90, 0xa3, 0x2a, 0xc5, 0xc6, 0x5a})), + std::make_pair( + 92, + std::vector<uint8_t>( + {0x85, 0x32, 0xc5, 0x8b, 0xf3, 0xc8, 0x01, 0x5d, 0x9d, 0x1c, 0xbe, + 0x00, 0xee, 0xf1, 0xf5, 0x08, 0x2f, 0x8f, 0x36, 0x32, 0xfb, 0xe9, + 0xf1, 0xed, 0x4f, 0x9d, 0xfb, 0x1f, 0xa7, 0x9e, 0x82, 0x83, 0x06, + 0x6d, 0x77, 0xc4, 0x4c, 0x4a, 0xf9, 0x43, 0xd7, 0x6b, 0x30, 0x03, + 0x64, 0xae, 0xcb, 0xd0, 0x64, 0x8c, 0x8a, 0x89, 0x39, 0xbd, 0x20, + 0x41, 0x23, 0xf4, 0xb5, 0x62, 0x60, 0x42, 0x2d, 0xec})), + std::make_pair( + 93, + std::vector<uint8_t>( + {0xfe, 0x98, 0x46, 0xd6, 0x4f, 0x7c, 0x77, 0x08, 0x69, 0x6f, 0x84, + 0x0e, 0x2d, 0x76, 0xcb, 0x44, 0x08, 0xb6, 0x59, 0x5c, 0x2f, 0x81, + 0xec, 0x6a, 0x28, 0xa7, 0xf2, 0xf2, 0x0c, 0xb8, 0x8c, 0xfe, 0x6a, + 0xc0, 0xb9, 0xe9, 0xb8, 0x24, 0x4f, 0x08, 0xbd, 0x70, 0x95, 0xc3, + 0x50, 0xc1, 0xd0, 0x84, 0x2f, 0x64, 0xfb, 0x01, 0xbb, 0x7f, 0x53, + 0x2d, 0xfc, 0xd4, 0x73, 0x71, 0xb0, 0xae, 0xeb, 0x79})), + std::make_pair( + 94, + std::vector<uint8_t>( + {0x28, 0xf1, 0x7e, 0xa6, 0xfb, 0x6c, 0x42, 0x09, 0x2d, 0xc2, 0x64, + 0x25, 0x7e, 0x29, 0x74, 0x63, 0x21, 0xfb, 0x5b, 0xda, 0xea, 0x98, + 0x73, 0xc2, 0xa7, 0xfa, 0x9d, 0x8f, 0x53, 0x81, 0x8e, 0x89, 0x9e, + 0x16, 0x1b, 0xc7, 0x7d, 0xfe, 0x80, 0x90, 0xaf, 0xd8, 0x2b, 0xf2, + 0x26, 0x6c, 0x5c, 0x1b, 0xc9, 0x30, 0xa8, 0xd1, 0x54, 0x76, 0x24, + 0x43, 0x9e, 0x66, 0x2e, 0xf6, 0x95, 0xf2, 0x6f, 0x24})), + std::make_pair( + 95, + std::vector<uint8_t>( + {0xec, 0x6b, 0x7d, 0x7f, 0x03, 0x0d, 0x48, 0x50, 0xac, 0xae, 0x3c, + 0xb6, 0x15, 0xc2, 0x1d, 0xd2, 0x52, 0x06, 0xd6, 0x3e, 0x84, 0xd1, + 0xdb, 0x8d, 0x95, 0x73, 0x70, 0x73, 0x7b, 0xa0, 0xe9, 0x84, 0x67, + 0xea, 0x0c, 0xe2, 0x74, 0xc6, 0x61, 0x99, 0x90, 0x1e, 0xae, 0xc1, + 0x8a, 0x08, 0x52, 0x57, 0x15, 0xf5, 0x3b, 0xfd, 0xb0, 0xaa, 0xcb, + 0x61, 0x3d, 0x34, 0x2e, 0xbd, 0xce, 0xed, 0xdc, 0x3b})), + std::make_pair( + 96, + std::vector<uint8_t>( + {0xb4, 0x03, 0xd3, 0x69, 0x1c, 0x03, 0xb0, 0xd3, 0x41, 0x8d, 0xf3, + 0x27, 0xd5, 0x86, 0x0d, 0x34, 0xbb, 0xfc, 0xc4, 0x51, 0x9b, 0xfb, + 0xce, 0x36, 0xbf, 0x33, 0xb2, 0x08, 0x38, 0x5f, 0xad, 0xb9, 0x18, + 0x6b, 0xc7, 0x8a, 0x76, 0xc4, 0x89, 0xd8, 0x9f, 0xd5, 0x7e, 0x7d, + 0xc7, 0x54, 0x12, 0xd2, 0x3b, 0xcd, 0x1d, 0xae, 0x84, 0x70, 0xce, + 0x92, 0x74, 0x75, 0x4b, 0xb8, 0x58, 0x5b, 0x13, 0xc5})), + std::make_pair( + 97, + std::vector<uint8_t>( + {0x31, 0xfc, 0x79, 0x73, 0x8b, 0x87, 0x72, 0xb3, 0xf5, 0x5c, 0xd8, + 0x17, 0x88, 0x13, 0xb3, 0xb5, 0x2d, 0x0d, 0xb5, 0xa4, 0x19, 0xd3, + 0x0b, 0xa9, 0x49, 0x5c, 0x4b, 0x9d, 0xa0, 0x21, 0x9f, 0xac, 0x6d, + 0xf8, 0xe7, 0xc2, 0x3a, 0x81, 0x15, 0x51, 0xa6, 0x2b, 0x82, 0x7f, + 0x25, 0x6e, 0xcd, 0xb8, 0x12, 0x4a, 0xc8, 0xa6, 0x79, 0x2c, 0xcf, + 0xec, 0xc3, 0xb3, 0x01, 0x27, 0x22, 0xe9, 0x44, 0x63})), + std::make_pair( + 98, + std::vector<uint8_t>( + {0xbb, 0x20, 0x39, 0xec, 0x28, 0x70, 0x91, 0xbc, 0xc9, 0x64, 0x2f, + 0xc9, 0x00, 0x49, 0xe7, 0x37, 0x32, 0xe0, 0x2e, 0x57, 0x7e, 0x28, + 0x62, 0xb3, 0x22, 0x16, 0xae, 0x9b, 0xed, 0xcd, 0x73, 0x0c, 0x4c, + 0x28, 0x4e, 0xf3, 0x96, 0x8c, 0x36, 0x8b, 0x7d, 0x37, 0x58, 0x4f, + 0x97, 0xbd, 0x4b, 0x4d, 0xc6, 0xef, 0x61, 0x27, 0xac, 0xfe, 0x2e, + 0x6a, 0xe2, 0x50, 0x91, 0x24, 0xe6, 0x6c, 0x8a, 0xf4})), + std::make_pair( + 99, + std::vector<uint8_t>( + {0xf5, 0x3d, 0x68, 0xd1, 0x3f, 0x45, 0xed, 0xfc, 0xb9, 0xbd, 0x41, + 0x5e, 0x28, 0x31, 0xe9, 0x38, 0x35, 0x0d, 0x53, 0x80, 0xd3, 0x43, + 0x22, 0x78, 0xfc, 0x1c, 0x0c, 0x38, 0x1f, 0xcb, 0x7c, 0x65, 0xc8, + 0x2d, 0xaf, 0xe0, 0x51, 0xd8, 0xc8, 0xb0, 0xd4, 0x4e, 0x09, 0x74, + 0xa0, 0xe5, 0x9e, 0xc7, 0xbf, 0x7e, 0xd0, 0x45, 0x9f, 0x86, 0xe9, + 0x6f, 0x32, 0x9f, 0xc7, 0x97, 0x52, 0x51, 0x0f, 0xd3})), + std::make_pair( + 100, + std::vector<uint8_t>( + {0x8d, 0x56, 0x8c, 0x79, 0x84, 0xf0, 0xec, 0xdf, 0x76, 0x40, 0xfb, + 0xc4, 0x83, 0xb5, 0xd8, 0xc9, 0xf8, 0x66, 0x34, 0xf6, 0xf4, 0x32, + 0x91, 0x84, 0x1b, 0x30, 0x9a, 0x35, 0x0a, 0xb9, 0xc1, 0x13, 0x7d, + 0x24, 0x06, 0x6b, 0x09, 0xda, 0x99, 0x44, 0xba, 0xc5, 0x4d, 0x5b, + 0xb6, 0x58, 0x0d, 0x83, 0x60, 0x47, 0xaa, 0xc7, 0x4a, 0xb7, 0x24, + 0xb8, 0x87, 0xeb, 0xf9, 0x3d, 0x4b, 0x32, 0xec, 0xa9})), + std::make_pair( + 101, + std::vector<uint8_t>( + {0xc0, 0xb6, 0x5c, 0xe5, 0xa9, 0x6f, 0xf7, 0x74, 0xc4, 0x56, 0xca, + 0xc3, 0xb5, 0xf2, 0xc4, 0xcd, 0x35, 0x9b, 0x4f, 0xf5, 0x3e, 0xf9, + 0x3a, 0x3d, 0xa0, 0x77, 0x8b, 0xe4, 0x90, 0x0d, 0x1e, 0x8d, 0xa1, + 0x60, 0x1e, 0x76, 0x9e, 0x8f, 0x1b, 0x02, 0xd2, 0xa2, 0xf8, 0xc5, + 0xb9, 0xfa, 0x10, 0xb4, 0x4f, 0x1c, 0x18, 0x69, 0x85, 0x46, 0x8f, + 0xee, 0xb0, 0x08, 0x73, 0x02, 0x83, 0xa6, 0x65, 0x7d})), + std::make_pair( + 102, + std::vector<uint8_t>( + {0x49, 0x00, 0xbb, 0xa6, 0xf5, 0xfb, 0x10, 0x3e, 0xce, 0x8e, 0xc9, + 0x6a, 0xda, 0x13, 0xa5, 0xc3, 0xc8, 0x54, 0x88, 0xe0, 0x55, 0x51, + 0xda, 0x6b, 0x6b, 0x33, 0xd9, 0x88, 0xe6, 0x11, 0xec, 0x0f, 0xe2, + 0xe3, 0xc2, 0xaa, 0x48, 0xea, 0x6a, 0xe8, 0x98, 0x6a, 0x3a, 0x23, + 0x1b, 0x22, 0x3c, 0x5d, 0x27, 0xce, 0xc2, 0xea, 0xdd, 0xe9, 0x1c, + 0xe0, 0x79, 0x81, 0xee, 0x65, 0x28, 0x62, 0xd1, 0xe4})), + std::make_pair( + 103, + std::vector<uint8_t>( + {0xc7, 0xf5, 0xc3, 0x7c, 0x72, 0x85, 0xf9, 0x27, 0xf7, 0x64, 0x43, + 0x41, 0x4d, 0x43, 0x57, 0xff, 0x78, 0x96, 0x47, 0xd7, 0xa0, 0x05, + 0xa5, 0xa7, 0x87, 0xe0, 0x3c, 0x34, 0x6b, 0x57, 0xf4, 0x9f, 0x21, + 0xb6, 0x4f, 0xa9, 0xcf, 0x4b, 0x7e, 0x45, 0x57, 0x3e, 0x23, 0x04, + 0x90, 0x17, 0x56, 0x71, 0x21, 0xa9, 0xc3, 0xd4, 0xb2, 0xb7, 0x3e, + 0xc5, 0xe9, 0x41, 0x35, 0x77, 0x52, 0x5d, 0xb4, 0x5a})), + std::make_pair( + 104, + std::vector<uint8_t>( + {0xec, 0x70, 0x96, 0x33, 0x07, 0x36, 0xfd, 0xb2, 0xd6, 0x4b, 0x56, + 0x53, 0xe7, 0x47, 0x5d, 0xa7, 0x46, 0xc2, 0x3a, 0x46, 0x13, 0xa8, + 0x26, 0x87, 0xa2, 0x80, 0x62, 0xd3, 0x23, 0x63, 0x64, 0x28, 0x4a, + 0xc0, 0x17, 0x20, 0xff, 0xb4, 0x06, 0xcf, 0xe2, 0x65, 0xc0, 0xdf, + 0x62, 0x6a, 0x18, 0x8c, 0x9e, 0x59, 0x63, 0xac, 0xe5, 0xd3, 0xd5, + 0xbb, 0x36, 0x3e, 0x32, 0xc3, 0x8c, 0x21, 0x90, 0xa6})), + std::make_pair( + 105, + std::vector<uint8_t>( + {0x82, 0xe7, 0x44, 0xc7, 0x5f, 0x46, 0x49, 0xec, 0x52, 0xb8, 0x07, + 0x71, 0xa7, 0x7d, 0x47, 0x5a, 0x3b, 0xc0, 0x91, 0x98, 0x95, 0x56, + 0x96, 0x0e, 0x27, 0x6a, 0x5f, 0x9e, 0xad, 0x92, 0xa0, 0x3f, 0x71, + 0x87, 0x42, 0xcd, 0xcf, 0xea, 0xee, 0x5c, 0xb8, 0x5c, 0x44, 0xaf, + 0x19, 0x8a, 0xdc, 0x43, 0xa4, 0xa4, 0x28, 0xf5, 0xf0, 0xc2, 0xdd, + 0xb0, 0xbe, 0x36, 0x05, 0x9f, 0x06, 0xd7, 0xdf, 0x73})), + std::make_pair( + 106, + std::vector<uint8_t>( + {0x28, 0x34, 0xb7, 0xa7, 0x17, 0x0f, 0x1f, 0x5b, 0x68, 0x55, 0x9a, + 0xb7, 0x8c, 0x10, 0x50, 0xec, 0x21, 0xc9, 0x19, 0x74, 0x0b, 0x78, + 0x4a, 0x90, 0x72, 0xf6, 0xe5, 0xd6, 0x9f, 0x82, 0x8d, 0x70, 0xc9, + 0x19, 0xc5, 0x03, 0x9f, 0xb1, 0x48, 0xe3, 0x9e, 0x2c, 0x8a, 0x52, + 0x11, 0x83, 0x78, 0xb0, 0x64, 0xca, 0x8d, 0x50, 0x01, 0xcd, 0x10, + 0xa5, 0x47, 0x83, 0x87, 0xb9, 0x66, 0x71, 0x5e, 0xd6})), + std::make_pair( + 107, + std::vector<uint8_t>( + {0x16, 0xb4, 0xad, 0xa8, 0x83, 0xf7, 0x2f, 0x85, 0x3b, 0xb7, 0xef, + 0x25, 0x3e, 0xfc, 0xab, 0x0c, 0x3e, 0x21, 0x61, 0x68, 0x7a, 0xd6, + 0x15, 0x43, 0xa0, 0xd2, 0x82, 0x4f, 0x91, 0xc1, 0xf8, 0x13, 0x47, + 0xd8, 0x6b, 0xe7, 0x09, 0xb1, 0x69, 0x96, 0xe1, 0x7f, 0x2d, 0xd4, + 0x86, 0x92, 0x7b, 0x02, 0x88, 0xad, 0x38, 0xd1, 0x30, 0x63, 0xc4, + 0xa9, 0x67, 0x2c, 0x39, 0x39, 0x7d, 0x37, 0x89, 0xb6})), + std::make_pair( + 108, + std::vector<uint8_t>( + {0x78, 0xd0, 0x48, 0xf3, 0xa6, 0x9d, 0x8b, 0x54, 0xae, 0x0e, 0xd6, + 0x3a, 0x57, 0x3a, 0xe3, 0x50, 0xd8, 0x9f, 0x7c, 0x6c, 0xf1, 0xf3, + 0x68, 0x89, 0x30, 0xde, 0x89, 0x9a, 0xfa, 0x03, 0x76, 0x97, 0x62, + 0x9b, 0x31, 0x4e, 0x5c, 0xd3, 0x03, 0xaa, 0x62, 0xfe, 0xea, 0x72, + 0xa2, 0x5b, 0xf4, 0x2b, 0x30, 0x4b, 0x6c, 0x6b, 0xcb, 0x27, 0xfa, + 0xe2, 0x1c, 0x16, 0xd9, 0x25, 0xe1, 0xfb, 0xda, 0xc3})), + std::make_pair( + 109, + std::vector<uint8_t>( + {0x0f, 0x74, 0x6a, 0x48, 0x74, 0x92, 0x87, 0xad, 0xa7, 0x7a, 0x82, + 0x96, 0x1f, 0x05, 0xa4, 0xda, 0x4a, 0xbd, 0xb7, 0xd7, 0x7b, 0x12, + 0x20, 0xf8, 0x36, 0xd0, 0x9e, 0xc8, 0x14, 0x35, 0x9c, 0x0e, 0xc0, + 0x23, 0x9b, 0x8c, 0x7b, 0x9f, 0xf9, 0xe0, 0x2f, 0x56, 0x9d, 0x1b, + 0x30, 0x1e, 0xf6, 0x7c, 0x46, 0x12, 0xd1, 0xde, 0x4f, 0x73, 0x0f, + 0x81, 0xc1, 0x2c, 0x40, 0xcc, 0x06, 0x3c, 0x5c, 0xaa})), + std::make_pair( + 110, + std::vector<uint8_t>( + {0xf0, 0xfc, 0x85, 0x9d, 0x3b, 0xd1, 0x95, 0xfb, 0xdc, 0x2d, 0x59, + 0x1e, 0x4c, 0xda, 0xc1, 0x51, 0x79, 0xec, 0x0f, 0x1d, 0xc8, 0x21, + 0xc1, 0x1d, 0xf1, 0xf0, 0xc1, 0xd2, 0x6e, 0x62, 0x60, 0xaa, 0xa6, + 0x5b, 0x79, 0xfa, 0xfa, 0xca, 0xfd, 0x7d, 0x3a, 0xd6, 0x1e, 0x60, + 0x0f, 0x25, 0x09, 0x05, 0xf5, 0x87, 0x8c, 0x87, 0x45, 0x28, 0x97, + 0x64, 0x7a, 0x35, 0xb9, 0x95, 0xbc, 0xad, 0xc3, 0xa3})), + std::make_pair( + 111, + std::vector<uint8_t>( + {0x26, 0x20, 0xf6, 0x87, 0xe8, 0x62, 0x5f, 0x6a, 0x41, 0x24, 0x60, + 0xb4, 0x2e, 0x2c, 0xef, 0x67, 0x63, 0x42, 0x08, 0xce, 0x10, 0xa0, + 0xcb, 0xd4, 0xdf, 0xf7, 0x04, 0x4a, 0x41, 0xb7, 0x88, 0x00, 0x77, + 0xe9, 0xf8, 0xdc, 0x3b, 0x8d, 0x12, 0x16, 0xd3, 0x37, 0x6a, 0x21, + 0xe0, 0x15, 0xb5, 0x8f, 0xb2, 0x79, 0xb5, 0x21, 0xd8, 0x3f, 0x93, + 0x88, 0xc7, 0x38, 0x2c, 0x85, 0x05, 0x59, 0x0b, 0x9b})), + std::make_pair( + 112, + std::vector<uint8_t>( + {0x22, 0x7e, 0x3a, 0xed, 0x8d, 0x2c, 0xb1, 0x0b, 0x91, 0x8f, 0xcb, + 0x04, 0xf9, 0xde, 0x3e, 0x6d, 0x0a, 0x57, 0xe0, 0x84, 0x76, 0xd9, + 0x37, 0x59, 0xcd, 0x7b, 0x2e, 0xd5, 0x4a, 0x1c, 0xbf, 0x02, 0x39, + 0xc5, 0x28, 0xfb, 0x04, 0xbb, 0xf2, 0x88, 0x25, 0x3e, 0x60, 0x1d, + 0x3b, 0xc3, 0x8b, 0x21, 0x79, 0x4a, 0xfe, 0xf9, 0x0b, 0x17, 0x09, + 0x4a, 0x18, 0x2c, 0xac, 0x55, 0x77, 0x45, 0xe7, 0x5f})), + std::make_pair( + 113, + std::vector<uint8_t>( + {0x1a, 0x92, 0x99, 0x01, 0xb0, 0x9c, 0x25, 0xf2, 0x7d, 0x6b, 0x35, + 0xbe, 0x7b, 0x2f, 0x1c, 0x47, 0x45, 0x13, 0x1f, 0xde, 0xbc, 0xa7, + 0xf3, 0xe2, 0x45, 0x19, 0x26, 0x72, 0x04, 0x34, 0xe0, 0xdb, 0x6e, + 0x74, 0xfd, 0x69, 0x3a, 0xd2, 0x9b, 0x77, 0x7d, 0xc3, 0x35, 0x5c, + 0x59, 0x2a, 0x36, 0x1c, 0x48, 0x73, 0xb0, 0x11, 0x33, 0xa5, 0x7c, + 0x2e, 0x3b, 0x70, 0x75, 0xcb, 0xdb, 0x86, 0xf4, 0xfc})), + std::make_pair( + 114, + std::vector<uint8_t>( + {0x5f, 0xd7, 0x96, 0x8b, 0xc2, 0xfe, 0x34, 0xf2, 0x20, 0xb5, 0xe3, + 0xdc, 0x5a, 0xf9, 0x57, 0x17, 0x42, 0xd7, 0x3b, 0x7d, 0x60, 0x81, + 0x9f, 0x28, 0x88, 0xb6, 0x29, 0x07, 0x2b, 0x96, 0xa9, 0xd8, 0xab, + 0x2d, 0x91, 0xb8, 0x2d, 0x0a, 0x9a, 0xab, 0xa6, 0x1b, 0xbd, 0x39, + 0x95, 0x81, 0x32, 0xfc, 0xc4, 0x25, 0x70, 0x23, 0xd1, 0xec, 0xa5, + 0x91, 0xb3, 0x05, 0x4e, 0x2d, 0xc8, 0x1c, 0x82, 0x00})), + std::make_pair( + 115, + std::vector<uint8_t>( + {0xdf, 0xcc, 0xe8, 0xcf, 0x32, 0x87, 0x0c, 0xc6, 0xa5, 0x03, 0xea, + 0xda, 0xfc, 0x87, 0xfd, 0x6f, 0x78, 0x91, 0x8b, 0x9b, 0x4d, 0x07, + 0x37, 0xdb, 0x68, 0x10, 0xbe, 0x99, 0x6b, 0x54, 0x97, 0xe7, 0xe5, + 0xcc, 0x80, 0xe3, 0x12, 0xf6, 0x1e, 0x71, 0xff, 0x3e, 0x96, 0x24, + 0x43, 0x60, 0x73, 0x15, 0x64, 0x03, 0xf7, 0x35, 0xf5, 0x6b, 0x0b, + 0x01, 0x84, 0x5c, 0x18, 0xf6, 0xca, 0xf7, 0x72, 0xe6})), + std::make_pair( + 116, + std::vector<uint8_t>( + {0x02, 0xf7, 0xef, 0x3a, 0x9c, 0xe0, 0xff, 0xf9, 0x60, 0xf6, 0x70, + 0x32, 0xb2, 0x96, 0xef, 0xca, 0x30, 0x61, 0xf4, 0x93, 0x4d, 0x69, + 0x07, 0x49, 0xf2, 0xd0, 0x1c, 0x35, 0xc8, 0x1c, 0x14, 0xf3, 0x9a, + 0x67, 0xfa, 0x35, 0x0b, 0xc8, 0xa0, 0x35, 0x9b, 0xf1, 0x72, 0x4b, + 0xff, 0xc3, 0xbc, 0xa6, 0xd7, 0xc7, 0xbb, 0xa4, 0x79, 0x1f, 0xd5, + 0x22, 0xa3, 0xad, 0x35, 0x3c, 0x02, 0xec, 0x5a, 0xa8})), + std::make_pair( + 117, + std::vector<uint8_t>( + {0x64, 0xbe, 0x5c, 0x6a, 0xba, 0x65, 0xd5, 0x94, 0x84, 0x4a, 0xe7, + 0x8b, 0xb0, 0x22, 0xe5, 0xbe, 0xbe, 0x12, 0x7f, 0xd6, 0xb6, 0xff, + 0xa5, 0xa1, 0x37, 0x03, 0x85, 0x5a, 0xb6, 0x3b, 0x62, 0x4d, 0xcd, + 0x1a, 0x36, 0x3f, 0x99, 0x20, 0x3f, 0x63, 0x2e, 0xc3, 0x86, 0xf3, + 0xea, 0x76, 0x7f, 0xc9, 0x92, 0xe8, 0xed, 0x96, 0x86, 0x58, 0x6a, + 0xa2, 0x75, 0x55, 0xa8, 0x59, 0x9d, 0x5b, 0x80, 0x8f})), + std::make_pair( + 118, + std::vector<uint8_t>( + {0xf7, 0x85, 0x85, 0x50, 0x5c, 0x4e, 0xaa, 0x54, 0xa8, 0xb5, 0xbe, + 0x70, 0xa6, 0x1e, 0x73, 0x5e, 0x0f, 0xf9, 0x7a, 0xf9, 0x44, 0xdd, + 0xb3, 0x00, 0x1e, 0x35, 0xd8, 0x6c, 0x4e, 0x21, 0x99, 0xd9, 0x76, + 0x10, 0x4b, 0x6a, 0xe3, 0x17, 0x50, 0xa3, 0x6a, 0x72, 0x6e, 0xd2, + 0x85, 0x06, 0x4f, 0x59, 0x81, 0xb5, 0x03, 0x88, 0x9f, 0xef, 0x82, + 0x2f, 0xcd, 0xc2, 0x89, 0x8d, 0xdd, 0xb7, 0x88, 0x9a})), + std::make_pair( + 119, + std::vector<uint8_t>( + {0xe4, 0xb5, 0x56, 0x60, 0x33, 0x86, 0x95, 0x72, 0xed, 0xfd, 0x87, + 0x47, 0x9a, 0x5b, 0xb7, 0x3c, 0x80, 0xe8, 0x75, 0x9b, 0x91, 0x23, + 0x28, 0x79, 0xd9, 0x6b, 0x1d, 0xda, 0x36, 0xc0, 0x12, 0x07, 0x6e, + 0xe5, 0xa2, 0xed, 0x7a, 0xe2, 0xde, 0x63, 0xef, 0x84, 0x06, 0xa0, + 0x6a, 0xea, 0x82, 0xc1, 0x88, 0x03, 0x1b, 0x56, 0x0b, 0xea, 0xfb, + 0x58, 0x3f, 0xb3, 0xde, 0x9e, 0x57, 0x95, 0x2a, 0x7e})), + std::make_pair( + 120, + std::vector<uint8_t>( + {0xe1, 0xb3, 0xe7, 0xed, 0x86, 0x7f, 0x6c, 0x94, 0x84, 0xa2, 0xa9, + 0x7f, 0x77, 0x15, 0xf2, 0x5e, 0x25, 0x29, 0x4e, 0x99, 0x2e, 0x41, + 0xf6, 0xa7, 0xc1, 0x61, 0xff, 0xc2, 0xad, 0xc6, 0xda, 0xae, 0xb7, + 0x11, 0x31, 0x02, 0xd5, 0xe6, 0x09, 0x02, 0x87, 0xfe, 0x6a, 0xd9, + 0x4c, 0xe5, 0xd6, 0xb7, 0x39, 0xc6, 0xca, 0x24, 0x0b, 0x05, 0xc7, + 0x6f, 0xb7, 0x3f, 0x25, 0xdd, 0x02, 0x4b, 0xf9, 0x35})), + std::make_pair( + 121, + std::vector<uint8_t>( + {0x85, 0xfd, 0x08, 0x5f, 0xdc, 0x12, 0xa0, 0x80, 0x98, 0x3d, 0xf0, + 0x7b, 0xd7, 0x01, 0x2b, 0x0d, 0x40, 0x2a, 0x0f, 0x40, 0x43, 0xfc, + 0xb2, 0x77, 0x5a, 0xdf, 0x0b, 0xad, 0x17, 0x4f, 0x9b, 0x08, 0xd1, + 0x67, 0x6e, 0x47, 0x69, 0x85, 0x78, 0x5c, 0x0a, 0x5d, 0xcc, 0x41, + 0xdb, 0xff, 0x6d, 0x95, 0xef, 0x4d, 0x66, 0xa3, 0xfb, 0xdc, 0x4a, + 0x74, 0xb8, 0x2b, 0xa5, 0x2d, 0xa0, 0x51, 0x2b, 0x74})), + std::make_pair( + 122, + std::vector<uint8_t>( + {0xae, 0xd8, 0xfa, 0x76, 0x4b, 0x0f, 0xbf, 0xf8, 0x21, 0xe0, 0x52, + 0x33, 0xd2, 0xf7, 0xb0, 0x90, 0x0e, 0xc4, 0x4d, 0x82, 0x6f, 0x95, + 0xe9, 0x3c, 0x34, 0x3c, 0x1b, 0xc3, 0xba, 0x5a, 0x24, 0x37, 0x4b, + 0x1d, 0x61, 0x6e, 0x7e, 0x7a, 0xba, 0x45, 0x3a, 0x0a, 0xda, 0x5e, + 0x4f, 0xab, 0x53, 0x82, 0x40, 0x9e, 0x0d, 0x42, 0xce, 0x9c, 0x2b, + 0xc7, 0xfb, 0x39, 0xa9, 0x9c, 0x34, 0x0c, 0x20, 0xf0})), + std::make_pair( + 123, + std::vector<uint8_t>( + {0x7b, 0xa3, 0xb2, 0xe2, 0x97, 0x23, 0x35, 0x22, 0xee, 0xb3, 0x43, + 0xbd, 0x3e, 0xbc, 0xfd, 0x83, 0x5a, 0x04, 0x00, 0x77, 0x35, 0xe8, + 0x7f, 0x0c, 0xa3, 0x00, 0xcb, 0xee, 0x6d, 0x41, 0x65, 0x65, 0x16, + 0x21, 0x71, 0x58, 0x1e, 0x40, 0x20, 0xff, 0x4c, 0xf1, 0x76, 0x45, + 0x0f, 0x12, 0x91, 0xea, 0x22, 0x85, 0xcb, 0x9e, 0xbf, 0xfe, 0x4c, + 0x56, 0x66, 0x06, 0x27, 0x68, 0x51, 0x45, 0x05, 0x1c})), + std::make_pair( + 124, + std::vector<uint8_t>( + {0xde, 0x74, 0x8b, 0xcf, 0x89, 0xec, 0x88, 0x08, 0x47, 0x21, 0xe1, + 0x6b, 0x85, 0xf3, 0x0a, 0xdb, 0x1a, 0x61, 0x34, 0xd6, 0x64, 0xb5, + 0x84, 0x35, 0x69, 0xba, 0xbc, 0x5b, 0xbd, 0x1a, 0x15, 0xca, 0x9b, + 0x61, 0x80, 0x3c, 0x90, 0x1a, 0x4f, 0xef, 0x32, 0x96, 0x5a, 0x17, + 0x49, 0xc9, 0xf3, 0xa4, 0xe2, 0x43, 0xe1, 0x73, 0x93, 0x9d, 0xc5, + 0xa8, 0xdc, 0x49, 0x5c, 0x67, 0x1a, 0xb5, 0x21, 0x45})), + std::make_pair( + 125, + std::vector<uint8_t>( + {0xaa, 0xf4, 0xd2, 0xbd, 0xf2, 0x00, 0xa9, 0x19, 0x70, 0x6d, 0x98, + 0x42, 0xdc, 0xe1, 0x6c, 0x98, 0x14, 0x0d, 0x34, 0xbc, 0x43, 0x3d, + 0xf3, 0x20, 0xab, 0xa9, 0xbd, 0x42, 0x9e, 0x54, 0x9a, 0xa7, 0xa3, + 0x39, 0x76, 0x52, 0xa4, 0xd7, 0x68, 0x27, 0x77, 0x86, 0xcf, 0x99, + 0x3c, 0xde, 0x23, 0x38, 0x67, 0x3e, 0xd2, 0xe6, 0xb6, 0x6c, 0x96, + 0x1f, 0xef, 0xb8, 0x2c, 0xd2, 0x0c, 0x93, 0x33, 0x8f})), + std::make_pair( + 126, + std::vector<uint8_t>( + {0xc4, 0x08, 0x21, 0x89, 0x68, 0xb7, 0x88, 0xbf, 0x86, 0x4f, 0x09, + 0x97, 0xe6, 0xbc, 0x4c, 0x3d, 0xba, 0x68, 0xb2, 0x76, 0xe2, 0x12, + 0x5a, 0x48, 0x43, 0x29, 0x60, 0x52, 0xff, 0x93, 0xbf, 0x57, 0x67, + 0xb8, 0xcd, 0xce, 0x71, 0x31, 0xf0, 0x87, 0x64, 0x30, 0xc1, 0x16, + 0x5f, 0xec, 0x6c, 0x4f, 0x47, 0xad, 0xaa, 0x4f, 0xd8, 0xbc, 0xfa, + 0xce, 0xf4, 0x63, 0xb5, 0xd3, 0xd0, 0xfa, 0x61, 0xa0})), + std::make_pair( + 127, + std::vector<uint8_t>( + {0x76, 0xd2, 0xd8, 0x19, 0xc9, 0x2b, 0xce, 0x55, 0xfa, 0x8e, 0x09, + 0x2a, 0xb1, 0xbf, 0x9b, 0x9e, 0xab, 0x23, 0x7a, 0x25, 0x26, 0x79, + 0x86, 0xca, 0xcf, 0x2b, 0x8e, 0xe1, 0x4d, 0x21, 0x4d, 0x73, 0x0d, + 0xc9, 0xa5, 0xaa, 0x2d, 0x7b, 0x59, 0x6e, 0x86, 0xa1, 0xfd, 0x8f, + 0xa0, 0x80, 0x4c, 0x77, 0x40, 0x2d, 0x2f, 0xcd, 0x45, 0x08, 0x36, + 0x88, 0xb2, 0x18, 0xb1, 0xcd, 0xfa, 0x0d, 0xcb, 0xcb})), + std::make_pair( + 128, + std::vector<uint8_t>( + {0x72, 0x06, 0x5e, 0xe4, 0xdd, 0x91, 0xc2, 0xd8, 0x50, 0x9f, 0xa1, + 0xfc, 0x28, 0xa3, 0x7c, 0x7f, 0xc9, 0xfa, 0x7d, 0x5b, 0x3f, 0x8a, + 0xd3, 0xd0, 0xd7, 0xa2, 0x56, 0x26, 0xb5, 0x7b, 0x1b, 0x44, 0x78, + 0x8d, 0x4c, 0xaf, 0x80, 0x62, 0x90, 0x42, 0x5f, 0x98, 0x90, 0xa3, + 0xa2, 0xa3, 0x5a, 0x90, 0x5a, 0xb4, 0xb3, 0x7a, 0xcf, 0xd0, 0xda, + 0x6e, 0x45, 0x17, 0xb2, 0x52, 0x5c, 0x96, 0x51, 0xe4})), + std::make_pair( + 129, + std::vector<uint8_t>( + {0x64, 0x47, 0x5d, 0xfe, 0x76, 0x00, 0xd7, 0x17, 0x1b, 0xea, 0x0b, + 0x39, 0x4e, 0x27, 0xc9, 0xb0, 0x0d, 0x8e, 0x74, 0xdd, 0x1e, 0x41, + 0x6a, 0x79, 0x47, 0x36, 0x82, 0xad, 0x3d, 0xfd, 0xbb, 0x70, 0x66, + 0x31, 0x55, 0x80, 0x55, 0xcf, 0xc8, 0xa4, 0x0e, 0x07, 0xbd, 0x01, + 0x5a, 0x45, 0x40, 0xdc, 0xde, 0xa1, 0x58, 0x83, 0xcb, 0xbf, 0x31, + 0x41, 0x2d, 0xf1, 0xde, 0x1c, 0xd4, 0x15, 0x2b, 0x91})), + std::make_pair( + 130, + std::vector<uint8_t>( + {0x12, 0xcd, 0x16, 0x74, 0xa4, 0x48, 0x8a, 0x5d, 0x7c, 0x2b, 0x31, + 0x60, 0xd2, 0xe2, 0xc4, 0xb5, 0x83, 0x71, 0xbe, 0xda, 0xd7, 0x93, + 0x41, 0x8d, 0x6f, 0x19, 0xc6, 0xee, 0x38, 0x5d, 0x70, 0xb3, 0xe0, + 0x67, 0x39, 0x36, 0x9d, 0x4d, 0xf9, 0x10, 0xed, 0xb0, 0xb0, 0xa5, + 0x4c, 0xbf, 0xf4, 0x3d, 0x54, 0x54, 0x4c, 0xd3, 0x7a, 0xb3, 0xa0, + 0x6c, 0xfa, 0x0a, 0x3d, 0xda, 0xc8, 0xb6, 0x6c, 0x89})), + std::make_pair( + 131, + std::vector<uint8_t>( + {0x60, 0x75, 0x69, 0x66, 0x47, 0x9d, 0xed, 0xc6, 0xdd, 0x4b, 0xcf, + 0xf8, 0xea, 0x7d, 0x1d, 0x4c, 0xe4, 0xd4, 0xaf, 0x2e, 0x7b, 0x09, + 0x7e, 0x32, 0xe3, 0x76, 0x35, 0x18, 0x44, 0x11, 0x47, 0xcc, 0x12, + 0xb3, 0xc0, 0xee, 0x6d, 0x2e, 0xca, 0xbf, 0x11, 0x98, 0xce, 0xc9, + 0x2e, 0x86, 0xa3, 0x61, 0x6f, 0xba, 0x4f, 0x4e, 0x87, 0x2f, 0x58, + 0x25, 0x33, 0x0a, 0xdb, 0xb4, 0xc1, 0xde, 0xe4, 0x44})), + std::make_pair( + 132, + std::vector<uint8_t>( + {0xa7, 0x80, 0x3b, 0xcb, 0x71, 0xbc, 0x1d, 0x0f, 0x43, 0x83, 0xdd, + 0xe1, 0xe0, 0x61, 0x2e, 0x04, 0xf8, 0x72, 0xb7, 0x15, 0xad, 0x30, + 0x81, 0x5c, 0x22, 0x49, 0xcf, 0x34, 0xab, 0xb8, 0xb0, 0x24, 0x91, + 0x5c, 0xb2, 0xfc, 0x9f, 0x4e, 0x7c, 0xc4, 0xc8, 0xcf, 0xd4, 0x5b, + 0xe2, 0xd5, 0xa9, 0x1e, 0xab, 0x09, 0x41, 0xc7, 0xd2, 0x70, 0xe2, + 0xda, 0x4c, 0xa4, 0xa9, 0xf7, 0xac, 0x68, 0x66, 0x3a})), + std::make_pair( + 133, + std::vector<uint8_t>( + {0xb8, 0x4e, 0xf6, 0xa7, 0x22, 0x9a, 0x34, 0xa7, 0x50, 0xd9, 0xa9, + 0x8e, 0xe2, 0x52, 0x98, 0x71, 0x81, 0x6b, 0x87, 0xfb, 0xe3, 0xbc, + 0x45, 0xb4, 0x5f, 0xa5, 0xae, 0x82, 0xd5, 0x14, 0x15, 0x40, 0x21, + 0x11, 0x65, 0xc3, 0xc5, 0xd7, 0xa7, 0x47, 0x6b, 0xa5, 0xa4, 0xaa, + 0x06, 0xd6, 0x64, 0x76, 0xf0, 0xd9, 0xdc, 0x49, 0xa3, 0xf1, 0xee, + 0x72, 0xc3, 0xac, 0xab, 0xd4, 0x98, 0x96, 0x74, 0x14})), + std::make_pair( + 134, + std::vector<uint8_t>( + {0xfa, 0xe4, 0xb6, 0xd8, 0xef, 0xc3, 0xf8, 0xc8, 0xe6, 0x4d, 0x00, + 0x1d, 0xab, 0xec, 0x3a, 0x21, 0xf5, 0x44, 0xe8, 0x27, 0x14, 0x74, + 0x52, 0x51, 0xb2, 0xb4, 0xb3, 0x93, 0xf2, 0xf4, 0x3e, 0x0d, 0xa3, + 0xd4, 0x03, 0xc6, 0x4d, 0xb9, 0x5a, 0x2c, 0xb6, 0xe2, 0x3e, 0xbb, + 0x7b, 0x9e, 0x94, 0xcd, 0xd5, 0xdd, 0xac, 0x54, 0xf0, 0x7c, 0x4a, + 0x61, 0xbd, 0x3c, 0xb1, 0x0a, 0xa6, 0xf9, 0x3b, 0x49})), + std::make_pair( + 135, + std::vector<uint8_t>( + {0x34, 0xf7, 0x28, 0x66, 0x05, 0xa1, 0x22, 0x36, 0x95, 0x40, 0x14, + 0x1d, 0xed, 0x79, 0xb8, 0x95, 0x72, 0x55, 0xda, 0x2d, 0x41, 0x55, + 0xab, 0xbf, 0x5a, 0x8d, 0xbb, 0x89, 0xc8, 0xeb, 0x7e, 0xde, 0x8e, + 0xee, 0xf1, 0xda, 0xa4, 0x6d, 0xc2, 0x9d, 0x75, 0x1d, 0x04, 0x5d, + 0xc3, 0xb1, 0xd6, 0x58, 0xbb, 0x64, 0xb8, 0x0f, 0xf8, 0x58, 0x9e, + 0xdd, 0xb3, 0x82, 0x4b, 0x13, 0xda, 0x23, 0x5a, 0x6b})), + std::make_pair( + 136, + std::vector<uint8_t>( + {0x3b, 0x3b, 0x48, 0x43, 0x4b, 0xe2, 0x7b, 0x9e, 0xab, 0xab, 0xba, + 0x43, 0xbf, 0x6b, 0x35, 0xf1, 0x4b, 0x30, 0xf6, 0xa8, 0x8d, 0xc2, + 0xe7, 0x50, 0xc3, 0x58, 0x47, 0x0d, 0x6b, 0x3a, 0xa3, 0xc1, 0x8e, + 0x47, 0xdb, 0x40, 0x17, 0xfa, 0x55, 0x10, 0x6d, 0x82, 0x52, 0xf0, + 0x16, 0x37, 0x1a, 0x00, 0xf5, 0xf8, 0xb0, 0x70, 0xb7, 0x4b, 0xa5, + 0xf2, 0x3c, 0xff, 0xc5, 0x51, 0x1c, 0x9f, 0x09, 0xf0})), + std::make_pair( + 137, + std::vector<uint8_t>( + {0xba, 0x28, 0x9e, 0xbd, 0x65, 0x62, 0xc4, 0x8c, 0x3e, 0x10, 0xa8, + 0xad, 0x6c, 0xe0, 0x2e, 0x73, 0x43, 0x3d, 0x1e, 0x93, 0xd7, 0xc9, + 0x27, 0x9d, 0x4d, 0x60, 0xa7, 0xe8, 0x79, 0xee, 0x11, 0xf4, 0x41, + 0xa0, 0x00, 0xf4, 0x8e, 0xd9, 0xf7, 0xc4, 0xed, 0x87, 0xa4, 0x51, + 0x36, 0xd7, 0xdc, 0xcd, 0xca, 0x48, 0x21, 0x09, 0xc7, 0x8a, 0x51, + 0x06, 0x2b, 0x3b, 0xa4, 0x04, 0x4a, 0xda, 0x24, 0x69})), + std::make_pair( + 138, + std::vector<uint8_t>( + {0x02, 0x29, 0x39, 0xe2, 0x38, 0x6c, 0x5a, 0x37, 0x04, 0x98, 0x56, + 0xc8, 0x50, 0xa2, 0xbb, 0x10, 0xa1, 0x3d, 0xfe, 0xa4, 0x21, 0x2b, + 0x4c, 0x73, 0x2a, 0x88, 0x40, 0xa9, 0xff, 0xa5, 0xfa, 0xf5, 0x48, + 0x75, 0xc5, 0x44, 0x88, 0x16, 0xb2, 0x78, 0x5a, 0x00, 0x7d, 0xa8, + 0xa8, 0xd2, 0xbc, 0x7d, 0x71, 0xa5, 0x4e, 0x4e, 0x65, 0x71, 0xf1, + 0x0b, 0x60, 0x0c, 0xbd, 0xb2, 0x5d, 0x13, 0xed, 0xe3})), + std::make_pair( + 139, + std::vector<uint8_t>( + {0xe6, 0xfe, 0xc1, 0x9d, 0x89, 0xce, 0x87, 0x17, 0xb1, 0xa0, 0x87, + 0x02, 0x46, 0x70, 0xfe, 0x02, 0x6f, 0x6c, 0x7c, 0xbd, 0xa1, 0x1c, + 0xae, 0xf9, 0x59, 0xbb, 0x2d, 0x35, 0x1b, 0xf8, 0x56, 0xf8, 0x05, + 0x5d, 0x1c, 0x0e, 0xbd, 0xaa, 0xa9, 0xd1, 0xb1, 0x78, 0x86, 0xfc, + 0x2c, 0x56, 0x2b, 0x5e, 0x99, 0x64, 0x2f, 0xc0, 0x64, 0x71, 0x0c, + 0x0d, 0x34, 0x88, 0xa0, 0x2b, 0x5e, 0xd7, 0xf6, 0xfd})), + std::make_pair( + 140, + std::vector<uint8_t>( + {0x94, 0xc9, 0x6f, 0x02, 0xa8, 0xf5, 0x76, 0xac, 0xa3, 0x2b, 0xa6, + 0x1c, 0x2b, 0x20, 0x6f, 0x90, 0x72, 0x85, 0xd9, 0x29, 0x9b, 0x83, + 0xac, 0x17, 0x5c, 0x20, 0x9a, 0x8d, 0x43, 0xd5, 0x3b, 0xfe, 0x68, + 0x3d, 0xd1, 0xd8, 0x3e, 0x75, 0x49, 0xcb, 0x90, 0x6c, 0x28, 0xf5, + 0x9a, 0xb7, 0xc4, 0x6f, 0x87, 0x51, 0x36, 0x6a, 0x28, 0xc3, 0x9d, + 0xd5, 0xfe, 0x26, 0x93, 0xc9, 0x01, 0x96, 0x66, 0xc8})), + std::make_pair( + 141, + std::vector<uint8_t>( + {0x31, 0xa0, 0xcd, 0x21, 0x5e, 0xbd, 0x2c, 0xb6, 0x1d, 0xe5, 0xb9, + 0xed, 0xc9, 0x1e, 0x61, 0x95, 0xe3, 0x1c, 0x59, 0xa5, 0x64, 0x8d, + 0x5c, 0x9f, 0x73, 0x7e, 0x12, 0x5b, 0x26, 0x05, 0x70, 0x8f, 0x2e, + 0x32, 0x5a, 0xb3, 0x38, 0x1c, 0x8d, 0xce, 0x1a, 0x3e, 0x95, 0x88, + 0x86, 0xf1, 0xec, 0xdc, 0x60, 0x31, 0x8f, 0x88, 0x2c, 0xfe, 0x20, + 0xa2, 0x41, 0x91, 0x35, 0x2e, 0x61, 0x7b, 0x0f, 0x21})), + std::make_pair( + 142, + std::vector<uint8_t>( + {0x91, 0xab, 0x50, 0x4a, 0x52, 0x2d, 0xce, 0x78, 0x77, 0x9f, 0x4c, + 0x6c, 0x6b, 0xa2, 0xe6, 0xb6, 0xdb, 0x55, 0x65, 0xc7, 0x6d, 0x3e, + 0x7e, 0x7c, 0x92, 0x0c, 0xaf, 0x7f, 0x75, 0x7e, 0xf9, 0xdb, 0x7c, + 0x8f, 0xcf, 0x10, 0xe5, 0x7f, 0x03, 0x37, 0x9e, 0xa9, 0xbf, 0x75, + 0xeb, 0x59, 0x89, 0x5d, 0x96, 0xe1, 0x49, 0x80, 0x0b, 0x6a, 0xae, + 0x01, 0xdb, 0x77, 0x8b, 0xb9, 0x0a, 0xfb, 0xc9, 0x89})), + std::make_pair( + 143, + std::vector<uint8_t>( + {0xd8, 0x5c, 0xab, 0xc6, 0xbd, 0x5b, 0x1a, 0x01, 0xa5, 0xaf, 0xd8, + 0xc6, 0x73, 0x47, 0x40, 0xda, 0x9f, 0xd1, 0xc1, 0xac, 0xc6, 0xdb, + 0x29, 0xbf, 0xc8, 0xa2, 0xe5, 0xb6, 0x68, 0xb0, 0x28, 0xb6, 0xb3, + 0x15, 0x4b, 0xfb, 0x87, 0x03, 0xfa, 0x31, 0x80, 0x25, 0x1d, 0x58, + 0x9a, 0xd3, 0x80, 0x40, 0xce, 0xb7, 0x07, 0xc4, 0xba, 0xd1, 0xb5, + 0x34, 0x3c, 0xb4, 0x26, 0xb6, 0x1e, 0xaa, 0x49, 0xc1})), + std::make_pair( + 144, + std::vector<uint8_t>( + {0xd6, 0x2e, 0xfb, 0xec, 0x2c, 0xa9, 0xc1, 0xf8, 0xbd, 0x66, 0xce, + 0x8b, 0x3f, 0x6a, 0x89, 0x8c, 0xb3, 0xf7, 0x56, 0x6b, 0xa6, 0x56, + 0x8c, 0x61, 0x8a, 0xd1, 0xfe, 0xb2, 0xb6, 0x5b, 0x76, 0xc3, 0xce, + 0x1d, 0xd2, 0x0f, 0x73, 0x95, 0x37, 0x2f, 0xaf, 0x28, 0x42, 0x7f, + 0x61, 0xc9, 0x27, 0x80, 0x49, 0xcf, 0x01, 0x40, 0xdf, 0x43, 0x4f, + 0x56, 0x33, 0x04, 0x8c, 0x86, 0xb8, 0x1e, 0x03, 0x99})), + std::make_pair( + 145, + std::vector<uint8_t>( + {0x7c, 0x8f, 0xdc, 0x61, 0x75, 0x43, 0x9e, 0x2c, 0x3d, 0xb1, 0x5b, + 0xaf, 0xa7, 0xfb, 0x06, 0x14, 0x3a, 0x6a, 0x23, 0xbc, 0x90, 0xf4, + 0x49, 0xe7, 0x9d, 0xee, 0xf7, 0x3c, 0x3d, 0x49, 0x2a, 0x67, 0x17, + 0x15, 0xc1, 0x93, 0xb6, 0xfe, 0xa9, 0xf0, 0x36, 0x05, 0x0b, 0x94, + 0x60, 0x69, 0x85, 0x6b, 0x89, 0x7e, 0x08, 0xc0, 0x07, 0x68, 0xf5, + 0xee, 0x5d, 0xdc, 0xf7, 0x0b, 0x7c, 0xd6, 0xd0, 0xe0})), + std::make_pair( + 146, + std::vector<uint8_t>( + {0x58, 0x60, 0x2e, 0xe7, 0x46, 0x8e, 0x6b, 0xc9, 0xdf, 0x21, 0xbd, + 0x51, 0xb2, 0x3c, 0x00, 0x5f, 0x72, 0xd6, 0xcb, 0x01, 0x3f, 0x0a, + 0x1b, 0x48, 0xcb, 0xec, 0x5e, 0xca, 0x29, 0x92, 0x99, 0xf9, 0x7f, + 0x09, 0xf5, 0x4a, 0x9a, 0x01, 0x48, 0x3e, 0xae, 0xb3, 0x15, 0xa6, + 0x47, 0x8b, 0xad, 0x37, 0xba, 0x47, 0xca, 0x13, 0x47, 0xc7, 0xc8, + 0xfc, 0x9e, 0x66, 0x95, 0x59, 0x2c, 0x91, 0xd7, 0x23})), + std::make_pair( + 147, + std::vector<uint8_t>( + {0x27, 0xf5, 0xb7, 0x9e, 0xd2, 0x56, 0xb0, 0x50, 0x99, 0x3d, 0x79, + 0x34, 0x96, 0xed, 0xf4, 0x80, 0x7c, 0x1d, 0x85, 0xa7, 0xb0, 0xa6, + 0x7c, 0x9c, 0x4f, 0xa9, 0x98, 0x60, 0x75, 0x0b, 0x0a, 0xe6, 0x69, + 0x89, 0x67, 0x0a, 0x8f, 0xfd, 0x78, 0x56, 0xd7, 0xce, 0x41, 0x15, + 0x99, 0xe5, 0x8c, 0x4d, 0x77, 0xb2, 0x32, 0xa6, 0x2b, 0xef, 0x64, + 0xd1, 0x52, 0x75, 0xbe, 0x46, 0xa6, 0x82, 0x35, 0xff})), + std::make_pair( + 148, + std::vector<uint8_t>( + {0x39, 0x57, 0xa9, 0x76, 0xb9, 0xf1, 0x88, 0x7b, 0xf0, 0x04, 0xa8, + 0xdc, 0xa9, 0x42, 0xc9, 0x2d, 0x2b, 0x37, 0xea, 0x52, 0x60, 0x0f, + 0x25, 0xe0, 0xc9, 0xbc, 0x57, 0x07, 0xd0, 0x27, 0x9c, 0x00, 0xc6, + 0xe8, 0x5a, 0x83, 0x9b, 0x0d, 0x2d, 0x8e, 0xb5, 0x9c, 0x51, 0xd9, + 0x47, 0x88, 0xeb, 0xe6, 0x24, 0x74, 0xa7, 0x91, 0xca, 0xdf, 0x52, + 0xcc, 0xcf, 0x20, 0xf5, 0x07, 0x0b, 0x65, 0x73, 0xfc})), + std::make_pair( + 149, + std::vector<uint8_t>( + {0xea, 0xa2, 0x37, 0x6d, 0x55, 0x38, 0x0b, 0xf7, 0x72, 0xec, 0xca, + 0x9c, 0xb0, 0xaa, 0x46, 0x68, 0xc9, 0x5c, 0x70, 0x71, 0x62, 0xfa, + 0x86, 0xd5, 0x18, 0xc8, 0xce, 0x0c, 0xa9, 0xbf, 0x73, 0x62, 0xb9, + 0xf2, 0xa0, 0xad, 0xc3, 0xff, 0x59, 0x92, 0x2d, 0xf9, 0x21, 0xb9, + 0x45, 0x67, 0xe8, 0x1e, 0x45, 0x2f, 0x6c, 0x1a, 0x07, 0xfc, 0x81, + 0x7c, 0xeb, 0xe9, 0x96, 0x04, 0xb3, 0x50, 0x5d, 0x38})), + std::make_pair( + 150, + std::vector<uint8_t>( + {0xc1, 0xe2, 0xc7, 0x8b, 0x6b, 0x27, 0x34, 0xe2, 0x48, 0x0e, 0xc5, + 0x50, 0x43, 0x4c, 0xb5, 0xd6, 0x13, 0x11, 0x1a, 0xdc, 0xc2, 0x1d, + 0x47, 0x55, 0x45, 0xc3, 0xb1, 0xb7, 0xe6, 0xff, 0x12, 0x44, 0x44, + 0x76, 0xe5, 0xc0, 0x55, 0x13, 0x2e, 0x22, 0x29, 0xdc, 0x0f, 0x80, + 0x70, 0x44, 0xbb, 0x91, 0x9b, 0x1a, 0x56, 0x62, 0xdd, 0x38, 0xa9, + 0xee, 0x65, 0xe2, 0x43, 0xa3, 0x91, 0x1a, 0xed, 0x1a})), + std::make_pair( + 151, + std::vector<uint8_t>( + {0x8a, 0xb4, 0x87, 0x13, 0x38, 0x9d, 0xd0, 0xfc, 0xf9, 0xf9, 0x65, + 0xd3, 0xce, 0x66, 0xb1, 0xe5, 0x59, 0xa1, 0xf8, 0xc5, 0x87, 0x41, + 0xd6, 0x76, 0x83, 0xcd, 0x97, 0x13, 0x54, 0xf4, 0x52, 0xe6, 0x2d, + 0x02, 0x07, 0xa6, 0x5e, 0x43, 0x6c, 0x5d, 0x5d, 0x8f, 0x8e, 0xe7, + 0x1c, 0x6a, 0xbf, 0xe5, 0x0e, 0x66, 0x90, 0x04, 0xc3, 0x02, 0xb3, + 0x1a, 0x7e, 0xa8, 0x31, 0x1d, 0x4a, 0x91, 0x60, 0x51})), + std::make_pair( + 152, + std::vector<uint8_t>( + {0x24, 0xce, 0x0a, 0xdd, 0xaa, 0x4c, 0x65, 0x03, 0x8b, 0xd1, 0xb1, + 0xc0, 0xf1, 0x45, 0x2a, 0x0b, 0x12, 0x87, 0x77, 0xaa, 0xbc, 0x94, + 0xa2, 0x9d, 0xf2, 0xfd, 0x6c, 0x7e, 0x2f, 0x85, 0xf8, 0xab, 0x9a, + 0xc7, 0xef, 0xf5, 0x16, 0xb0, 0xe0, 0xa8, 0x25, 0xc8, 0x4a, 0x24, + 0xcf, 0xe4, 0x92, 0xea, 0xad, 0x0a, 0x63, 0x08, 0xe4, 0x6d, 0xd4, + 0x2f, 0xe8, 0x33, 0x3a, 0xb9, 0x71, 0xbb, 0x30, 0xca})), + std::make_pair( + 153, + std::vector<uint8_t>( + {0x51, 0x54, 0xf9, 0x29, 0xee, 0x03, 0x04, 0x5b, 0x6b, 0x0c, 0x00, + 0x04, 0xfa, 0x77, 0x8e, 0xde, 0xe1, 0xd1, 0x39, 0x89, 0x32, 0x67, + 0xcc, 0x84, 0x82, 0x5a, 0xd7, 0xb3, 0x6c, 0x63, 0xde, 0x32, 0x79, + 0x8e, 0x4a, 0x16, 0x6d, 0x24, 0x68, 0x65, 0x61, 0x35, 0x4f, 0x63, + 0xb0, 0x07, 0x09, 0xa1, 0x36, 0x4b, 0x3c, 0x24, 0x1d, 0xe3, 0xfe, + 0xbf, 0x07, 0x54, 0x04, 0x58, 0x97, 0x46, 0x7c, 0xd4})), + std::make_pair( + 154, + std::vector<uint8_t>( + {0xe7, 0x4e, 0x90, 0x79, 0x20, 0xfd, 0x87, 0xbd, 0x5a, 0xd6, 0x36, + 0xdd, 0x11, 0x08, 0x5e, 0x50, 0xee, 0x70, 0x45, 0x9c, 0x44, 0x3e, + 0x1c, 0xe5, 0x80, 0x9a, 0xf2, 0xbc, 0x2e, 0xba, 0x39, 0xf9, 0xe6, + 0xd7, 0x12, 0x8e, 0x0e, 0x37, 0x12, 0xc3, 0x16, 0xda, 0x06, 0xf4, + 0x70, 0x5d, 0x78, 0xa4, 0x83, 0x8e, 0x28, 0x12, 0x1d, 0x43, 0x44, + 0xa2, 0xc7, 0x9c, 0x5e, 0x0d, 0xb3, 0x07, 0xa6, 0x77})), + std::make_pair( + 155, + std::vector<uint8_t>( + {0xbf, 0x91, 0xa2, 0x23, 0x34, 0xba, 0xc2, 0x0f, 0x3f, 0xd8, 0x06, + 0x63, 0xb3, 0xcd, 0x06, 0xc4, 0xe8, 0x80, 0x2f, 0x30, 0xe6, 0xb5, + 0x9f, 0x90, 0xd3, 0x03, 0x5c, 0xc9, 0x79, 0x8a, 0x21, 0x7e, 0xd5, + 0xa3, 0x1a, 0xbb, 0xda, 0x7f, 0xa6, 0x84, 0x28, 0x27, 0xbd, 0xf2, + 0xa7, 0xa1, 0xc2, 0x1f, 0x6f, 0xcf, 0xcc, 0xbb, 0x54, 0xc6, 0xc5, + 0x29, 0x26, 0xf3, 0x2d, 0xa8, 0x16, 0x26, 0x9b, 0xe1})), + std::make_pair( + 156, + std::vector<uint8_t>( + {0xd9, 0xd5, 0xc7, 0x4b, 0xe5, 0x12, 0x1b, 0x0b, 0xd7, 0x42, 0xf2, + 0x6b, 0xff, 0xb8, 0xc8, 0x9f, 0x89, 0x17, 0x1f, 0x3f, 0x93, 0x49, + 0x13, 0x49, 0x2b, 0x09, 0x03, 0xc2, 0x71, 0xbb, 0xe2, 0xb3, 0x39, + 0x5e, 0xf2, 0x59, 0x66, 0x9b, 0xef, 0x43, 0xb5, 0x7f, 0x7f, 0xcc, + 0x30, 0x27, 0xdb, 0x01, 0x82, 0x3f, 0x6b, 0xae, 0xe6, 0x6e, 0x4f, + 0x9f, 0xea, 0xd4, 0xd6, 0x72, 0x6c, 0x74, 0x1f, 0xce})), + std::make_pair( + 157, + std::vector<uint8_t>( + {0x50, 0xc8, 0xb8, 0xcf, 0x34, 0xcd, 0x87, 0x9f, 0x80, 0xe2, 0xfa, + 0xab, 0x32, 0x30, 0xb0, 0xc0, 0xe1, 0xcc, 0x3e, 0x9d, 0xca, 0xde, + 0xb1, 0xb9, 0xd9, 0x7a, 0xb9, 0x23, 0x41, 0x5d, 0xd9, 0xa1, 0xfe, + 0x38, 0xad, 0xdd, 0x5c, 0x11, 0x75, 0x6c, 0x67, 0x99, 0x0b, 0x25, + 0x6e, 0x95, 0xad, 0x6d, 0x8f, 0x9f, 0xed, 0xce, 0x10, 0xbf, 0x1c, + 0x90, 0x67, 0x9c, 0xde, 0x0e, 0xcf, 0x1b, 0xe3, 0x47})), + std::make_pair( + 158, + std::vector<uint8_t>( + {0x0a, 0x38, 0x6e, 0x7c, 0xd5, 0xdd, 0x9b, 0x77, 0xa0, 0x35, 0xe0, + 0x9f, 0xe6, 0xfe, 0xe2, 0xc8, 0xce, 0x61, 0xb5, 0x38, 0x3c, 0x87, + 0xea, 0x43, 0x20, 0x50, 0x59, 0xc5, 0xe4, 0xcd, 0x4f, 0x44, 0x08, + 0x31, 0x9b, 0xb0, 0xa8, 0x23, 0x60, 0xf6, 0xa5, 0x8e, 0x6c, 0x9c, + 0xe3, 0xf4, 0x87, 0xc4, 0x46, 0x06, 0x3b, 0xf8, 0x13, 0xbc, 0x6b, + 0xa5, 0x35, 0xe1, 0x7f, 0xc1, 0x82, 0x6c, 0xfc, 0x91})), + std::make_pair( + 159, + std::vector<uint8_t>( + {0x1f, 0x14, 0x59, 0xcb, 0x6b, 0x61, 0xcb, 0xac, 0x5f, 0x0e, 0xfe, + 0x8f, 0xc4, 0x87, 0x53, 0x8f, 0x42, 0x54, 0x89, 0x87, 0xfc, 0xd5, + 0x62, 0x21, 0xcf, 0xa7, 0xbe, 0xb2, 0x25, 0x04, 0x76, 0x9e, 0x79, + 0x2c, 0x45, 0xad, 0xfb, 0x1d, 0x6b, 0x3d, 0x60, 0xd7, 0xb7, 0x49, + 0xc8, 0xa7, 0x5b, 0x0b, 0xdf, 0x14, 0xe8, 0xea, 0x72, 0x1b, 0x95, + 0xdc, 0xa5, 0x38, 0xca, 0x6e, 0x25, 0x71, 0x12, 0x09})), + std::make_pair( + 160, + std::vector<uint8_t>( + {0xe5, 0x8b, 0x38, 0x36, 0xb7, 0xd8, 0xfe, 0xdb, 0xb5, 0x0c, 0xa5, + 0x72, 0x5c, 0x65, 0x71, 0xe7, 0x4c, 0x07, 0x85, 0xe9, 0x78, 0x21, + 0xda, 0xb8, 0xb6, 0x29, 0x8c, 0x10, 0xe4, 0xc0, 0x79, 0xd4, 0xa6, + 0xcd, 0xf2, 0x2f, 0x0f, 0xed, 0xb5, 0x50, 0x32, 0x92, 0x5c, 0x16, + 0x74, 0x81, 0x15, 0xf0, 0x1a, 0x10, 0x5e, 0x77, 0xe0, 0x0c, 0xee, + 0x3d, 0x07, 0x92, 0x4d, 0xc0, 0xd8, 0xf9, 0x06, 0x59})), + std::make_pair( + 161, + std::vector<uint8_t>( + {0xb9, 0x29, 0xcc, 0x65, 0x05, 0xf0, 0x20, 0x15, 0x86, 0x72, 0xde, + 0xda, 0x56, 0xd0, 0xdb, 0x08, 0x1a, 0x2e, 0xe3, 0x4c, 0x00, 0xc1, + 0x10, 0x00, 0x29, 0xbd, 0xf8, 0xea, 0x98, 0x03, 0x4f, 0xa4, 0xbf, + 0x3e, 0x86, 0x55, 0xec, 0x69, 0x7f, 0xe3, 0x6f, 0x40, 0x55, 0x3c, + 0x5b, 0xb4, 0x68, 0x01, 0x64, 0x4a, 0x62, 0x7d, 0x33, 0x42, 0xf4, + 0xfc, 0x92, 0xb6, 0x1f, 0x03, 0x29, 0x0f, 0xb3, 0x81})), + std::make_pair( + 162, + std::vector<uint8_t>( + {0x72, 0xd3, 0x53, 0x99, 0x4b, 0x49, 0xd3, 0xe0, 0x31, 0x53, 0x92, + 0x9a, 0x1e, 0x4d, 0x4f, 0x18, 0x8e, 0xe5, 0x8a, 0xb9, 0xe7, 0x2e, + 0xe8, 0xe5, 0x12, 0xf2, 0x9b, 0xc7, 0x73, 0x91, 0x38, 0x19, 0xce, + 0x05, 0x7d, 0xdd, 0x70, 0x02, 0xc0, 0x43, 0x3e, 0xe0, 0xa1, 0x61, + 0x14, 0xe3, 0xd1, 0x56, 0xdd, 0x2c, 0x4a, 0x7e, 0x80, 0xee, 0x53, + 0x37, 0x8b, 0x86, 0x70, 0xf2, 0x3e, 0x33, 0xef, 0x56})), + std::make_pair( + 163, + std::vector<uint8_t>( + {0xc7, 0x0e, 0xf9, 0xbf, 0xd7, 0x75, 0xd4, 0x08, 0x17, 0x67, 0x37, + 0xa0, 0x73, 0x6d, 0x68, 0x51, 0x7c, 0xe1, 0xaa, 0xad, 0x7e, 0x81, + 0xa9, 0x3c, 0x8c, 0x1e, 0xd9, 0x67, 0xea, 0x21, 0x4f, 0x56, 0xc8, + 0xa3, 0x77, 0xb1, 0x76, 0x3e, 0x67, 0x66, 0x15, 0xb6, 0x0f, 0x39, + 0x88, 0x24, 0x1e, 0xae, 0x6e, 0xab, 0x96, 0x85, 0xa5, 0x12, 0x49, + 0x29, 0xd2, 0x81, 0x88, 0xf2, 0x9e, 0xab, 0x06, 0xf7})), + std::make_pair( + 164, + std::vector<uint8_t>( + {0xc2, 0x30, 0xf0, 0x80, 0x26, 0x79, 0xcb, 0x33, 0x82, 0x2e, 0xf8, + 0xb3, 0xb2, 0x1b, 0xf7, 0xa9, 0xa2, 0x89, 0x42, 0x09, 0x29, 0x01, + 0xd7, 0xda, 0xc3, 0x76, 0x03, 0x00, 0x83, 0x10, 0x26, 0xcf, 0x35, + 0x4c, 0x92, 0x32, 0xdf, 0x3e, 0x08, 0x4d, 0x99, 0x03, 0x13, 0x0c, + 0x60, 0x1f, 0x63, 0xc1, 0xf4, 0xa4, 0xa4, 0xb8, 0x10, 0x6e, 0x46, + 0x8c, 0xd4, 0x43, 0xbb, 0xe5, 0xa7, 0x34, 0xf4, 0x5f})), + std::make_pair( + 165, + std::vector<uint8_t>( + {0x6f, 0x43, 0x09, 0x4c, 0xaf, 0xb5, 0xeb, 0xf1, 0xf7, 0xa4, 0x93, + 0x7e, 0xc5, 0x0f, 0x56, 0xa4, 0xc9, 0xda, 0x30, 0x3c, 0xbb, 0x55, + 0xac, 0x1f, 0x27, 0xf1, 0xf1, 0x97, 0x6c, 0xd9, 0x6b, 0xed, 0xa9, + 0x46, 0x4f, 0x0e, 0x7b, 0x9c, 0x54, 0x62, 0x0b, 0x8a, 0x9f, 0xba, + 0x98, 0x31, 0x64, 0xb8, 0xbe, 0x35, 0x78, 0x42, 0x5a, 0x02, 0x4f, + 0x5f, 0xe1, 0x99, 0xc3, 0x63, 0x56, 0xb8, 0x89, 0x72})), + std::make_pair( + 166, + std::vector<uint8_t>( + {0x37, 0x45, 0x27, 0x3f, 0x4c, 0x38, 0x22, 0x5d, 0xb2, 0x33, 0x73, + 0x81, 0x87, 0x1a, 0x0c, 0x6a, 0xaf, 0xd3, 0xaf, 0x9b, 0x01, 0x8c, + 0x88, 0xaa, 0x02, 0x02, 0x58, 0x50, 0xa5, 0xdc, 0x3a, 0x42, 0xa1, + 0xa3, 0xe0, 0x3e, 0x56, 0xcb, 0xf1, 0xb0, 0x87, 0x6d, 0x63, 0xa4, + 0x41, 0xf1, 0xd2, 0x85, 0x6a, 0x39, 0xb8, 0x80, 0x1e, 0xb5, 0xaf, + 0x32, 0x52, 0x01, 0xc4, 0x15, 0xd6, 0x5e, 0x97, 0xfe})), + std::make_pair( + 167, + std::vector<uint8_t>( + {0xc5, 0x0c, 0x44, 0xcc, 0xa3, 0xec, 0x3e, 0xda, 0xae, 0x77, 0x9a, + 0x7e, 0x17, 0x94, 0x50, 0xeb, 0xdd, 0xa2, 0xf9, 0x70, 0x67, 0xc6, + 0x90, 0xaa, 0x6c, 0x5a, 0x4a, 0xc7, 0xc3, 0x01, 0x39, 0xbb, 0x27, + 0xc0, 0xdf, 0x4d, 0xb3, 0x22, 0x0e, 0x63, 0xcb, 0x11, 0x0d, 0x64, + 0xf3, 0x7f, 0xfe, 0x07, 0x8d, 0xb7, 0x26, 0x53, 0xe2, 0xda, 0xac, + 0xf9, 0x3a, 0xe3, 0xf0, 0xa2, 0xd1, 0xa7, 0xeb, 0x2e})), + std::make_pair( + 168, + std::vector<uint8_t>( + {0x8a, 0xef, 0x26, 0x3e, 0x38, 0x5c, 0xbc, 0x61, 0xe1, 0x9b, 0x28, + 0x91, 0x42, 0x43, 0x26, 0x2a, 0xf5, 0xaf, 0xe8, 0x72, 0x6a, 0xf3, + 0xce, 0x39, 0xa7, 0x9c, 0x27, 0x02, 0x8c, 0xf3, 0xec, 0xd3, 0xf8, + 0xd2, 0xdf, 0xd9, 0xcf, 0xc9, 0xad, 0x91, 0xb5, 0x8f, 0x6f, 0x20, + 0x77, 0x8f, 0xd5, 0xf0, 0x28, 0x94, 0xa3, 0xd9, 0x1c, 0x7d, 0x57, + 0xd1, 0xe4, 0xb8, 0x66, 0xa7, 0xf3, 0x64, 0xb6, 0xbe})), + std::make_pair( + 169, + std::vector<uint8_t>( + {0x28, 0x69, 0x61, 0x41, 0xde, 0x6e, 0x2d, 0x9b, 0xcb, 0x32, 0x35, + 0x57, 0x8a, 0x66, 0x16, 0x6c, 0x14, 0x48, 0xd3, 0xe9, 0x05, 0xa1, + 0xb4, 0x82, 0xd4, 0x23, 0xbe, 0x4b, 0xc5, 0x36, 0x9b, 0xc8, 0xc7, + 0x4d, 0xae, 0x0a, 0xcc, 0x9c, 0xc1, 0x23, 0xe1, 0xd8, 0xdd, 0xce, + 0x9f, 0x97, 0x91, 0x7e, 0x8c, 0x01, 0x9c, 0x55, 0x2d, 0xa3, 0x2d, + 0x39, 0xd2, 0x21, 0x9b, 0x9a, 0xbf, 0x0f, 0xa8, 0xc8})), + std::make_pair( + 170, + std::vector<uint8_t>( + {0x2f, 0xb9, 0xeb, 0x20, 0x85, 0x83, 0x01, 0x81, 0x90, 0x3a, 0x9d, + 0xaf, 0xe3, 0xdb, 0x42, 0x8e, 0xe1, 0x5b, 0xe7, 0x66, 0x22, 0x24, + 0xef, 0xd6, 0x43, 0x37, 0x1f, 0xb2, 0x56, 0x46, 0xae, 0xe7, 0x16, + 0xe5, 0x31, 0xec, 0xa6, 0x9b, 0x2b, 0xdc, 0x82, 0x33, 0xf1, 0xa8, + 0x08, 0x1f, 0xa4, 0x3d, 0xa1, 0x50, 0x03, 0x02, 0x97, 0x5a, 0x77, + 0xf4, 0x2f, 0xa5, 0x92, 0x13, 0x67, 0x10, 0xe9, 0xdc})), + std::make_pair( + 171, + std::vector<uint8_t>( + {0x66, 0xf9, 0xa7, 0x14, 0x3f, 0x7a, 0x33, 0x14, 0xa6, 0x69, 0xbf, + 0x2e, 0x24, 0xbb, 0xb3, 0x50, 0x14, 0x26, 0x1d, 0x63, 0x9f, 0x49, + 0x5b, 0x6c, 0x9c, 0x1f, 0x10, 0x4f, 0xe8, 0xe3, 0x20, 0xac, 0xa6, + 0x0d, 0x45, 0x50, 0xd6, 0x9d, 0x52, 0xed, 0xbd, 0x5a, 0x3c, 0xde, + 0xb4, 0x01, 0x4a, 0xe6, 0x5b, 0x1d, 0x87, 0xaa, 0x77, 0x0b, 0x69, + 0xae, 0x5c, 0x15, 0xf4, 0x33, 0x0b, 0x0b, 0x0a, 0xd8})), + std::make_pair( + 172, + std::vector<uint8_t>( + {0xf4, 0xc4, 0xdd, 0x1d, 0x59, 0x4c, 0x35, 0x65, 0xe3, 0xe2, 0x5c, + 0xa4, 0x3d, 0xad, 0x82, 0xf6, 0x2a, 0xbe, 0xa4, 0x83, 0x5e, 0xd4, + 0xcd, 0x81, 0x1b, 0xcd, 0x97, 0x5e, 0x46, 0x27, 0x98, 0x28, 0xd4, + 0x4d, 0x4c, 0x62, 0xc3, 0x67, 0x9f, 0x1b, 0x7f, 0x7b, 0x9d, 0xd4, + 0x57, 0x1d, 0x7b, 0x49, 0x55, 0x73, 0x47, 0xb8, 0xc5, 0x46, 0x0c, + 0xbd, 0xc1, 0xbe, 0xf6, 0x90, 0xfb, 0x2a, 0x08, 0xc0})), + std::make_pair( + 173, + std::vector<uint8_t>( + {0x8f, 0x1d, 0xc9, 0x64, 0x9c, 0x3a, 0x84, 0x55, 0x1f, 0x8f, 0x6e, + 0x91, 0xca, 0xc6, 0x82, 0x42, 0xa4, 0x3b, 0x1f, 0x8f, 0x32, 0x8e, + 0xe9, 0x22, 0x80, 0x25, 0x73, 0x87, 0xfa, 0x75, 0x59, 0xaa, 0x6d, + 0xb1, 0x2e, 0x4a, 0xea, 0xdc, 0x2d, 0x26, 0x09, 0x91, 0x78, 0x74, + 0x9c, 0x68, 0x64, 0xb3, 0x57, 0xf3, 0xf8, 0x3b, 0x2f, 0xb3, 0xef, + 0xa8, 0xd2, 0xa8, 0xdb, 0x05, 0x6b, 0xed, 0x6b, 0xcc})), + std::make_pair( + 174, + std::vector<uint8_t>( + {0x31, 0x39, 0xc1, 0xa7, 0xf9, 0x7a, 0xfd, 0x16, 0x75, 0xd4, 0x60, + 0xeb, 0xbc, 0x07, 0xf2, 0x72, 0x8a, 0xa1, 0x50, 0xdf, 0x84, 0x96, + 0x24, 0x51, 0x1e, 0xe0, 0x4b, 0x74, 0x3b, 0xa0, 0xa8, 0x33, 0x09, + 0x2f, 0x18, 0xc1, 0x2d, 0xc9, 0x1b, 0x4d, 0xd2, 0x43, 0xf3, 0x33, + 0x40, 0x2f, 0x59, 0xfe, 0x28, 0xab, 0xdb, 0xbb, 0xae, 0x30, 0x1e, + 0x7b, 0x65, 0x9c, 0x7a, 0x26, 0xd5, 0xc0, 0xf9, 0x79})), + std::make_pair( + 175, + std::vector<uint8_t>( + {0x06, 0xf9, 0x4a, 0x29, 0x96, 0x15, 0x8a, 0x81, 0x9f, 0xe3, 0x4c, + 0x40, 0xde, 0x3c, 0xf0, 0x37, 0x9f, 0xd9, 0xfb, 0x85, 0xb3, 0xe3, + 0x63, 0xba, 0x39, 0x26, 0xa0, 0xe7, 0xd9, 0x60, 0xe3, 0xf4, 0xc2, + 0xe0, 0xc7, 0x0c, 0x7c, 0xe0, 0xcc, 0xb2, 0xa6, 0x4f, 0xc2, 0x98, + 0x69, 0xf6, 0xe7, 0xab, 0x12, 0xbd, 0x4d, 0x3f, 0x14, 0xfc, 0xe9, + 0x43, 0x27, 0x90, 0x27, 0xe7, 0x85, 0xfb, 0x5c, 0x29})), + std::make_pair( + 176, + std::vector<uint8_t>( + {0xc2, 0x9c, 0x39, 0x9e, 0xf3, 0xee, 0xe8, 0x96, 0x1e, 0x87, 0x56, + 0x5c, 0x1c, 0xe2, 0x63, 0x92, 0x5f, 0xc3, 0xd0, 0xce, 0x26, 0x7d, + 0x13, 0xe4, 0x8d, 0xd9, 0xe7, 0x32, 0xee, 0x67, 0xb0, 0xf6, 0x9f, + 0xad, 0x56, 0x40, 0x1b, 0x0f, 0x10, 0xfc, 0xaa, 0xc1, 0x19, 0x20, + 0x10, 0x46, 0xcc, 0xa2, 0x8c, 0x5b, 0x14, 0xab, 0xde, 0xa3, 0x21, + 0x2a, 0xe6, 0x55, 0x62, 0xf7, 0xf1, 0x38, 0xdb, 0x3d})), + std::make_pair( + 177, + std::vector<uint8_t>( + {0x4c, 0xec, 0x4c, 0x9d, 0xf5, 0x2e, 0xef, 0x05, 0xc3, 0xf6, 0xfa, + 0xaa, 0x97, 0x91, 0xbc, 0x74, 0x45, 0x93, 0x71, 0x83, 0x22, 0x4e, + 0xcc, 0x37, 0xa1, 0xe5, 0x8d, 0x01, 0x32, 0xd3, 0x56, 0x17, 0x53, + 0x1d, 0x7e, 0x79, 0x5f, 0x52, 0xaf, 0x7b, 0x1e, 0xb9, 0xd1, 0x47, + 0xde, 0x12, 0x92, 0xd3, 0x45, 0xfe, 0x34, 0x18, 0x23, 0xf8, 0xe6, + 0xbc, 0x1e, 0x5b, 0xad, 0xca, 0x5c, 0x65, 0x61, 0x08})), + std::make_pair( + 178, + std::vector<uint8_t>( + {0x89, 0x8b, 0xfb, 0xae, 0x93, 0xb3, 0xe1, 0x8d, 0x00, 0x69, 0x7e, + 0xab, 0x7d, 0x97, 0x04, 0xfa, 0x36, 0xec, 0x33, 0x9d, 0x07, 0x61, + 0x31, 0xce, 0xfd, 0xf3, 0x0e, 0xdb, 0xe8, 0xd9, 0xcc, 0x81, 0xc3, + 0xa8, 0x0b, 0x12, 0x96, 0x59, 0xb1, 0x63, 0xa3, 0x23, 0xba, 0xb9, + 0x79, 0x3d, 0x4f, 0xee, 0xd9, 0x2d, 0x54, 0xda, 0xe9, 0x66, 0xc7, + 0x75, 0x29, 0x76, 0x4a, 0x09, 0xbe, 0x88, 0xdb, 0x45})), + std::make_pair( + 179, + std::vector<uint8_t>( + {0xee, 0x9b, 0xd0, 0x46, 0x9d, 0x3a, 0xaf, 0x4f, 0x14, 0x03, 0x5b, + 0xe4, 0x8a, 0x2c, 0x3b, 0x84, 0xd9, 0xb4, 0xb1, 0xff, 0xf1, 0xd9, + 0x45, 0xe1, 0xf1, 0xc1, 0xd3, 0x89, 0x80, 0xa9, 0x51, 0xbe, 0x19, + 0x7b, 0x25, 0xfe, 0x22, 0xc7, 0x31, 0xf2, 0x0a, 0xea, 0xcc, 0x93, + 0x0b, 0xa9, 0xc4, 0xa1, 0xf4, 0x76, 0x22, 0x27, 0x61, 0x7a, 0xd3, + 0x50, 0xfd, 0xab, 0xb4, 0xe8, 0x02, 0x73, 0xa0, 0xf4})), + std::make_pair( + 180, + std::vector<uint8_t>( + {0x3d, 0x4d, 0x31, 0x13, 0x30, 0x05, 0x81, 0xcd, 0x96, 0xac, 0xbf, + 0x09, 0x1c, 0x3d, 0x0f, 0x3c, 0x31, 0x01, 0x38, 0xcd, 0x69, 0x79, + 0xe6, 0x02, 0x6c, 0xde, 0x62, 0x3e, 0x2d, 0xd1, 0xb2, 0x4d, 0x4a, + 0x86, 0x38, 0xbe, 0xd1, 0x07, 0x33, 0x44, 0x78, 0x3a, 0xd0, 0x64, + 0x9c, 0xc6, 0x30, 0x5c, 0xce, 0xc0, 0x4b, 0xeb, 0x49, 0xf3, 0x1c, + 0x63, 0x30, 0x88, 0xa9, 0x9b, 0x65, 0x13, 0x02, 0x67})), + std::make_pair( + 181, + std::vector<uint8_t>( + {0x95, 0xc0, 0x59, 0x1a, 0xd9, 0x1f, 0x92, 0x1a, 0xc7, 0xbe, 0x6d, + 0x9c, 0xe3, 0x7e, 0x06, 0x63, 0xed, 0x80, 0x11, 0xc1, 0xcf, 0xd6, + 0xd0, 0x16, 0x2a, 0x55, 0x72, 0xe9, 0x43, 0x68, 0xba, 0xc0, 0x20, + 0x24, 0x48, 0x5e, 0x6a, 0x39, 0x85, 0x4a, 0xa4, 0x6f, 0xe3, 0x8e, + 0x97, 0xd6, 0xc6, 0xb1, 0x94, 0x7c, 0xd2, 0x72, 0xd8, 0x6b, 0x06, + 0xbb, 0x5b, 0x2f, 0x78, 0xb9, 0xb6, 0x8d, 0x55, 0x9d})), + std::make_pair( + 182, + std::vector<uint8_t>( + {0x22, 0x7b, 0x79, 0xde, 0xd3, 0x68, 0x15, 0x3b, 0xf4, 0x6c, 0x0a, + 0x3c, 0xa9, 0x78, 0xbf, 0xdb, 0xef, 0x31, 0xf3, 0x02, 0x4a, 0x56, + 0x65, 0x84, 0x24, 0x68, 0x49, 0x0b, 0x0f, 0xf7, 0x48, 0xae, 0x04, + 0xe7, 0x83, 0x2e, 0xd4, 0xc9, 0xf4, 0x9d, 0xe9, 0xb1, 0x70, 0x67, + 0x09, 0xd6, 0x23, 0xe5, 0xc8, 0xc1, 0x5e, 0x3c, 0xae, 0xca, 0xe8, + 0xd5, 0xe4, 0x33, 0x43, 0x0f, 0xf7, 0x2f, 0x20, 0xeb})), + std::make_pair( + 183, + std::vector<uint8_t>( + {0x5d, 0x34, 0xf3, 0x95, 0x2f, 0x01, 0x05, 0xee, 0xf8, 0x8a, 0xe8, + 0xb6, 0x4c, 0x6c, 0xe9, 0x5e, 0xbf, 0xad, 0xe0, 0xe0, 0x2c, 0x69, + 0xb0, 0x87, 0x62, 0xa8, 0x71, 0x2d, 0x2e, 0x49, 0x11, 0xad, 0x3f, + 0x94, 0x1f, 0xc4, 0x03, 0x4d, 0xc9, 0xb2, 0xe4, 0x79, 0xfd, 0xbc, + 0xd2, 0x79, 0xb9, 0x02, 0xfa, 0xf5, 0xd8, 0x38, 0xbb, 0x2e, 0x0c, + 0x64, 0x95, 0xd3, 0x72, 0xb5, 0xb7, 0x02, 0x98, 0x13})), + std::make_pair( + 184, + std::vector<uint8_t>( + {0x7f, 0x93, 0x9b, 0xf8, 0x35, 0x3a, 0xbc, 0xe4, 0x9e, 0x77, 0xf1, + 0x4f, 0x37, 0x50, 0xaf, 0x20, 0xb7, 0xb0, 0x39, 0x02, 0xe1, 0xa1, + 0xe7, 0xfb, 0x6a, 0xaf, 0x76, 0xd0, 0x25, 0x9c, 0xd4, 0x01, 0xa8, + 0x31, 0x90, 0xf1, 0x56, 0x40, 0xe7, 0x4f, 0x3e, 0x6c, 0x5a, 0x90, + 0xe8, 0x39, 0xc7, 0x82, 0x1f, 0x64, 0x74, 0x75, 0x7f, 0x75, 0xc7, + 0xbf, 0x90, 0x02, 0x08, 0x4d, 0xdc, 0x7a, 0x62, 0xdc})), + std::make_pair( + 185, + std::vector<uint8_t>( + {0x06, 0x2b, 0x61, 0xa2, 0xf9, 0xa3, 0x3a, 0x71, 0xd7, 0xd0, 0xa0, + 0x61, 0x19, 0x64, 0x4c, 0x70, 0xb0, 0x71, 0x6a, 0x50, 0x4d, 0xe7, + 0xe5, 0xe1, 0xbe, 0x49, 0xbd, 0x7b, 0x86, 0xe7, 0xed, 0x68, 0x17, + 0x71, 0x4f, 0x9f, 0x0f, 0xc3, 0x13, 0xd0, 0x61, 0x29, 0x59, 0x7e, + 0x9a, 0x22, 0x35, 0xec, 0x85, 0x21, 0xde, 0x36, 0xf7, 0x29, 0x0a, + 0x90, 0xcc, 0xfc, 0x1f, 0xfa, 0x6d, 0x0a, 0xee, 0x29})), + std::make_pair( + 186, + std::vector<uint8_t>( + {0xf2, 0x9e, 0x01, 0xee, 0xae, 0x64, 0x31, 0x1e, 0xb7, 0xf1, 0xc6, + 0x42, 0x2f, 0x94, 0x6b, 0xf7, 0xbe, 0xa3, 0x63, 0x79, 0x52, 0x3e, + 0x7b, 0x2b, 0xba, 0xba, 0x7d, 0x1d, 0x34, 0xa2, 0x2d, 0x5e, 0xa5, + 0xf1, 0xc5, 0xa0, 0x9d, 0x5c, 0xe1, 0xfe, 0x68, 0x2c, 0xce, 0xd9, + 0xa4, 0x79, 0x8d, 0x1a, 0x05, 0xb4, 0x6c, 0xd7, 0x2d, 0xff, 0x5c, + 0x1b, 0x35, 0x54, 0x40, 0xb2, 0xa2, 0xd4, 0x76, 0xbc})), + std::make_pair( + 187, + std::vector<uint8_t>( + {0xec, 0x38, 0xcd, 0x3b, 0xba, 0xb3, 0xef, 0x35, 0xd7, 0xcb, 0x6d, + 0x5c, 0x91, 0x42, 0x98, 0x35, 0x1d, 0x8a, 0x9d, 0xc9, 0x7f, 0xce, + 0xe0, 0x51, 0xa8, 0xa0, 0x2f, 0x58, 0xe3, 0xed, 0x61, 0x84, 0xd0, + 0xb7, 0x81, 0x0a, 0x56, 0x15, 0x41, 0x1a, 0xb1, 0xb9, 0x52, 0x09, + 0xc3, 0xc8, 0x10, 0x11, 0x4f, 0xde, 0xb2, 0x24, 0x52, 0x08, 0x4e, + 0x77, 0xf3, 0xf8, 0x47, 0xc6, 0xdb, 0xaa, 0xfe, 0x16})), + std::make_pair( + 188, + std::vector<uint8_t>( + {0xc2, 0xae, 0xf5, 0xe0, 0xca, 0x43, 0xe8, 0x26, 0x41, 0x56, 0x5b, + 0x8c, 0xb9, 0x43, 0xaa, 0x8b, 0xa5, 0x35, 0x50, 0xca, 0xef, 0x79, + 0x3b, 0x65, 0x32, 0xfa, 0xfa, 0xd9, 0x4b, 0x81, 0x60, 0x82, 0xf0, + 0x11, 0x3a, 0x3e, 0xa2, 0xf6, 0x36, 0x08, 0xab, 0x40, 0x43, 0x7e, + 0xcc, 0x0f, 0x02, 0x29, 0xcb, 0x8f, 0xa2, 0x24, 0xdc, 0xf1, 0xc4, + 0x78, 0xa6, 0x7d, 0x9b, 0x64, 0x16, 0x2b, 0x92, 0xd1})), + std::make_pair( + 189, + std::vector<uint8_t>( + {0x15, 0xf5, 0x34, 0xef, 0xff, 0x71, 0x05, 0xcd, 0x1c, 0x25, 0x4d, + 0x07, 0x4e, 0x27, 0xd5, 0x89, 0x8b, 0x89, 0x31, 0x3b, 0x7d, 0x36, + 0x6d, 0xc2, 0xd7, 0xd8, 0x71, 0x13, 0xfa, 0x7d, 0x53, 0xaa, 0xe1, + 0x3f, 0x6d, 0xba, 0x48, 0x7a, 0xd8, 0x10, 0x3d, 0x5e, 0x85, 0x4c, + 0x91, 0xfd, 0xb6, 0xe1, 0xe7, 0x4b, 0x2e, 0xf6, 0xd1, 0x43, 0x17, + 0x69, 0xc3, 0x07, 0x67, 0xdd, 0xe0, 0x67, 0xa3, 0x5c})), + std::make_pair( + 190, + std::vector<uint8_t>( + {0x89, 0xac, 0xbc, 0xa0, 0xb1, 0x69, 0x89, 0x7a, 0x0a, 0x27, 0x14, + 0xc2, 0xdf, 0x8c, 0x95, 0xb5, 0xb7, 0x9c, 0xb6, 0x93, 0x90, 0x14, + 0x2b, 0x7d, 0x60, 0x18, 0xbb, 0x3e, 0x30, 0x76, 0xb0, 0x99, 0xb7, + 0x9a, 0x96, 0x41, 0x52, 0xa9, 0xd9, 0x12, 0xb1, 0xb8, 0x64, 0x12, + 0xb7, 0xe3, 0x72, 0xe9, 0xce, 0xca, 0xd7, 0xf2, 0x5d, 0x4c, 0xba, + 0xb8, 0xa3, 0x17, 0xbe, 0x36, 0x49, 0x2a, 0x67, 0xd7})), + std::make_pair( + 191, + std::vector<uint8_t>( + {0xe3, 0xc0, 0x73, 0x91, 0x90, 0xed, 0x84, 0x9c, 0x9c, 0x96, 0x2f, + 0xd9, 0xdb, 0xb5, 0x5e, 0x20, 0x7e, 0x62, 0x4f, 0xca, 0xc1, 0xeb, + 0x41, 0x76, 0x91, 0x51, 0x54, 0x99, 0xee, 0xa8, 0xd8, 0x26, 0x7b, + 0x7e, 0x8f, 0x12, 0x87, 0xa6, 0x36, 0x33, 0xaf, 0x50, 0x11, 0xfd, + 0xe8, 0xc4, 0xdd, 0xf5, 0x5b, 0xfd, 0xf7, 0x22, 0xed, 0xf8, 0x88, + 0x31, 0x41, 0x4f, 0x2c, 0xfa, 0xed, 0x59, 0xcb, 0x9a})), + std::make_pair( + 192, + std::vector<uint8_t>( + {0x8d, 0x6c, 0xf8, 0x7c, 0x08, 0x38, 0x0d, 0x2d, 0x15, 0x06, 0xee, + 0xe4, 0x6f, 0xd4, 0x22, 0x2d, 0x21, 0xd8, 0xc0, 0x4e, 0x58, 0x5f, + 0xbf, 0xd0, 0x82, 0x69, 0xc9, 0x8f, 0x70, 0x28, 0x33, 0xa1, 0x56, + 0x32, 0x6a, 0x07, 0x24, 0x65, 0x64, 0x00, 0xee, 0x09, 0x35, 0x1d, + 0x57, 0xb4, 0x40, 0x17, 0x5e, 0x2a, 0x5d, 0xe9, 0x3c, 0xc5, 0xf8, + 0x0d, 0xb6, 0xda, 0xf8, 0x35, 0x76, 0xcf, 0x75, 0xfa})), + std::make_pair( + 193, + std::vector<uint8_t>( + {0xda, 0x24, 0xbe, 0xde, 0x38, 0x36, 0x66, 0xd5, 0x63, 0xee, 0xed, + 0x37, 0xf6, 0x31, 0x9b, 0xaf, 0x20, 0xd5, 0xc7, 0x5d, 0x16, 0x35, + 0xa6, 0xba, 0x5e, 0xf4, 0xcf, 0xa1, 0xac, 0x95, 0x48, 0x7e, 0x96, + 0xf8, 0xc0, 0x8a, 0xf6, 0x00, 0xaa, 0xb8, 0x7c, 0x98, 0x6e, 0xba, + 0xd4, 0x9f, 0xc7, 0x0a, 0x58, 0xb4, 0x89, 0x0b, 0x9c, 0x87, 0x6e, + 0x09, 0x10, 0x16, 0xda, 0xf4, 0x9e, 0x1d, 0x32, 0x2e})), + std::make_pair( + 194, + std::vector<uint8_t>( + {0xf9, 0xd1, 0xd1, 0xb1, 0xe8, 0x7e, 0xa7, 0xae, 0x75, 0x3a, 0x02, + 0x97, 0x50, 0xcc, 0x1c, 0xf3, 0xd0, 0x15, 0x7d, 0x41, 0x80, 0x5e, + 0x24, 0x5c, 0x56, 0x17, 0xbb, 0x93, 0x4e, 0x73, 0x2f, 0x0a, 0xe3, + 0x18, 0x0b, 0x78, 0xe0, 0x5b, 0xfe, 0x76, 0xc7, 0xc3, 0x05, 0x1e, + 0x3e, 0x3a, 0xc7, 0x8b, 0x9b, 0x50, 0xc0, 0x51, 0x42, 0x65, 0x7e, + 0x1e, 0x03, 0x21, 0x5d, 0x6e, 0xc7, 0xbf, 0xd0, 0xfc})), + std::make_pair( + 195, + std::vector<uint8_t>( + {0x11, 0xb7, 0xbc, 0x16, 0x68, 0x03, 0x20, 0x48, 0xaa, 0x43, 0x34, + 0x3d, 0xe4, 0x76, 0x39, 0x5e, 0x81, 0x4b, 0xbb, 0xc2, 0x23, 0x67, + 0x8d, 0xb9, 0x51, 0xa1, 0xb0, 0x3a, 0x02, 0x1e, 0xfa, 0xc9, 0x48, + 0xcf, 0xbe, 0x21, 0x5f, 0x97, 0xfe, 0x9a, 0x72, 0xa2, 0xf6, 0xbc, + 0x03, 0x9e, 0x39, 0x56, 0xbf, 0xa4, 0x17, 0xc1, 0xa9, 0xf1, 0x0d, + 0x6d, 0x7b, 0xa5, 0xd3, 0xd3, 0x2f, 0xf3, 0x23, 0xe5})), + std::make_pair( + 196, + std::vector<uint8_t>( + {0xb8, 0xd9, 0x00, 0x0e, 0x4f, 0xc2, 0xb0, 0x66, 0xed, 0xb9, 0x1a, + 0xfe, 0xe8, 0xe7, 0xeb, 0x0f, 0x24, 0xe3, 0xa2, 0x01, 0xdb, 0x8b, + 0x67, 0x93, 0xc0, 0x60, 0x85, 0x81, 0xe6, 0x28, 0xed, 0x0b, 0xcc, + 0x4e, 0x5a, 0xa6, 0x78, 0x79, 0x92, 0xa4, 0xbc, 0xc4, 0x4e, 0x28, + 0x80, 0x93, 0xe6, 0x3e, 0xe8, 0x3a, 0xbd, 0x0b, 0xc3, 0xec, 0x6d, + 0x09, 0x34, 0xa6, 0x74, 0xa4, 0xda, 0x13, 0x83, 0x8a})), + std::make_pair( + 197, + std::vector<uint8_t>( + {0xce, 0x32, 0x5e, 0x29, 0x4f, 0x9b, 0x67, 0x19, 0xd6, 0xb6, 0x12, + 0x78, 0x27, 0x6a, 0xe0, 0x6a, 0x25, 0x64, 0xc0, 0x3b, 0xb0, 0xb7, + 0x83, 0xfa, 0xfe, 0x78, 0x5b, 0xdf, 0x89, 0xc7, 0xd5, 0xac, 0xd8, + 0x3e, 0x78, 0x75, 0x6d, 0x30, 0x1b, 0x44, 0x56, 0x99, 0x02, 0x4e, + 0xae, 0xb7, 0x7b, 0x54, 0xd4, 0x77, 0x33, 0x6e, 0xc2, 0xa4, 0xf3, + 0x32, 0xf2, 0xb3, 0xf8, 0x87, 0x65, 0xdd, 0xb0, 0xc3})), + std::make_pair( + 198, + std::vector<uint8_t>( + {0x29, 0xac, 0xc3, 0x0e, 0x96, 0x03, 0xae, 0x2f, 0xcc, 0xf9, 0x0b, + 0xf9, 0x7e, 0x6c, 0xc4, 0x63, 0xeb, 0xe2, 0x8c, 0x1b, 0x2f, 0x9b, + 0x4b, 0x76, 0x5e, 0x70, 0x53, 0x7c, 0x25, 0xc7, 0x02, 0xa2, 0x9d, + 0xcb, 0xfb, 0xf1, 0x4c, 0x99, 0xc5, 0x43, 0x45, 0xba, 0x2b, 0x51, + 0xf1, 0x7b, 0x77, 0xb5, 0xf1, 0x5d, 0xb9, 0x2b, 0xba, 0xd8, 0xfa, + 0x95, 0xc4, 0x71, 0xf5, 0xd0, 0x70, 0xa1, 0x37, 0xcc})), + std::make_pair( + 199, + std::vector<uint8_t>( + {0x33, 0x79, 0xcb, 0xaa, 0xe5, 0x62, 0xa8, 0x7b, 0x4c, 0x04, 0x25, + 0x55, 0x0f, 0xfd, 0xd6, 0xbf, 0xe1, 0x20, 0x3f, 0x0d, 0x66, 0x6c, + 0xc7, 0xea, 0x09, 0x5b, 0xe4, 0x07, 0xa5, 0xdf, 0xe6, 0x1e, 0xe9, + 0x14, 0x41, 0xcd, 0x51, 0x54, 0xb3, 0xe5, 0x3b, 0x4f, 0x5f, 0xb3, + 0x1a, 0xd4, 0xc7, 0xa9, 0xad, 0x5c, 0x7a, 0xf4, 0xae, 0x67, 0x9a, + 0xa5, 0x1a, 0x54, 0x00, 0x3a, 0x54, 0xca, 0x6b, 0x2d})), + std::make_pair( + 200, + std::vector<uint8_t>( + {0x30, 0x95, 0xa3, 0x49, 0xd2, 0x45, 0x70, 0x8c, 0x7c, 0xf5, 0x50, + 0x11, 0x87, 0x03, 0xd7, 0x30, 0x2c, 0x27, 0xb6, 0x0a, 0xf5, 0xd4, + 0xe6, 0x7f, 0xc9, 0x78, 0xf8, 0xa4, 0xe6, 0x09, 0x53, 0xc7, 0xa0, + 0x4f, 0x92, 0xfc, 0xf4, 0x1a, 0xee, 0x64, 0x32, 0x1c, 0xcb, 0x70, + 0x7a, 0x89, 0x58, 0x51, 0x55, 0x2b, 0x1e, 0x37, 0xb0, 0x0b, 0xc5, + 0xe6, 0xb7, 0x2f, 0xa5, 0xbc, 0xef, 0x9e, 0x3f, 0xff})), + std::make_pair( + 201, + std::vector<uint8_t>( + {0x07, 0x26, 0x2d, 0x73, 0x8b, 0x09, 0x32, 0x1f, 0x4d, 0xbc, 0xce, + 0xc4, 0xbb, 0x26, 0xf4, 0x8c, 0xb0, 0xf0, 0xed, 0x24, 0x6c, 0xe0, + 0xb3, 0x1b, 0x9a, 0x6e, 0x7b, 0xc6, 0x83, 0x04, 0x9f, 0x1f, 0x3e, + 0x55, 0x45, 0xf2, 0x8c, 0xe9, 0x32, 0xdd, 0x98, 0x5c, 0x5a, 0xb0, + 0xf4, 0x3b, 0xd6, 0xde, 0x07, 0x70, 0x56, 0x0a, 0xf3, 0x29, 0x06, + 0x5e, 0xd2, 0xe4, 0x9d, 0x34, 0x62, 0x4c, 0x2c, 0xbb})), + std::make_pair( + 202, + std::vector<uint8_t>( + {0xb6, 0x40, 0x5e, 0xca, 0x8e, 0xe3, 0x31, 0x6c, 0x87, 0x06, 0x1c, + 0xc6, 0xec, 0x18, 0xdb, 0xa5, 0x3e, 0x6c, 0x25, 0x0c, 0x63, 0xba, + 0x1f, 0x3b, 0xae, 0x9e, 0x55, 0xdd, 0x34, 0x98, 0x03, 0x6a, 0xf0, + 0x8c, 0xd2, 0x72, 0xaa, 0x24, 0xd7, 0x13, 0xc6, 0x02, 0x0d, 0x77, + 0xab, 0x2f, 0x39, 0x19, 0xaf, 0x1a, 0x32, 0xf3, 0x07, 0x42, 0x06, + 0x18, 0xab, 0x97, 0xe7, 0x39, 0x53, 0x99, 0x4f, 0xb4})), + std::make_pair( + 203, + std::vector<uint8_t>( + {0x7e, 0xe6, 0x82, 0xf6, 0x31, 0x48, 0xee, 0x45, 0xf6, 0xe5, 0x31, + 0x5d, 0xa8, 0x1e, 0x5c, 0x6e, 0x55, 0x7c, 0x2c, 0x34, 0x64, 0x1f, + 0xc5, 0x09, 0xc7, 0xa5, 0x70, 0x10, 0x88, 0xc3, 0x8a, 0x74, 0x75, + 0x61, 0x68, 0xe2, 0xcd, 0x8d, 0x35, 0x1e, 0x88, 0xfd, 0x1a, 0x45, + 0x1f, 0x36, 0x0a, 0x01, 0xf5, 0xb2, 0x58, 0x0f, 0x9b, 0x5a, 0x2e, + 0x8c, 0xfc, 0x13, 0x8f, 0x3d, 0xd5, 0x9a, 0x3f, 0xfc})), + std::make_pair( + 204, + std::vector<uint8_t>( + {0x1d, 0x26, 0x3c, 0x17, 0x9d, 0x6b, 0x26, 0x8f, 0x6f, 0xa0, 0x16, + 0xf3, 0xa4, 0xf2, 0x9e, 0x94, 0x38, 0x91, 0x12, 0x5e, 0xd8, 0x59, + 0x3c, 0x81, 0x25, 0x60, 0x59, 0xf5, 0xa7, 0xb4, 0x4a, 0xf2, 0xdc, + 0xb2, 0x03, 0x0d, 0x17, 0x5c, 0x00, 0xe6, 0x2e, 0xca, 0xf7, 0xee, + 0x96, 0x68, 0x2a, 0xa0, 0x7a, 0xb2, 0x0a, 0x61, 0x10, 0x24, 0xa2, + 0x85, 0x32, 0xb1, 0xc2, 0x5b, 0x86, 0x65, 0x79, 0x02})), + std::make_pair( + 205, + std::vector<uint8_t>( + {0x10, 0x6d, 0x13, 0x2c, 0xbd, 0xb4, 0xcd, 0x25, 0x97, 0x81, 0x28, + 0x46, 0xe2, 0xbc, 0x1b, 0xf7, 0x32, 0xfe, 0xc5, 0xf0, 0xa5, 0xf6, + 0x5d, 0xbb, 0x39, 0xec, 0x4e, 0x6d, 0xc6, 0x4a, 0xb2, 0xce, 0x6d, + 0x24, 0x63, 0x0d, 0x0f, 0x15, 0xa8, 0x05, 0xc3, 0x54, 0x00, 0x25, + 0xd8, 0x4a, 0xfa, 0x98, 0xe3, 0x67, 0x03, 0xc3, 0xdb, 0xee, 0x71, + 0x3e, 0x72, 0xdd, 0xe8, 0x46, 0x5b, 0xc1, 0xbe, 0x7e})), + std::make_pair( + 206, + std::vector<uint8_t>( + {0x0e, 0x79, 0x96, 0x82, 0x26, 0x65, 0x06, 0x67, 0xa8, 0xd8, 0x62, + 0xea, 0x8d, 0xa4, 0x89, 0x1a, 0xf5, 0x6a, 0x4e, 0x3a, 0x8b, 0x6d, + 0x17, 0x50, 0xe3, 0x94, 0xf0, 0xde, 0xa7, 0x6d, 0x64, 0x0d, 0x85, + 0x07, 0x7b, 0xce, 0xc2, 0xcc, 0x86, 0x88, 0x6e, 0x50, 0x67, 0x51, + 0xb4, 0xf6, 0xa5, 0x83, 0x8f, 0x7f, 0x0b, 0x5f, 0xef, 0x76, 0x5d, + 0x9d, 0xc9, 0x0d, 0xcd, 0xcb, 0xaf, 0x07, 0x9f, 0x08})), + std::make_pair( + 207, + std::vector<uint8_t>( + {0x52, 0x11, 0x56, 0xa8, 0x2a, 0xb0, 0xc4, 0xe5, 0x66, 0xe5, 0x84, + 0x4d, 0x5e, 0x31, 0xad, 0x9a, 0xaf, 0x14, 0x4b, 0xbd, 0x5a, 0x46, + 0x4f, 0xdc, 0xa3, 0x4d, 0xbd, 0x57, 0x17, 0xe8, 0xff, 0x71, 0x1d, + 0x3f, 0xfe, 0xbb, 0xfa, 0x08, 0x5d, 0x67, 0xfe, 0x99, 0x6a, 0x34, + 0xf6, 0xd3, 0xe4, 0xe6, 0x0b, 0x13, 0x96, 0xbf, 0x4b, 0x16, 0x10, + 0xc2, 0x63, 0xbd, 0xbb, 0x83, 0x4d, 0x56, 0x08, 0x16})), + std::make_pair( + 208, + std::vector<uint8_t>( + {0x1a, 0xba, 0x88, 0xbe, 0xfc, 0x55, 0xbc, 0x25, 0xef, 0xbc, 0xe0, + 0x2d, 0xb8, 0xb9, 0x93, 0x3e, 0x46, 0xf5, 0x76, 0x61, 0xba, 0xea, + 0xbe, 0xb2, 0x1c, 0xc2, 0x57, 0x4d, 0x2a, 0x51, 0x8a, 0x3c, 0xba, + 0x5d, 0xc5, 0xa3, 0x8e, 0x49, 0x71, 0x34, 0x40, 0xb2, 0x5f, 0x9c, + 0x74, 0x4e, 0x75, 0xf6, 0xb8, 0x5c, 0x9d, 0x8f, 0x46, 0x81, 0xf6, + 0x76, 0x16, 0x0f, 0x61, 0x05, 0x35, 0x7b, 0x84, 0x06})), + std::make_pair( + 209, + std::vector<uint8_t>( + {0x5a, 0x99, 0x49, 0xfc, 0xb2, 0xc4, 0x73, 0xcd, 0xa9, 0x68, 0xac, + 0x1b, 0x5d, 0x08, 0x56, 0x6d, 0xc2, 0xd8, 0x16, 0xd9, 0x60, 0xf5, + 0x7e, 0x63, 0xb8, 0x98, 0xfa, 0x70, 0x1c, 0xf8, 0xeb, 0xd3, 0xf5, + 0x9b, 0x12, 0x4d, 0x95, 0xbf, 0xbb, 0xed, 0xc5, 0xf1, 0xcf, 0x0e, + 0x17, 0xd5, 0xea, 0xed, 0x0c, 0x02, 0xc5, 0x0b, 0x69, 0xd8, 0xa4, + 0x02, 0xca, 0xbc, 0xca, 0x44, 0x33, 0xb5, 0x1f, 0xd4})), + std::make_pair( + 210, + std::vector<uint8_t>( + {0xb0, 0xce, 0xad, 0x09, 0x80, 0x7c, 0x67, 0x2a, 0xf2, 0xeb, 0x2b, + 0x0f, 0x06, 0xdd, 0xe4, 0x6c, 0xf5, 0x37, 0x0e, 0x15, 0xa4, 0x09, + 0x6b, 0x1a, 0x7d, 0x7c, 0xbb, 0x36, 0xec, 0x31, 0xc2, 0x05, 0xfb, + 0xef, 0xca, 0x00, 0xb7, 0xa4, 0x16, 0x2f, 0xa8, 0x9f, 0xb4, 0xfb, + 0x3e, 0xb7, 0x8d, 0x79, 0x77, 0x0c, 0x23, 0xf4, 0x4e, 0x72, 0x06, + 0x66, 0x4c, 0xe3, 0xcd, 0x93, 0x1c, 0x29, 0x1e, 0x5d})), + std::make_pair( + 211, + std::vector<uint8_t>( + {0xbb, 0x66, 0x64, 0x93, 0x1e, 0xc9, 0x70, 0x44, 0xe4, 0x5b, 0x2a, + 0xe4, 0x20, 0xae, 0x1c, 0x55, 0x1a, 0x88, 0x74, 0xbc, 0x93, 0x7d, + 0x08, 0xe9, 0x69, 0x39, 0x9c, 0x39, 0x64, 0xeb, 0xdb, 0xa8, 0x34, + 0x6c, 0xdd, 0x5d, 0x09, 0xca, 0xaf, 0xe4, 0xc2, 0x8b, 0xa7, 0xec, + 0x78, 0x81, 0x91, 0xce, 0xca, 0x65, 0xdd, 0xd6, 0xf9, 0x5f, 0x18, + 0x58, 0x3e, 0x04, 0x0d, 0x0f, 0x30, 0xd0, 0x36, 0x4d})), + std::make_pair( + 212, + std::vector<uint8_t>( + {0x65, 0xbc, 0x77, 0x0a, 0x5f, 0xaa, 0x37, 0x92, 0x36, 0x98, 0x03, + 0x68, 0x3e, 0x84, 0x4b, 0x0b, 0xe7, 0xee, 0x96, 0xf2, 0x9f, 0x6d, + 0x6a, 0x35, 0x56, 0x80, 0x06, 0xbd, 0x55, 0x90, 0xf9, 0xa4, 0xef, + 0x63, 0x9b, 0x7a, 0x80, 0x61, 0xc7, 0xb0, 0x42, 0x4b, 0x66, 0xb6, + 0x0a, 0xc3, 0x4a, 0xf3, 0x11, 0x99, 0x05, 0xf3, 0x3a, 0x9d, 0x8c, + 0x3a, 0xe1, 0x83, 0x82, 0xca, 0x9b, 0x68, 0x99, 0x00})), + std::make_pair( + 213, + std::vector<uint8_t>( + {0xea, 0x9b, 0x4d, 0xca, 0x33, 0x33, 0x36, 0xaa, 0xf8, 0x39, 0xa4, + 0x5c, 0x6e, 0xaa, 0x48, 0xb8, 0xcb, 0x4c, 0x7d, 0xda, 0xbf, 0xfe, + 0xa4, 0xf6, 0x43, 0xd6, 0x35, 0x7e, 0xa6, 0x62, 0x8a, 0x48, 0x0a, + 0x5b, 0x45, 0xf2, 0xb0, 0x52, 0xc1, 0xb0, 0x7d, 0x1f, 0xed, 0xca, + 0x91, 0x8b, 0x6f, 0x11, 0x39, 0xd8, 0x0f, 0x74, 0xc2, 0x45, 0x10, + 0xdc, 0xba, 0xa4, 0xbe, 0x70, 0xea, 0xcc, 0x1b, 0x06})), + std::make_pair( + 214, + std::vector<uint8_t>( + {0xe6, 0x34, 0x2f, 0xb4, 0xa7, 0x80, 0xad, 0x97, 0x5d, 0x0e, 0x24, + 0xbc, 0xe1, 0x49, 0x98, 0x9b, 0x91, 0xd3, 0x60, 0x55, 0x7e, 0x87, + 0x99, 0x4f, 0x6b, 0x45, 0x7b, 0x89, 0x55, 0x75, 0xcc, 0x02, 0xd0, + 0xc1, 0x5b, 0xad, 0x3c, 0xe7, 0x57, 0x7f, 0x4c, 0x63, 0x92, 0x7f, + 0xf1, 0x3f, 0x3e, 0x38, 0x1f, 0xf7, 0xe7, 0x2b, 0xdb, 0xe7, 0x45, + 0x32, 0x48, 0x44, 0xa9, 0xd2, 0x7e, 0x3f, 0x1c, 0x01})), + std::make_pair( + 215, + std::vector<uint8_t>( + {0x3e, 0x20, 0x9c, 0x9b, 0x33, 0xe8, 0xe4, 0x61, 0x17, 0x8a, 0xb4, + 0x6b, 0x1c, 0x64, 0xb4, 0x9a, 0x07, 0xfb, 0x74, 0x5f, 0x1c, 0x8b, + 0xc9, 0x5f, 0xbf, 0xb9, 0x4c, 0x6b, 0x87, 0xc6, 0x95, 0x16, 0x65, + 0x1b, 0x26, 0x4e, 0xf9, 0x80, 0x93, 0x7f, 0xad, 0x41, 0x23, 0x8b, + 0x91, 0xdd, 0xc0, 0x11, 0xa5, 0xdd, 0x77, 0x7c, 0x7e, 0xfd, 0x44, + 0x94, 0xb4, 0xb6, 0xec, 0xd3, 0xa9, 0xc2, 0x2a, 0xc0})), + std::make_pair( + 216, + std::vector<uint8_t>( + {0xfd, 0x6a, 0x3d, 0x5b, 0x18, 0x75, 0xd8, 0x04, 0x86, 0xd6, 0xe6, + 0x96, 0x94, 0xa5, 0x6d, 0xbb, 0x04, 0xa9, 0x9a, 0x4d, 0x05, 0x1f, + 0x15, 0xdb, 0x26, 0x89, 0x77, 0x6b, 0xa1, 0xc4, 0x88, 0x2e, 0x6d, + 0x46, 0x2a, 0x60, 0x3b, 0x70, 0x15, 0xdc, 0x9f, 0x4b, 0x74, 0x50, + 0xf0, 0x53, 0x94, 0x30, 0x3b, 0x86, 0x52, 0xcf, 0xb4, 0x04, 0xa2, + 0x66, 0x96, 0x2c, 0x41, 0xba, 0xe6, 0xe1, 0x8a, 0x94})), + std::make_pair( + 217, + std::vector<uint8_t>( + {0x95, 0x1e, 0x27, 0x51, 0x7e, 0x6b, 0xad, 0x9e, 0x41, 0x95, 0xfc, + 0x86, 0x71, 0xde, 0xe3, 0xe7, 0xe9, 0xbe, 0x69, 0xce, 0xe1, 0x42, + 0x2c, 0xb9, 0xfe, 0xcf, 0xce, 0x0d, 0xba, 0x87, 0x5f, 0x7b, 0x31, + 0x0b, 0x93, 0xee, 0x3a, 0x3d, 0x55, 0x8f, 0x94, 0x1f, 0x63, 0x5f, + 0x66, 0x8f, 0xf8, 0x32, 0xd2, 0xc1, 0xd0, 0x33, 0xc5, 0xe2, 0xf0, + 0x99, 0x7e, 0x4c, 0x66, 0xf1, 0x47, 0x34, 0x4e, 0x02})), + std::make_pair( + 218, + std::vector<uint8_t>( + {0x8e, 0xba, 0x2f, 0x87, 0x4f, 0x1a, 0xe8, 0x40, 0x41, 0x90, 0x3c, + 0x7c, 0x42, 0x53, 0xc8, 0x22, 0x92, 0x53, 0x0f, 0xc8, 0x50, 0x95, + 0x50, 0xbf, 0xdc, 0x34, 0xc9, 0x5c, 0x7e, 0x28, 0x89, 0xd5, 0x65, + 0x0b, 0x0a, 0xd8, 0xcb, 0x98, 0x8e, 0x5c, 0x48, 0x94, 0xcb, 0x87, + 0xfb, 0xfb, 0xb1, 0x96, 0x12, 0xea, 0x93, 0xcc, 0xc4, 0xc5, 0xca, + 0xd1, 0x71, 0x58, 0xb9, 0x76, 0x34, 0x64, 0xb4, 0x92})), + std::make_pair( + 219, + std::vector<uint8_t>( + {0x16, 0xf7, 0x12, 0xea, 0xa1, 0xb7, 0xc6, 0x35, 0x47, 0x19, 0xa8, + 0xe7, 0xdb, 0xdf, 0xaf, 0x55, 0xe4, 0x06, 0x3a, 0x4d, 0x27, 0x7d, + 0x94, 0x75, 0x50, 0x01, 0x9b, 0x38, 0xdf, 0xb5, 0x64, 0x83, 0x09, + 0x11, 0x05, 0x7d, 0x50, 0x50, 0x61, 0x36, 0xe2, 0x39, 0x4c, 0x3b, + 0x28, 0x94, 0x5c, 0xc9, 0x64, 0x96, 0x7d, 0x54, 0xe3, 0x00, 0x0c, + 0x21, 0x81, 0x62, 0x6c, 0xfb, 0x9b, 0x73, 0xef, 0xd2})), + std::make_pair( + 220, + std::vector<uint8_t>( + {0xc3, 0x96, 0x39, 0xe7, 0xd5, 0xc7, 0xfb, 0x8c, 0xdd, 0x0f, 0xd3, + 0xe6, 0xa5, 0x20, 0x96, 0x03, 0x94, 0x37, 0x12, 0x2f, 0x21, 0xc7, + 0x8f, 0x16, 0x79, 0xce, 0xa9, 0xd7, 0x8a, 0x73, 0x4c, 0x56, 0xec, + 0xbe, 0xb2, 0x86, 0x54, 0xb4, 0xf1, 0x8e, 0x34, 0x2c, 0x33, 0x1f, + 0x6f, 0x72, 0x29, 0xec, 0x4b, 0x4b, 0xc2, 0x81, 0xb2, 0xd8, 0x0a, + 0x6e, 0xb5, 0x00, 0x43, 0xf3, 0x17, 0x96, 0xc8, 0x8c})), + std::make_pair( + 221, + std::vector<uint8_t>( + {0x72, 0xd0, 0x81, 0xaf, 0x99, 0xf8, 0xa1, 0x73, 0xdc, 0xc9, 0xa0, + 0xac, 0x4e, 0xb3, 0x55, 0x74, 0x05, 0x63, 0x9a, 0x29, 0x08, 0x4b, + 0x54, 0xa4, 0x01, 0x72, 0x91, 0x2a, 0x2f, 0x8a, 0x39, 0x51, 0x29, + 0xd5, 0x53, 0x6f, 0x09, 0x18, 0xe9, 0x02, 0xf9, 0xe8, 0xfa, 0x60, + 0x00, 0x99, 0x5f, 0x41, 0x68, 0xdd, 0xc5, 0xf8, 0x93, 0x01, 0x1b, + 0xe6, 0xa0, 0xdb, 0xc9, 0xb8, 0xa1, 0xa3, 0xf5, 0xbb})), + std::make_pair( + 222, + std::vector<uint8_t>( + {0xc1, 0x1a, 0xa8, 0x1e, 0x5e, 0xfd, 0x24, 0xd5, 0xfc, 0x27, 0xee, + 0x58, 0x6c, 0xfd, 0x88, 0x47, 0xfb, 0xb0, 0xe2, 0x76, 0x01, 0xcc, + 0xec, 0xe5, 0xec, 0xca, 0x01, 0x98, 0xe3, 0xc7, 0x76, 0x53, 0x93, + 0xbb, 0x74, 0x45, 0x7c, 0x7e, 0x7a, 0x27, 0xeb, 0x91, 0x70, 0x35, + 0x0e, 0x1f, 0xb5, 0x38, 0x57, 0x17, 0x75, 0x06, 0xbe, 0x3e, 0x76, + 0x2c, 0xc0, 0xf1, 0x4d, 0x8c, 0x3a, 0xfe, 0x90, 0x77})), + std::make_pair( + 223, + std::vector<uint8_t>( + {0xc2, 0x8f, 0x21, 0x50, 0xb4, 0x52, 0xe6, 0xc0, 0xc4, 0x24, 0xbc, + 0xde, 0x6f, 0x8d, 0x72, 0x00, 0x7f, 0x93, 0x10, 0xfe, 0xd7, 0xf2, + 0xf8, 0x7d, 0xe0, 0xdb, 0xb6, 0x4f, 0x44, 0x79, 0xd6, 0xc1, 0x44, + 0x1b, 0xa6, 0x6f, 0x44, 0xb2, 0xac, 0xce, 0xe6, 0x16, 0x09, 0x17, + 0x7e, 0xd3, 0x40, 0x12, 0x8b, 0x40, 0x7e, 0xce, 0xc7, 0xc6, 0x4b, + 0xbe, 0x50, 0xd6, 0x3d, 0x22, 0xd8, 0x62, 0x77, 0x27})), + std::make_pair( + 224, + std::vector<uint8_t>( + {0xf6, 0x3d, 0x88, 0x12, 0x28, 0x77, 0xec, 0x30, 0xb8, 0xc8, 0xb0, + 0x0d, 0x22, 0xe8, 0x90, 0x00, 0xa9, 0x66, 0x42, 0x61, 0x12, 0xbd, + 0x44, 0x16, 0x6e, 0x2f, 0x52, 0x5b, 0x76, 0x9c, 0xcb, 0xe9, 0xb2, + 0x86, 0xd4, 0x37, 0xa0, 0x12, 0x91, 0x30, 0xdd, 0xe1, 0xa8, 0x6c, + 0x43, 0xe0, 0x4b, 0xed, 0xb5, 0x94, 0xe6, 0x71, 0xd9, 0x82, 0x83, + 0xaf, 0xe6, 0x4c, 0xe3, 0x31, 0xde, 0x98, 0x28, 0xfd})), + std::make_pair( + 225, + std::vector<uint8_t>( + {0x34, 0x8b, 0x05, 0x32, 0x88, 0x0b, 0x88, 0xa6, 0x61, 0x4a, 0x8d, + 0x74, 0x08, 0xc3, 0xf9, 0x13, 0x35, 0x7f, 0xbb, 0x60, 0xe9, 0x95, + 0xc6, 0x02, 0x05, 0xbe, 0x91, 0x39, 0xe7, 0x49, 0x98, 0xae, 0xde, + 0x7f, 0x45, 0x81, 0xe4, 0x2f, 0x6b, 0x52, 0x69, 0x8f, 0x7f, 0xa1, + 0x21, 0x97, 0x08, 0xc1, 0x44, 0x98, 0x06, 0x7f, 0xd1, 0xe0, 0x95, + 0x02, 0xde, 0x83, 0xa7, 0x7d, 0xd2, 0x81, 0x15, 0x0c})), + std::make_pair( + 226, + std::vector<uint8_t>( + {0x51, 0x33, 0xdc, 0x8b, 0xef, 0x72, 0x53, 0x59, 0xdf, 0xf5, 0x97, + 0x92, 0xd8, 0x5e, 0xaf, 0x75, 0xb7, 0xe1, 0xdc, 0xd1, 0x97, 0x8b, + 0x01, 0xc3, 0x5b, 0x1b, 0x85, 0xfc, 0xeb, 0xc6, 0x33, 0x88, 0xad, + 0x99, 0xa1, 0x7b, 0x63, 0x46, 0xa2, 0x17, 0xdc, 0x1a, 0x96, 0x22, + 0xeb, 0xd1, 0x22, 0xec, 0xf6, 0x91, 0x3c, 0x4d, 0x31, 0xa6, 0xb5, + 0x2a, 0x69, 0x5b, 0x86, 0xaf, 0x00, 0xd7, 0x41, 0xa0})), + std::make_pair( + 227, + std::vector<uint8_t>( + {0x27, 0x53, 0xc4, 0xc0, 0xe9, 0x8e, 0xca, 0xd8, 0x06, 0xe8, 0x87, + 0x80, 0xec, 0x27, 0xfc, 0xcd, 0x0f, 0x5c, 0x1a, 0xb5, 0x47, 0xf9, + 0xe4, 0xbf, 0x16, 0x59, 0xd1, 0x92, 0xc2, 0x3a, 0xa2, 0xcc, 0x97, + 0x1b, 0x58, 0xb6, 0x80, 0x25, 0x80, 0xba, 0xef, 0x8a, 0xdc, 0x3b, + 0x77, 0x6e, 0xf7, 0x08, 0x6b, 0x25, 0x45, 0xc2, 0x98, 0x7f, 0x34, + 0x8e, 0xe3, 0x71, 0x9c, 0xde, 0xf2, 0x58, 0xc4, 0x03})), + std::make_pair( + 228, + std::vector<uint8_t>( + {0xb1, 0x66, 0x35, 0x73, 0xce, 0x4b, 0x9d, 0x8c, 0xae, 0xfc, 0x86, + 0x50, 0x12, 0xf3, 0xe3, 0x97, 0x14, 0xb9, 0x89, 0x8a, 0x5d, 0xa6, + 0xce, 0x17, 0xc2, 0x5a, 0x6a, 0x47, 0x93, 0x1a, 0x9d, 0xdb, 0x9b, + 0xbe, 0x98, 0xad, 0xaa, 0x55, 0x3b, 0xee, 0xd4, 0x36, 0xe8, 0x95, + 0x78, 0x45, 0x54, 0x16, 0xc2, 0xa5, 0x2a, 0x52, 0x5c, 0xf2, 0x86, + 0x2b, 0x8d, 0x1d, 0x49, 0xa2, 0x53, 0x1b, 0x73, 0x91})), + std::make_pair( + 229, + std::vector<uint8_t>( + {0x64, 0xf5, 0x8b, 0xd6, 0xbf, 0xc8, 0x56, 0xf5, 0xe8, 0x73, 0xb2, + 0xa2, 0x95, 0x6e, 0xa0, 0xed, 0xa0, 0xd6, 0xdb, 0x0d, 0xa3, 0x9c, + 0x8c, 0x7f, 0xc6, 0x7c, 0x9f, 0x9f, 0xee, 0xfc, 0xff, 0x30, 0x72, + 0xcd, 0xf9, 0xe6, 0xea, 0x37, 0xf6, 0x9a, 0x44, 0xf0, 0xc6, 0x1a, + 0xa0, 0xda, 0x36, 0x93, 0xc2, 0xdb, 0x5b, 0x54, 0x96, 0x0c, 0x02, + 0x81, 0xa0, 0x88, 0x15, 0x1d, 0xb4, 0x2b, 0x11, 0xe8})), + std::make_pair( + 230, + std::vector<uint8_t>( + {0x07, 0x64, 0xc7, 0xbe, 0x28, 0x12, 0x5d, 0x90, 0x65, 0xc4, 0xb9, + 0x8a, 0x69, 0xd6, 0x0a, 0xed, 0xe7, 0x03, 0x54, 0x7c, 0x66, 0xa1, + 0x2e, 0x17, 0xe1, 0xc6, 0x18, 0x99, 0x41, 0x32, 0xf5, 0xef, 0x82, + 0x48, 0x2c, 0x1e, 0x3f, 0xe3, 0x14, 0x6c, 0xc6, 0x53, 0x76, 0xcc, + 0x10, 0x9f, 0x01, 0x38, 0xed, 0x9a, 0x80, 0xe4, 0x9f, 0x1f, 0x3c, + 0x7d, 0x61, 0x0d, 0x2f, 0x24, 0x32, 0xf2, 0x06, 0x05})), + std::make_pair( + 231, + std::vector<uint8_t>( + {0xf7, 0x48, 0x78, 0x43, 0x98, 0xa2, 0xff, 0x03, 0xeb, 0xeb, 0x07, + 0xe1, 0x55, 0xe6, 0x61, 0x16, 0xa8, 0x39, 0x74, 0x1a, 0x33, 0x6e, + 0x32, 0xda, 0x71, 0xec, 0x69, 0x60, 0x01, 0xf0, 0xad, 0x1b, 0x25, + 0xcd, 0x48, 0xc6, 0x9c, 0xfc, 0xa7, 0x26, 0x5e, 0xca, 0x1d, 0xd7, + 0x19, 0x04, 0xa0, 0xce, 0x74, 0x8a, 0xc4, 0x12, 0x4f, 0x35, 0x71, + 0x07, 0x6d, 0xfa, 0x71, 0x16, 0xa9, 0xcf, 0x00, 0xe9})), + std::make_pair( + 232, + std::vector<uint8_t>( + {0x3f, 0x0d, 0xbc, 0x01, 0x86, 0xbc, 0xeb, 0x6b, 0x78, 0x5b, 0xa7, + 0x8d, 0x2a, 0x2a, 0x01, 0x3c, 0x91, 0x0b, 0xe1, 0x57, 0xbd, 0xaf, + 0xfa, 0xe8, 0x1b, 0xb6, 0x66, 0x3b, 0x1a, 0x73, 0x72, 0x2f, 0x7f, + 0x12, 0x28, 0x79, 0x5f, 0x3e, 0xca, 0xda, 0x87, 0xcf, 0x6e, 0xf0, + 0x07, 0x84, 0x74, 0xaf, 0x73, 0xf3, 0x1e, 0xca, 0x0c, 0xc2, 0x00, + 0xed, 0x97, 0x5b, 0x68, 0x93, 0xf7, 0x61, 0xcb, 0x6d})), + std::make_pair( + 233, + std::vector<uint8_t>( + {0xd4, 0x76, 0x2c, 0xd4, 0x59, 0x98, 0x76, 0xca, 0x75, 0xb2, 0xb8, + 0xfe, 0x24, 0x99, 0x44, 0xdb, 0xd2, 0x7a, 0xce, 0x74, 0x1f, 0xda, + 0xb9, 0x36, 0x16, 0xcb, 0xc6, 0xe4, 0x25, 0x46, 0x0f, 0xeb, 0x51, + 0xd4, 0xe7, 0xad, 0xcc, 0x38, 0x18, 0x0e, 0x7f, 0xc4, 0x7c, 0x89, + 0x02, 0x4a, 0x7f, 0x56, 0x19, 0x1a, 0xdb, 0x87, 0x8d, 0xfd, 0xe4, + 0xea, 0xd6, 0x22, 0x23, 0xf5, 0xa2, 0x61, 0x0e, 0xfe})), + std::make_pair( + 234, + std::vector<uint8_t>( + {0xcd, 0x36, 0xb3, 0xd5, 0xb4, 0xc9, 0x1b, 0x90, 0xfc, 0xbb, 0xa7, + 0x95, 0x13, 0xcf, 0xee, 0x19, 0x07, 0xd8, 0x64, 0x5a, 0x16, 0x2a, + 0xfd, 0x0c, 0xd4, 0xcf, 0x41, 0x92, 0xd4, 0xa5, 0xf4, 0xc8, 0x92, + 0x18, 0x3a, 0x8e, 0xac, 0xdb, 0x2b, 0x6b, 0x6a, 0x9d, 0x9a, 0xa8, + 0xc1, 0x1a, 0xc1, 0xb2, 0x61, 0xb3, 0x80, 0xdb, 0xee, 0x24, 0xca, + 0x46, 0x8f, 0x1b, 0xfd, 0x04, 0x3c, 0x58, 0xee, 0xfe})), + std::make_pair( + 235, + std::vector<uint8_t>( + {0x98, 0x59, 0x34, 0x52, 0x28, 0x16, 0x61, 0xa5, 0x3c, 0x48, 0xa9, + 0xd8, 0xcd, 0x79, 0x08, 0x26, 0xc1, 0xa1, 0xce, 0x56, 0x77, 0x38, + 0x05, 0x3d, 0x0b, 0xee, 0x4a, 0x91, 0xa3, 0xd5, 0xbd, 0x92, 0xee, + 0xfd, 0xba, 0xbe, 0xbe, 0x32, 0x04, 0xf2, 0x03, 0x1c, 0xa5, 0xf7, + 0x81, 0xbd, 0xa9, 0x9e, 0xf5, 0xd8, 0xae, 0x56, 0xe5, 0xb0, 0x4a, + 0x9e, 0x1e, 0xcd, 0x21, 0xb0, 0xeb, 0x05, 0xd3, 0xe1})), + std::make_pair( + 236, + std::vector<uint8_t>( + {0x77, 0x1f, 0x57, 0xdd, 0x27, 0x75, 0xcc, 0xda, 0xb5, 0x59, 0x21, + 0xd3, 0xe8, 0xe3, 0x0c, 0xcf, 0x48, 0x4d, 0x61, 0xfe, 0x1c, 0x1b, + 0x9c, 0x2a, 0xe8, 0x19, 0xd0, 0xfb, 0x2a, 0x12, 0xfa, 0xb9, 0xbe, + 0x70, 0xc4, 0xa7, 0xa1, 0x38, 0xda, 0x84, 0xe8, 0x28, 0x04, 0x35, + 0xda, 0xad, 0xe5, 0xbb, 0xe6, 0x6a, 0xf0, 0x83, 0x6a, 0x15, 0x4f, + 0x81, 0x7f, 0xb1, 0x7f, 0x33, 0x97, 0xe7, 0x25, 0xa3})), + std::make_pair( + 237, + std::vector<uint8_t>( + {0xc6, 0x08, 0x97, 0xc6, 0xf8, 0x28, 0xe2, 0x1f, 0x16, 0xfb, 0xb5, + 0xf1, 0x5b, 0x32, 0x3f, 0x87, 0xb6, 0xc8, 0x95, 0x5e, 0xab, 0xf1, + 0xd3, 0x80, 0x61, 0xf7, 0x07, 0xf6, 0x08, 0xab, 0xdd, 0x99, 0x3f, + 0xac, 0x30, 0x70, 0x63, 0x3e, 0x28, 0x6c, 0xf8, 0x33, 0x9c, 0xe2, + 0x95, 0xdd, 0x35, 0x2d, 0xf4, 0xb4, 0xb4, 0x0b, 0x2f, 0x29, 0xda, + 0x1d, 0xd5, 0x0b, 0x3a, 0x05, 0xd0, 0x79, 0xe6, 0xbb})), + std::make_pair( + 238, + std::vector<uint8_t>( + {0x82, 0x10, 0xcd, 0x2c, 0x2d, 0x3b, 0x13, 0x5c, 0x2c, 0xf0, 0x7f, + 0xa0, 0xd1, 0x43, 0x3c, 0xd7, 0x71, 0xf3, 0x25, 0xd0, 0x75, 0xc6, + 0x46, 0x9d, 0x9c, 0x7f, 0x1b, 0xa0, 0x94, 0x3c, 0xd4, 0xab, 0x09, + 0x80, 0x8c, 0xab, 0xf4, 0xac, 0xb9, 0xce, 0x5b, 0xb8, 0x8b, 0x49, + 0x89, 0x29, 0xb4, 0xb8, 0x47, 0xf6, 0x81, 0xad, 0x2c, 0x49, 0x0d, + 0x04, 0x2d, 0xb2, 0xae, 0xc9, 0x42, 0x14, 0xb0, 0x6b})), + std::make_pair( + 239, + std::vector<uint8_t>( + {0x1d, 0x4e, 0xdf, 0xff, 0xd8, 0xfd, 0x80, 0xf7, 0xe4, 0x10, 0x78, + 0x40, 0xfa, 0x3a, 0xa3, 0x1e, 0x32, 0x59, 0x84, 0x91, 0xe4, 0xaf, + 0x70, 0x13, 0xc1, 0x97, 0xa6, 0x5b, 0x7f, 0x36, 0xdd, 0x3a, 0xc4, + 0xb4, 0x78, 0x45, 0x61, 0x11, 0xcd, 0x43, 0x09, 0xd9, 0x24, 0x35, + 0x10, 0x78, 0x2f, 0xa3, 0x1b, 0x7c, 0x4c, 0x95, 0xfa, 0x95, 0x15, + 0x20, 0xd0, 0x20, 0xeb, 0x7e, 0x5c, 0x36, 0xe4, 0xef})), + std::make_pair( + 240, + std::vector<uint8_t>( + {0xaf, 0x8e, 0x6e, 0x91, 0xfa, 0xb4, 0x6c, 0xe4, 0x87, 0x3e, 0x1a, + 0x50, 0xa8, 0xef, 0x44, 0x8c, 0xc2, 0x91, 0x21, 0xf7, 0xf7, 0x4d, + 0xee, 0xf3, 0x4a, 0x71, 0xef, 0x89, 0xcc, 0x00, 0xd9, 0x27, 0x4b, + 0xc6, 0xc2, 0x45, 0x4b, 0xbb, 0x32, 0x30, 0xd8, 0xb2, 0xec, 0x94, + 0xc6, 0x2b, 0x1d, 0xec, 0x85, 0xf3, 0x59, 0x3b, 0xfa, 0x30, 0xea, + 0x6f, 0x7a, 0x44, 0xd7, 0xc0, 0x94, 0x65, 0xa2, 0x53})), + std::make_pair( + 241, + std::vector<uint8_t>( + {0x29, 0xfd, 0x38, 0x4e, 0xd4, 0x90, 0x6f, 0x2d, 0x13, 0xaa, 0x9f, + 0xe7, 0xaf, 0x90, 0x59, 0x90, 0x93, 0x8b, 0xed, 0x80, 0x7f, 0x18, + 0x32, 0x45, 0x4a, 0x37, 0x2a, 0xb4, 0x12, 0xee, 0xa1, 0xf5, 0x62, + 0x5a, 0x1f, 0xcc, 0x9a, 0xc8, 0x34, 0x3b, 0x7c, 0x67, 0xc5, 0xab, + 0xa6, 0xe0, 0xb1, 0xcc, 0x46, 0x44, 0x65, 0x49, 0x13, 0x69, 0x2c, + 0x6b, 0x39, 0xeb, 0x91, 0x87, 0xce, 0xac, 0xd3, 0xec})), + std::make_pair( + 242, + std::vector<uint8_t>( + {0xa2, 0x68, 0xc7, 0x88, 0x5d, 0x98, 0x74, 0xa5, 0x1c, 0x44, 0xdf, + 0xfe, 0xd8, 0xea, 0x53, 0xe9, 0x4f, 0x78, 0x45, 0x6e, 0x0b, 0x2e, + 0xd9, 0x9f, 0xf5, 0xa3, 0x92, 0x47, 0x60, 0x81, 0x38, 0x26, 0xd9, + 0x60, 0xa1, 0x5e, 0xdb, 0xed, 0xbb, 0x5d, 0xe5, 0x22, 0x6b, 0xa4, + 0xb0, 0x74, 0xe7, 0x1b, 0x05, 0xc5, 0x5b, 0x97, 0x56, 0xbb, 0x79, + 0xe5, 0x5c, 0x02, 0x75, 0x4c, 0x2c, 0x7b, 0x6c, 0x8a})), + std::make_pair( + 243, + std::vector<uint8_t>( + {0x0c, 0xf8, 0x54, 0x54, 0x88, 0xd5, 0x6a, 0x86, 0x81, 0x7c, 0xd7, + 0xec, 0xb1, 0x0f, 0x71, 0x16, 0xb7, 0xea, 0x53, 0x0a, 0x45, 0xb6, + 0xea, 0x49, 0x7b, 0x6c, 0x72, 0xc9, 0x97, 0xe0, 0x9e, 0x3d, 0x0d, + 0xa8, 0x69, 0x8f, 0x46, 0xbb, 0x00, 0x6f, 0xc9, 0x77, 0xc2, 0xcd, + 0x3d, 0x11, 0x77, 0x46, 0x3a, 0xc9, 0x05, 0x7f, 0xdd, 0x16, 0x62, + 0xc8, 0x5d, 0x0c, 0x12, 0x64, 0x43, 0xc1, 0x04, 0x73})), + std::make_pair( + 244, + std::vector<uint8_t>( + {0xb3, 0x96, 0x14, 0x26, 0x8f, 0xdd, 0x87, 0x81, 0x51, 0x5e, 0x2c, + 0xfe, 0xbf, 0x89, 0xb4, 0xd5, 0x40, 0x2b, 0xab, 0x10, 0xc2, 0x26, + 0xe6, 0x34, 0x4e, 0x6b, 0x9a, 0xe0, 0x00, 0xfb, 0x0d, 0x6c, 0x79, + 0xcb, 0x2f, 0x3e, 0xc8, 0x0e, 0x80, 0xea, 0xeb, 0x19, 0x80, 0xd2, + 0xf8, 0x69, 0x89, 0x16, 0xbd, 0x2e, 0x9f, 0x74, 0x72, 0x36, 0x65, + 0x51, 0x16, 0x64, 0x9c, 0xd3, 0xca, 0x23, 0xa8, 0x37})), + std::make_pair( + 245, + std::vector<uint8_t>( + {0x74, 0xbe, 0xf0, 0x92, 0xfc, 0x6f, 0x1e, 0x5d, 0xba, 0x36, 0x63, + 0xa3, 0xfb, 0x00, 0x3b, 0x2a, 0x5b, 0xa2, 0x57, 0x49, 0x65, 0x36, + 0xd9, 0x9f, 0x62, 0xb9, 0xd7, 0x3f, 0x8f, 0x9e, 0xb3, 0xce, 0x9f, + 0xf3, 0xee, 0xc7, 0x09, 0xeb, 0x88, 0x36, 0x55, 0xec, 0x9e, 0xb8, + 0x96, 0xb9, 0x12, 0x8f, 0x2a, 0xfc, 0x89, 0xcf, 0x7d, 0x1a, 0xb5, + 0x8a, 0x72, 0xf4, 0xa3, 0xbf, 0x03, 0x4d, 0x2b, 0x4a})), + std::make_pair( + 246, + std::vector<uint8_t>( + {0x3a, 0x98, 0x8d, 0x38, 0xd7, 0x56, 0x11, 0xf3, 0xef, 0x38, 0xb8, + 0x77, 0x49, 0x80, 0xb3, 0x3e, 0x57, 0x3b, 0x6c, 0x57, 0xbe, 0xe0, + 0x46, 0x9b, 0xa5, 0xee, 0xd9, 0xb4, 0x4f, 0x29, 0x94, 0x5e, 0x73, + 0x47, 0x96, 0x7f, 0xba, 0x2c, 0x16, 0x2e, 0x1c, 0x3b, 0xe7, 0xf3, + 0x10, 0xf2, 0xf7, 0x5e, 0xe2, 0x38, 0x1e, 0x7b, 0xfd, 0x6b, 0x3f, + 0x0b, 0xae, 0xa8, 0xd9, 0x5d, 0xfb, 0x1d, 0xaf, 0xb1})), + std::make_pair( + 247, + std::vector<uint8_t>( + {0x58, 0xae, 0xdf, 0xce, 0x6f, 0x67, 0xdd, 0xc8, 0x5a, 0x28, 0xc9, + 0x92, 0xf1, 0xc0, 0xbd, 0x09, 0x69, 0xf0, 0x41, 0xe6, 0x6f, 0x1e, + 0xe8, 0x80, 0x20, 0xa1, 0x25, 0xcb, 0xfc, 0xfe, 0xbc, 0xd6, 0x17, + 0x09, 0xc9, 0xc4, 0xeb, 0xa1, 0x92, 0xc1, 0x5e, 0x69, 0xf0, 0x20, + 0xd4, 0x62, 0x48, 0x60, 0x19, 0xfa, 0x8d, 0xea, 0x0c, 0xd7, 0xa4, + 0x29, 0x21, 0xa1, 0x9d, 0x2f, 0xe5, 0x46, 0xd4, 0x3d})), + std::make_pair( + 248, + std::vector<uint8_t>( + {0x93, 0x47, 0xbd, 0x29, 0x14, 0x73, 0xe6, 0xb4, 0xe3, 0x68, 0x43, + 0x7b, 0x8e, 0x56, 0x1e, 0x06, 0x5f, 0x64, 0x9a, 0x6d, 0x8a, 0xda, + 0x47, 0x9a, 0xd0, 0x9b, 0x19, 0x99, 0xa8, 0xf2, 0x6b, 0x91, 0xcf, + 0x61, 0x20, 0xfd, 0x3b, 0xfe, 0x01, 0x4e, 0x83, 0xf2, 0x3a, 0xcf, + 0xa4, 0xc0, 0xad, 0x7b, 0x37, 0x12, 0xb2, 0xc3, 0xc0, 0x73, 0x32, + 0x70, 0x66, 0x31, 0x12, 0xcc, 0xd9, 0x28, 0x5c, 0xd9})), + std::make_pair( + 249, + std::vector<uint8_t>( + {0xb3, 0x21, 0x63, 0xe7, 0xc5, 0xdb, 0xb5, 0xf5, 0x1f, 0xdc, 0x11, + 0xd2, 0xea, 0xc8, 0x75, 0xef, 0xbb, 0xcb, 0x7e, 0x76, 0x99, 0x09, + 0x0a, 0x7e, 0x7f, 0xf8, 0xa8, 0xd5, 0x07, 0x95, 0xaf, 0x5d, 0x74, + 0xd9, 0xff, 0x98, 0x54, 0x3e, 0xf8, 0xcd, 0xf8, 0x9a, 0xc1, 0x3d, + 0x04, 0x85, 0x27, 0x87, 0x56, 0xe0, 0xef, 0x00, 0xc8, 0x17, 0x74, + 0x56, 0x61, 0xe1, 0xd5, 0x9f, 0xe3, 0x8e, 0x75, 0x37})), + std::make_pair( + 250, + std::vector<uint8_t>( + {0x10, 0x85, 0xd7, 0x83, 0x07, 0xb1, 0xc4, 0xb0, 0x08, 0xc5, 0x7a, + 0x2e, 0x7e, 0x5b, 0x23, 0x46, 0x58, 0xa0, 0xa8, 0x2e, 0x4f, 0xf1, + 0xe4, 0xaa, 0xac, 0x72, 0xb3, 0x12, 0xfd, 0xa0, 0xfe, 0x27, 0xd2, + 0x33, 0xbc, 0x5b, 0x10, 0xe9, 0xcc, 0x17, 0xfd, 0xc7, 0x69, 0x7b, + 0x54, 0x0c, 0x7d, 0x95, 0xeb, 0x21, 0x5a, 0x19, 0xa1, 0xa0, 0xe2, + 0x0e, 0x1a, 0xbf, 0xa1, 0x26, 0xef, 0xd5, 0x68, 0xc7})), + std::make_pair( + 251, + std::vector<uint8_t>( + {0x4e, 0x5c, 0x73, 0x4c, 0x7d, 0xde, 0x01, 0x1d, 0x83, 0xea, 0xc2, + 0xb7, 0x34, 0x7b, 0x37, 0x35, 0x94, 0xf9, 0x2d, 0x70, 0x91, 0xb9, + 0xca, 0x34, 0xcb, 0x9c, 0x6f, 0x39, 0xbd, 0xf5, 0xa8, 0xd2, 0xf1, + 0x34, 0x37, 0x9e, 0x16, 0xd8, 0x22, 0xf6, 0x52, 0x21, 0x70, 0xcc, + 0xf2, 0xdd, 0xd5, 0x5c, 0x84, 0xb9, 0xe6, 0xc6, 0x4f, 0xc9, 0x27, + 0xac, 0x4c, 0xf8, 0xdf, 0xb2, 0xa1, 0x77, 0x01, 0xf2})), + std::make_pair( + 252, + std::vector<uint8_t>( + {0x69, 0x5d, 0x83, 0xbd, 0x99, 0x0a, 0x11, 0x17, 0xb3, 0xd0, 0xce, + 0x06, 0xcc, 0x88, 0x80, 0x27, 0xd1, 0x2a, 0x05, 0x4c, 0x26, 0x77, + 0xfd, 0x82, 0xf0, 0xd4, 0xfb, 0xfc, 0x93, 0x57, 0x55, 0x23, 0xe7, + 0x99, 0x1a, 0x5e, 0x35, 0xa3, 0x75, 0x2e, 0x9b, 0x70, 0xce, 0x62, + 0x99, 0x2e, 0x26, 0x8a, 0x87, 0x77, 0x44, 0xcd, 0xd4, 0x35, 0xf5, + 0xf1, 0x30, 0x86, 0x9c, 0x9a, 0x20, 0x74, 0xb3, 0x38})), + std::make_pair( + 253, + std::vector<uint8_t>( + {0xa6, 0x21, 0x37, 0x43, 0x56, 0x8e, 0x3b, 0x31, 0x58, 0xb9, 0x18, + 0x43, 0x01, 0xf3, 0x69, 0x08, 0x47, 0x55, 0x4c, 0x68, 0x45, 0x7c, + 0xb4, 0x0f, 0xc9, 0xa4, 0xb8, 0xcf, 0xd8, 0xd4, 0xa1, 0x18, 0xc3, + 0x01, 0xa0, 0x77, 0x37, 0xae, 0xda, 0x0f, 0x92, 0x9c, 0x68, 0x91, + 0x3c, 0x5f, 0x51, 0xc8, 0x03, 0x94, 0xf5, 0x3b, 0xff, 0x1c, 0x3e, + 0x83, 0xb2, 0xe4, 0x0c, 0xa9, 0x7e, 0xba, 0x9e, 0x15})), + std::make_pair( + 254, + std::vector<uint8_t>( + {0xd4, 0x44, 0xbf, 0xa2, 0x36, 0x2a, 0x96, 0xdf, 0x21, 0x3d, 0x07, + 0x0e, 0x33, 0xfa, 0x84, 0x1f, 0x51, 0x33, 0x4e, 0x4e, 0x76, 0x86, + 0x6b, 0x81, 0x39, 0xe8, 0xaf, 0x3b, 0xb3, 0x39, 0x8b, 0xe2, 0xdf, + 0xad, 0xdc, 0xbc, 0x56, 0xb9, 0x14, 0x6d, 0xe9, 0xf6, 0x81, 0x18, + 0xdc, 0x58, 0x29, 0xe7, 0x4b, 0x0c, 0x28, 0xd7, 0x71, 0x19, 0x07, + 0xb1, 0x21, 0xf9, 0x16, 0x1c, 0xb9, 0x2b, 0x69, 0xa9})), + std::make_pair( + 255, + std::vector<uint8_t>( + {0x14, 0x27, 0x09, 0xd6, 0x2e, 0x28, 0xfc, 0xcc, 0xd0, 0xaf, 0x97, + 0xfa, 0xd0, 0xf8, 0x46, 0x5b, 0x97, 0x1e, 0x82, 0x20, 0x1d, 0xc5, + 0x10, 0x70, 0xfa, 0xa0, 0x37, 0x2a, 0xa4, 0x3e, 0x92, 0x48, 0x4b, + 0xe1, 0xc1, 0xe7, 0x3b, 0xa1, 0x09, 0x06, 0xd5, 0xd1, 0x85, 0x3d, + 0xb6, 0xa4, 0x10, 0x6e, 0x0a, 0x7b, 0xf9, 0x80, 0x0d, 0x37, 0x3d, + 0x6d, 0xee, 0x2d, 0x46, 0xd6, 0x2e, 0xf2, 0xa4, 0x61}))};
\ No newline at end of file diff --git a/security/nss/gtests/freebl_gtest/rsa_unittest.cc b/security/nss/gtests/freebl_gtest/rsa_unittest.cc new file mode 100644 index 000000000..5c667a1d1 --- /dev/null +++ b/security/nss/gtests/freebl_gtest/rsa_unittest.cc @@ -0,0 +1,61 @@ +// 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 "gtest/gtest.h" + +#include <stdint.h> + +#include "blapi.h" +#include "secitem.h" + +template <class T> +struct ScopedDelete { + void operator()(T* ptr) { + if (ptr) { + PORT_FreeArena(ptr->arena, PR_TRUE); + } + } +}; + +typedef std::unique_ptr<RSAPrivateKey, ScopedDelete<RSAPrivateKey>> + ScopedRSAPrivateKey; + +class RSANewKeyTest : public ::testing::Test { + protected: + RSAPrivateKey* CreateKeyWithExponent(int keySizeInBits, + unsigned char publicExponent) { + SECItem exp = {siBuffer, 0, 0}; + unsigned char pubExp[1] = {publicExponent}; + exp.data = pubExp; + exp.len = 1; + + return RSA_NewKey(keySizeInBits, &exp); + } +}; + +TEST_F(RSANewKeyTest, expOneTest) { + ScopedRSAPrivateKey key(CreateKeyWithExponent(2048, 0x01)); + ASSERT_TRUE(key == nullptr); +} +TEST_F(RSANewKeyTest, expTwoTest) { + ScopedRSAPrivateKey key(CreateKeyWithExponent(2048, 0x02)); + ASSERT_TRUE(key == nullptr); +} +TEST_F(RSANewKeyTest, expFourTest) { + ScopedRSAPrivateKey key(CreateKeyWithExponent(2048, 0x04)); + ASSERT_TRUE(key == nullptr); +} +TEST_F(RSANewKeyTest, WrongKeysizeTest) { + ScopedRSAPrivateKey key(CreateKeyWithExponent(2047, 0x03)); + ASSERT_TRUE(key == nullptr); +} + +TEST_F(RSANewKeyTest, expThreeTest) { + ScopedRSAPrivateKey key(CreateKeyWithExponent(2048, 0x03)); +#ifdef NSS_FIPS_DISABLED + ASSERT_TRUE(key != nullptr); +#else + ASSERT_TRUE(key == nullptr); +#endif +} diff --git a/security/nss/gtests/manifest.mn b/security/nss/gtests/manifest.mn index 1ae4cab77..13048f037 100644 --- a/security/nss/gtests/manifest.mn +++ b/security/nss/gtests/manifest.mn @@ -13,7 +13,6 @@ LIB_SRCDIRS = \ ifneq ($(NSS_BUILD_WITHOUT_UTIL),1) UTIL_SRCDIRS = \ util_gtest \ - der_gtest \ $(NULL) endif @@ -22,9 +21,12 @@ ifneq ($(NSS_BUILD_UTIL_ONLY),1) NSS_SRCDIRS = \ certdb_gtest \ certhigh_gtest \ + cryptohi_gtest \ + der_gtest \ pk11_gtest \ + softoken_gtest \ ssl_gtest \ - nss_bogo_shim \ + nss_bogo_shim \ $(NULL) endif endif diff --git a/security/nss/gtests/nss_bogo_shim/Makefile b/security/nss/gtests/nss_bogo_shim/Makefile index fd6426d89..a2ac4b145 100644 --- a/security/nss/gtests/nss_bogo_shim/Makefile +++ b/security/nss/gtests/nss_bogo_shim/Makefile @@ -30,10 +30,6 @@ include ../common/gtest.mk CFLAGS += -I$(CORE_DEPTH)/lib/ssl -ifdef NSS_SSL_ENABLE_ZLIB -include $(CORE_DEPTH)/coreconf/zlib.mk -endif - ####################################################################### # (5) Execute "global" rules. (OPTIONAL) # ####################################################################### @@ -48,5 +44,3 @@ include $(CORE_DEPTH)/coreconf/rules.mk ####################################################################### # (7) Execute "local" rules. (OPTIONAL). # ####################################################################### - - diff --git a/security/nss/gtests/nss_bogo_shim/config.json b/security/nss/gtests/nss_bogo_shim/config.json index 4109bd2ca..03f875466 100644 --- a/security/nss/gtests/nss_bogo_shim/config.json +++ b/security/nss/gtests/nss_bogo_shim/config.json @@ -1,12 +1,78 @@ { "DisabledTests": { "### These tests break whenever we rev versions, so just leave them here for easy uncommenting":"", - "#*TLS13*":"(NSS=18, BoGo=16)", - "#*HelloRetryRequest*":"(NSS=18, BoGo=16)", - "#*KeyShare*":"(NSS=18, BoGo=16)", - "#*EncryptedExtensions*":"(NSS=18, BoGo=16)", - "#*SecondClientHello*":"(NSS=18, BoGo=16)", - "#*IgnoreClientVersionOrder*":"(NSS=18, BoGo=16)", + "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", + "SupportedVersionSelection-TLS12":"Should maybe reject TLS 1.2 in SH.supported_versions (Bug 1438266)", + "*TLS13*":"(NSS=19, BoGo=18)", + "*HelloRetryRequest*":"(NSS=19, BoGo=18)", + "*KeyShare*":"(NSS=19, BoGo=18)", + "*EncryptedExtensions*":"(NSS=19, BoGo=18)", + "*SecondClientHello*":"(NSS=19, BoGo=18)", + "*IgnoreClientVersionOrder*":"(NSS=19, BoGo=18)", + "SkipEarlyData*":"(NSS=19, BoGo=18)", + "*Binder*":"(NSS=19, BoGo=18)", "Resume-Server-BinderWrongLength":"Alert disagreement (Bug 1317633)", "Resume-Server-NoPSKBinder":"Alert disagreement (Bug 1317633)", "CheckRecordVersion-TLS*":"Bug 1317634", @@ -66,4 +132,3 @@ ":DIGEST_CHECK_FAILED:":"SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE" } } - diff --git a/security/nss/gtests/pk11_gtest/manifest.mn b/security/nss/gtests/pk11_gtest/manifest.mn index fb773ee18..a3dff9d10 100644 --- a/security/nss/gtests/pk11_gtest/manifest.mn +++ b/security/nss/gtests/pk11_gtest/manifest.mn @@ -11,6 +11,7 @@ CPPSRCS = \ pk11_chacha20poly1305_unittest.cc \ pk11_curve25519_unittest.cc \ pk11_ecdsa_unittest.cc \ + pk11_encrypt_derive_unittest.cc \ pk11_export_unittest.cc \ pk11_pbkdf2_unittest.cc \ pk11_prf_unittest.cc \ @@ -23,10 +24,12 @@ INCLUDES += -I$(CORE_DEPTH)/gtests/google_test/gtest/include \ -I$(CORE_DEPTH)/gtests/common \ -I$(CORE_DEPTH)/cpputil -REQUIRES = nspr nss libdbm gtest +REQUIRES = nspr nss libdbm gtest cpputil PROGRAM = pk11_gtest -EXTRA_LIBS = $(DIST)/lib/$(LIB_PREFIX)gtest.$(LIB_SUFFIX) $(EXTRA_OBJS) \ - $(DIST)/lib/$(LIB_PREFIX)gtestutil.$(LIB_SUFFIX) +EXTRA_LIBS = $(DIST)/lib/$(LIB_PREFIX)gtest.$(LIB_SUFFIX) \ + $(DIST)/lib/$(LIB_PREFIX)cpputil.$(LIB_SUFFIX) \ + $(DIST)/lib/$(LIB_PREFIX)gtestutil.$(LIB_SUFFIX) \ + $(NULL) diff --git a/security/nss/gtests/pk11_gtest/pk11_ecdsa_unittest.cc b/security/nss/gtests/pk11_gtest/pk11_ecdsa_unittest.cc index a54190c7c..fb0659852 100644 --- a/security/nss/gtests/pk11_gtest/pk11_ecdsa_unittest.cc +++ b/security/nss/gtests/pk11_gtest/pk11_ecdsa_unittest.cc @@ -15,103 +15,117 @@ namespace nss_test { -class Pkcs11EcdsaTest : public Pk11SignatureTest { +class Pkcs11EcdsaTestBase : public Pk11SignatureTest { protected: - CK_MECHANISM_TYPE mechanism() { return CKM_ECDSA; } - SECItem* parameters() { return nullptr; } + Pkcs11EcdsaTestBase(SECOidTag hash_oid) + : Pk11SignatureTest(CKM_ECDSA, hash_oid) {} }; -class Pkcs11EcdsaSha256Test : public Pkcs11EcdsaTest { - protected: - SECOidTag hashOID() { return SEC_OID_SHA256; } +struct Pkcs11EcdsaTestParams { + SECOidTag hash_oid_; + Pkcs11SignatureTestParams sig_params_; }; -class Pkcs11EcdsaSha384Test : public Pkcs11EcdsaTest { - protected: - SECOidTag hashOID() { return SEC_OID_SHA384; } +class Pkcs11EcdsaTest + : public Pkcs11EcdsaTestBase, + public ::testing::WithParamInterface<Pkcs11EcdsaTestParams> { + public: + Pkcs11EcdsaTest() : Pkcs11EcdsaTestBase(GetParam().hash_oid_) {} }; -class Pkcs11EcdsaSha512Test : public Pkcs11EcdsaTest { - protected: - SECOidTag hashOID() { return SEC_OID_SHA512; } -}; +TEST_P(Pkcs11EcdsaTest, Verify) { Verify(GetParam().sig_params_); } -TEST_F(Pkcs11EcdsaSha256Test, VerifyP256) { - SIG_TEST_VECTOR_VERIFY(kP256Spki, kP256Data, kP256Signature) -} -TEST_F(Pkcs11EcdsaSha256Test, SignAndVerifyP256) { - SIG_TEST_VECTOR_SIGN_VERIFY(kP256Pkcs8, kP256Spki, kP256Data) +TEST_P(Pkcs11EcdsaTest, SignAndVerify) { + SignAndVerify(GetParam().sig_params_); } -TEST_F(Pkcs11EcdsaSha384Test, VerifyP384) { - SIG_TEST_VECTOR_VERIFY(kP384Spki, kP384Data, kP384Signature) -} -TEST_F(Pkcs11EcdsaSha384Test, SignAndVerifyP384) { - SIG_TEST_VECTOR_SIGN_VERIFY(kP384Pkcs8, kP384Spki, kP384Data) -} - -TEST_F(Pkcs11EcdsaSha512Test, VerifyP521) { - SIG_TEST_VECTOR_VERIFY(kP521Spki, kP521Data, kP521Signature) -} -TEST_F(Pkcs11EcdsaSha512Test, SignAndVerifyP521) { - SIG_TEST_VECTOR_SIGN_VERIFY(kP521Pkcs8, kP521Spki, kP521Data) -} +static const Pkcs11EcdsaTestParams kEcdsaVectors[] = { + {SEC_OID_SHA256, + {DataBuffer(kP256Pkcs8, sizeof(kP256Pkcs8)), + DataBuffer(kP256Spki, sizeof(kP256Spki)), + DataBuffer(kP256Data, sizeof(kP256Data)), + DataBuffer(kP256Signature, sizeof(kP256Signature))}}, + {SEC_OID_SHA384, + {DataBuffer(kP384Pkcs8, sizeof(kP384Pkcs8)), + DataBuffer(kP384Spki, sizeof(kP384Spki)), + DataBuffer(kP384Data, sizeof(kP384Data)), + DataBuffer(kP384Signature, sizeof(kP384Signature))}}, + {SEC_OID_SHA512, + {DataBuffer(kP521Pkcs8, sizeof(kP521Pkcs8)), + DataBuffer(kP521Spki, sizeof(kP521Spki)), + DataBuffer(kP521Data, sizeof(kP521Data)), + DataBuffer(kP521Signature, sizeof(kP521Signature))}}}; + +INSTANTIATE_TEST_CASE_P(EcdsaSignVerify, Pkcs11EcdsaTest, + ::testing::ValuesIn(kEcdsaVectors)); + +class Pkcs11EcdsaSha256Test : public Pkcs11EcdsaTestBase { + public: + Pkcs11EcdsaSha256Test() : Pkcs11EcdsaTestBase(SEC_OID_SHA256) {} +}; // Importing a private key in PKCS#8 format must fail when the outer AlgID // struct contains neither id-ecPublicKey nor a namedCurve parameter. TEST_F(Pkcs11EcdsaSha256Test, ImportNoCurveOIDOrAlgorithmParams) { - EXPECT_FALSE(ImportPrivateKey(kP256Pkcs8NoCurveOIDOrAlgorithmParams, - sizeof(kP256Pkcs8NoCurveOIDOrAlgorithmParams))); + DataBuffer k(kP256Pkcs8NoCurveOIDOrAlgorithmParams, + sizeof(kP256Pkcs8NoCurveOIDOrAlgorithmParams)); + EXPECT_FALSE(ImportPrivateKey(k)); }; // Importing a private key in PKCS#8 format must succeed when only the outer // AlgID struct contains the namedCurve parameters. TEST_F(Pkcs11EcdsaSha256Test, ImportOnlyAlgorithmParams) { - EXPECT_TRUE(ImportPrivateKeyAndSignHashedData( - kP256Pkcs8OnlyAlgorithmParams, sizeof(kP256Pkcs8OnlyAlgorithmParams), - kP256Data, sizeof(kP256Data))); + DataBuffer k(kP256Pkcs8OnlyAlgorithmParams, + sizeof(kP256Pkcs8OnlyAlgorithmParams)); + DataBuffer data(kP256Data, sizeof(kP256Data)); + DataBuffer sig; + EXPECT_TRUE(ImportPrivateKeyAndSignHashedData(k, data, &sig)); }; // Importing a private key in PKCS#8 format must succeed when the outer AlgID // struct and the inner ECPrivateKey contain the same namedCurve parameters. // The inner curveOID is always ignored, so only the outer one will be used. TEST_F(Pkcs11EcdsaSha256Test, ImportMatchingCurveOIDAndAlgorithmParams) { - EXPECT_TRUE(ImportPrivateKeyAndSignHashedData( - kP256Pkcs8MatchingCurveOIDAndAlgorithmParams, - sizeof(kP256Pkcs8MatchingCurveOIDAndAlgorithmParams), kP256Data, - sizeof(kP256Data))); + DataBuffer k(kP256Pkcs8MatchingCurveOIDAndAlgorithmParams, + sizeof(kP256Pkcs8MatchingCurveOIDAndAlgorithmParams)); + DataBuffer data(kP256Data, sizeof(kP256Data)); + DataBuffer sig; + EXPECT_TRUE(ImportPrivateKeyAndSignHashedData(k, data, &sig)); }; // Importing a private key in PKCS#8 format must succeed when the outer AlgID // struct and the inner ECPrivateKey contain dissimilar namedCurve parameters. // The inner curveOID is always ignored, so only the outer one will be used. TEST_F(Pkcs11EcdsaSha256Test, ImportDissimilarCurveOIDAndAlgorithmParams) { - EXPECT_TRUE(ImportPrivateKeyAndSignHashedData( - kP256Pkcs8DissimilarCurveOIDAndAlgorithmParams, - sizeof(kP256Pkcs8DissimilarCurveOIDAndAlgorithmParams), kP256Data, - sizeof(kP256Data))); + DataBuffer k(kP256Pkcs8DissimilarCurveOIDAndAlgorithmParams, + sizeof(kP256Pkcs8DissimilarCurveOIDAndAlgorithmParams)); + DataBuffer data(kP256Data, sizeof(kP256Data)); + DataBuffer sig; + EXPECT_TRUE(ImportPrivateKeyAndSignHashedData(k, data, &sig)); }; // Importing a private key in PKCS#8 format must fail when the outer ASN.1 // AlgorithmID struct contains only id-ecPublicKey but no namedCurve parameter. TEST_F(Pkcs11EcdsaSha256Test, ImportNoAlgorithmParams) { - EXPECT_FALSE(ImportPrivateKey(kP256Pkcs8NoAlgorithmParams, - sizeof(kP256Pkcs8NoAlgorithmParams))); + DataBuffer k(kP256Pkcs8NoAlgorithmParams, + sizeof(kP256Pkcs8NoAlgorithmParams)); + EXPECT_FALSE(ImportPrivateKey(k)); }; // Importing a private key in PKCS#8 format must fail when id-ecPublicKey is // given (so we know it's an EC key) but the namedCurve parameter is unknown. TEST_F(Pkcs11EcdsaSha256Test, ImportInvalidAlgorithmParams) { - EXPECT_FALSE(ImportPrivateKey(kP256Pkcs8InvalidAlgorithmParams, - sizeof(kP256Pkcs8InvalidAlgorithmParams))); + DataBuffer k(kP256Pkcs8InvalidAlgorithmParams, + sizeof(kP256Pkcs8InvalidAlgorithmParams)); + EXPECT_FALSE(ImportPrivateKey(k)); }; // Importing a private key in PKCS#8 format with a point not on the curve will // succeed. Using the contained public key however will fail when trying to // import it before using it for any operation. TEST_F(Pkcs11EcdsaSha256Test, ImportPointNotOnCurve) { - ScopedSECKEYPrivateKey privKey(ImportPrivateKey( - kP256Pkcs8PointNotOnCurve, sizeof(kP256Pkcs8PointNotOnCurve))); + DataBuffer k(kP256Pkcs8PointNotOnCurve, sizeof(kP256Pkcs8PointNotOnCurve)); + ScopedSECKEYPrivateKey privKey(ImportPrivateKey(k)); ASSERT_TRUE(privKey); ScopedSECKEYPublicKey pubKey(SECKEY_ConvertToPublicKey(privKey.get())); @@ -127,23 +141,23 @@ TEST_F(Pkcs11EcdsaSha256Test, ImportPointNotOnCurve) { // Importing a private key in PKCS#8 format must fail when no point is given. // PK11 currently offers no APIs to derive raw public keys from private values. TEST_F(Pkcs11EcdsaSha256Test, ImportNoPublicKey) { - EXPECT_FALSE( - ImportPrivateKey(kP256Pkcs8NoPublicKey, sizeof(kP256Pkcs8NoPublicKey))); + DataBuffer k(kP256Pkcs8NoPublicKey, sizeof(kP256Pkcs8NoPublicKey)); + EXPECT_FALSE(ImportPrivateKey(k)); }; // Importing a public key in SPKI format must fail when id-ecPublicKey is // given (so we know it's an EC key) but the namedCurve parameter is missing. TEST_F(Pkcs11EcdsaSha256Test, ImportSpkiNoAlgorithmParams) { - EXPECT_FALSE(ImportPublicKey(kP256SpkiNoAlgorithmParams, - sizeof(kP256SpkiNoAlgorithmParams))); + DataBuffer k(kP256SpkiNoAlgorithmParams, sizeof(kP256SpkiNoAlgorithmParams)); + EXPECT_FALSE(ImportPublicKey(k)); } // Importing a public key in SPKI format with a point not on the curve will // succeed. Using the public key however will fail when trying to import // it before using it for any operation. TEST_F(Pkcs11EcdsaSha256Test, ImportSpkiPointNotOnCurve) { - ScopedSECKEYPublicKey pubKey(ImportPublicKey( - kP256SpkiPointNotOnCurve, sizeof(kP256SpkiPointNotOnCurve))); + DataBuffer k(kP256SpkiPointNotOnCurve, sizeof(kP256SpkiPointNotOnCurve)); + ScopedSECKEYPublicKey pubKey(ImportPublicKey(k)); ASSERT_TRUE(pubKey); ScopedPK11SlotInfo slot(PK11_GetInternalSlot()); diff --git a/security/nss/gtests/pk11_gtest/pk11_encrypt_derive_unittest.cc b/security/nss/gtests/pk11_gtest/pk11_encrypt_derive_unittest.cc new file mode 100644 index 000000000..aa92756f2 --- /dev/null +++ b/security/nss/gtests/pk11_gtest/pk11_encrypt_derive_unittest.cc @@ -0,0 +1,210 @@ +/* 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 "pk11pub.h" +#include "nssutil.h" +#include <stdio.h> +#include "prerror.h" +#include "nss.h" +#include "gtest/gtest.h" +#include "scoped_ptrs.h" +#include "cpputil.h" +#include "databuffer.h" +#include "util.h" + +#define MAX_KEY_SIZE 24 + +namespace nss_test { + +static const uint8_t kIv[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77}; +static const uint8_t kInput[] = { + 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00, 0xff, 0xee, 0xdd, 0xcc, + 0xbb, 0xaa, 0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00}; + +class EncryptDeriveTest + : public ::testing::Test, + public ::testing::WithParamInterface<CK_MECHANISM_TYPE> { + public: + void TestEncryptDerive() { + ScopedPK11SymKey derived_key(PK11_Derive(key_.get(), derive_mech(), + derive_param(), encrypt_mech(), + CKA_DECRYPT, keysize())); + ASSERT_TRUE(derived_key); + + uint8_t derived_key_data[MAX_KEY_SIZE]; + ASSERT_GE(sizeof(derived_key_data), keysize()); + GetKeyData(derived_key, derived_key_data, keysize()); + RemoveChecksum(derived_key_data); + + uint8_t reference_key_data[MAX_KEY_SIZE]; + unsigned int reference_len = 0; + SECStatus rv = PK11_Encrypt(key_.get(), encrypt_mech(), encrypt_param(), + reference_key_data, &reference_len, keysize(), + kInput, keysize()); + ASSERT_EQ(SECSuccess, rv); + ASSERT_EQ(keysize(), static_cast<size_t>(reference_len)); + RemoveChecksum(reference_key_data); + + EXPECT_EQ(DataBuffer(reference_key_data, keysize()), + DataBuffer(derived_key_data, keysize())); + } + + protected: + unsigned int keysize() const { return 16; } + + private: + CK_MECHANISM_TYPE encrypt_mech() const { return GetParam(); } + + CK_MECHANISM_TYPE derive_mech() const { + switch (encrypt_mech()) { + case CKM_DES3_ECB: + return CKM_DES3_ECB_ENCRYPT_DATA; + case CKM_DES3_CBC: + return CKM_DES3_CBC_ENCRYPT_DATA; + case CKM_AES_ECB: + return CKM_AES_ECB_ENCRYPT_DATA; + case CKM_AES_CBC: + return CKM_AES_CBC_ENCRYPT_DATA; + case CKM_CAMELLIA_ECB: + return CKM_CAMELLIA_ECB_ENCRYPT_DATA; + case CKM_CAMELLIA_CBC: + return CKM_CAMELLIA_CBC_ENCRYPT_DATA; + case CKM_SEED_ECB: + return CKM_SEED_ECB_ENCRYPT_DATA; + case CKM_SEED_CBC: + return CKM_SEED_CBC_ENCRYPT_DATA; + default: + ADD_FAILURE() << "Unknown mechanism"; + break; + } + return CKM_INVALID_MECHANISM; + } + + SECItem* derive_param() const { + static CK_AES_CBC_ENCRYPT_DATA_PARAMS aes_data; + static CK_DES_CBC_ENCRYPT_DATA_PARAMS des_data; + static CK_KEY_DERIVATION_STRING_DATA string_data; + static SECItem param = {siBuffer, NULL, 0}; + + switch (encrypt_mech()) { + case CKM_DES3_ECB: + case CKM_AES_ECB: + case CKM_CAMELLIA_ECB: + case CKM_SEED_ECB: + string_data.pData = toUcharPtr(kInput); + string_data.ulLen = keysize(); + param.data = reinterpret_cast<uint8_t*>(&string_data); + param.len = sizeof(string_data); + break; + + case CKM_DES3_CBC: + des_data.pData = toUcharPtr(kInput); + des_data.length = keysize(); + PORT_Memcpy(des_data.iv, kIv, 8); + param.data = reinterpret_cast<uint8_t*>(&des_data); + param.len = sizeof(des_data); + break; + + case CKM_AES_CBC: + case CKM_CAMELLIA_CBC: + case CKM_SEED_CBC: + aes_data.pData = toUcharPtr(kInput); + aes_data.length = keysize(); + PORT_Memcpy(aes_data.iv, kIv, keysize()); + param.data = reinterpret_cast<uint8_t*>(&aes_data); + param.len = sizeof(aes_data); + break; + + default: + ADD_FAILURE() << "Unknown mechanism"; + break; + } + return ¶m; + } + + SECItem* encrypt_param() const { + static SECItem param = {siBuffer, NULL, 0}; + + switch (encrypt_mech()) { + case CKM_DES3_ECB: + case CKM_AES_ECB: + case CKM_CAMELLIA_ECB: + case CKM_SEED_ECB: + // No parameter needed here. + break; + + case CKM_DES3_CBC: + case CKM_AES_CBC: + case CKM_CAMELLIA_CBC: + case CKM_SEED_CBC: + param.data = toUcharPtr(kIv); + param.len = keysize(); + break; + + default: + ADD_FAILURE() << "Unknown mechanism"; + break; + } + return ¶m; + } + + virtual void SetUp() { + slot_.reset(PK11_GetBestSlot(derive_mech(), NULL)); + ASSERT_TRUE(slot_); + + key_.reset(PK11_TokenKeyGenWithFlags(slot_.get(), encrypt_mech(), NULL, + keysize(), NULL, + CKF_ENCRYPT | CKF_DERIVE, 0, NULL)); + ASSERT_TRUE(key_); + } + + void GetKeyData(ScopedPK11SymKey& key, uint8_t* buf, size_t max_len) const { + ASSERT_EQ(SECSuccess, PK11_ExtractKeyValue(key.get())); + SECItem* data = PK11_GetKeyData(key.get()); + ASSERT_TRUE(data); + ASSERT_EQ(max_len, static_cast<size_t>(data->len)); + PORT_Memcpy(buf, data->data, data->len); + } + + // Remove checksum if the key is a 3DES key. + void RemoveChecksum(uint8_t* key_data) const { + if (encrypt_mech() != CKM_DES3_CBC && encrypt_mech() != CKM_DES3_ECB) { + return; + } + for (size_t i = 0; i < keysize(); ++i) { + key_data[i] &= 0xfe; + } + } + + ScopedPK11SlotInfo slot_; + ScopedPK11SymKey key_; +}; + +TEST_P(EncryptDeriveTest, Test) { TestEncryptDerive(); } + +static const CK_MECHANISM_TYPE kEncryptDeriveMechanisms[] = { + CKM_DES3_ECB, CKM_DES3_CBC, CKM_AES_ECB, CKM_AES_ECB, CKM_AES_CBC, + CKM_CAMELLIA_ECB, CKM_CAMELLIA_CBC, CKM_SEED_ECB, CKM_SEED_CBC}; + +INSTANTIATE_TEST_CASE_P(EncryptDeriveTests, EncryptDeriveTest, + ::testing::ValuesIn(kEncryptDeriveMechanisms)); + +// This class handles the case where 3DES takes a 192-bit key +// where all 24 octets will be used. +class EncryptDerive3Test : public EncryptDeriveTest { + protected: + unsigned int keysize() const { return 24; } +}; + +TEST_P(EncryptDerive3Test, Test) { TestEncryptDerive(); } + +static const CK_MECHANISM_TYPE kDES3EncryptDeriveMechanisms[] = {CKM_DES3_ECB, + CKM_DES3_CBC}; + +INSTANTIATE_TEST_CASE_P(Encrypt3DeriveTests, EncryptDerive3Test, + ::testing::ValuesIn(kDES3EncryptDeriveMechanisms)); + +} // namespace nss_test diff --git a/security/nss/gtests/pk11_gtest/pk11_gtest.gyp b/security/nss/gtests/pk11_gtest/pk11_gtest.gyp index c47ff4778..076b4d37f 100644 --- a/security/nss/gtests/pk11_gtest/pk11_gtest.gyp +++ b/security/nss/gtests/pk11_gtest/pk11_gtest.gyp @@ -16,6 +16,7 @@ 'pk11_chacha20poly1305_unittest.cc', 'pk11_curve25519_unittest.cc', 'pk11_ecdsa_unittest.cc', + 'pk11_encrypt_derive_unittest.cc', 'pk11_pbkdf2_unittest.cc', 'pk11_prf_unittest.cc', 'pk11_prng_unittest.cc', @@ -26,6 +27,7 @@ 'dependencies': [ '<(DEPTH)/exports.gyp:nss_exports', '<(DEPTH)/lib/util/util.gyp:nssutil3', + '<(DEPTH)/cpputil/cpputil.gyp:cpputil', '<(DEPTH)/gtests/google_test/google_test.gyp:gtest', ], 'conditions': [ diff --git a/security/nss/gtests/pk11_gtest/pk11_rsapss_unittest.cc b/security/nss/gtests/pk11_gtest/pk11_rsapss_unittest.cc index 012bae0e9..6c8c5ab4e 100644 --- a/security/nss/gtests/pk11_gtest/pk11_rsapss_unittest.cc +++ b/security/nss/gtests/pk11_gtest/pk11_rsapss_unittest.cc @@ -12,14 +12,14 @@ #include "gtest/gtest.h" #include "scoped_ptrs.h" -#include "pk11_rsapss_vectors.h" #include "pk11_signature_test.h" +#include "pk11_rsapss_vectors.h" namespace nss_test { -class Pkcs11RsaPssVectorTest : public Pk11SignatureTest { +class Pkcs11RsaPssTest : public Pk11SignatureTest { public: - Pkcs11RsaPssVectorTest() { + Pkcs11RsaPssTest() : Pk11SignatureTest(CKM_RSA_PKCS_PSS, SEC_OID_SHA1) { rsaPssParams_.hashAlg = CKM_SHA_1; rsaPssParams_.mgf = CKG_MGF1_SHA1; rsaPssParams_.sLen = HASH_ResultLenByOidTag(SEC_OID_SHA1); @@ -30,16 +30,14 @@ class Pkcs11RsaPssVectorTest : public Pk11SignatureTest { } protected: - CK_MECHANISM_TYPE mechanism() { return CKM_RSA_PKCS_PSS; } - SECItem* parameters() { return ¶ms_; } - SECOidTag hashOID() { return SEC_OID_SHA1; } + const SECItem* parameters() const { return ¶ms_; } private: CK_RSA_PKCS_PSS_PARAMS rsaPssParams_; SECItem params_; }; -TEST_F(Pkcs11RsaPssVectorTest, GenerateAndSignAndVerify) { +TEST_F(Pkcs11RsaPssTest, GenerateAndSignAndVerify) { // Sign data with a 1024-bit RSA key, using PSS/SHA-256. SECOidTag hashOid = SEC_OID_SHA256; CK_MECHANISM_TYPE hashMech = CKM_SHA256; @@ -95,105 +93,56 @@ TEST_F(Pkcs11RsaPssVectorTest, GenerateAndSignAndVerify) { EXPECT_EQ(rv, SECFailure); } -// RSA-PSS test vectors, pss-vect.txt, Example 1.1: A 1024-bit RSA Key Pair -// <ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip> -TEST_F(Pkcs11RsaPssVectorTest, VerifyKnownSignature1) { - SIG_TEST_VECTOR_VERIFY(kTestVector1Spki, kTestVector1Data, kTestVector1Sig); -} -TEST_F(Pkcs11RsaPssVectorTest, SignAndVerify1) { - SIG_TEST_VECTOR_SIGN_VERIFY(kTestVector1Pkcs8, kTestVector1Spki, - kTestVector1Data); -} +class Pkcs11RsaPssVectorTest + : public Pkcs11RsaPssTest, + public ::testing::WithParamInterface<Pkcs11SignatureTestParams> {}; -// RSA-PSS test vectors, pss-vect.txt, Example 2.1: A 1025-bit RSA Key Pair -// <ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip> -TEST_F(Pkcs11RsaPssVectorTest, VerifyKnownSignature2) { - SIG_TEST_VECTOR_VERIFY(kTestVector2Spki, kTestVector2Data, kTestVector2Sig); -} -TEST_F(Pkcs11RsaPssVectorTest, SignAndVerify2) { - SIG_TEST_VECTOR_SIGN_VERIFY(kTestVector2Pkcs8, kTestVector2Spki, - kTestVector2Data); -} +TEST_P(Pkcs11RsaPssVectorTest, Verify) { Verify(GetParam()); } -// RSA-PSS test vectors, pss-vect.txt, Example 3.1: A 1026-bit RSA Key Pair -// <ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip> -TEST_F(Pkcs11RsaPssVectorTest, VerifyKnownSignature3) { - SIG_TEST_VECTOR_VERIFY(kTestVector3Spki, kTestVector3Data, kTestVector3Sig); -} -TEST_F(Pkcs11RsaPssVectorTest, SignAndVerify3) { - SIG_TEST_VECTOR_SIGN_VERIFY(kTestVector3Pkcs8, kTestVector3Spki, - kTestVector3Data); -} +TEST_P(Pkcs11RsaPssVectorTest, SignAndVerify) { SignAndVerify(GetParam()); } -// RSA-PSS test vectors, pss-vect.txt, Example 4.1: A 1027-bit RSA Key Pair -// <ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip> -TEST_F(Pkcs11RsaPssVectorTest, VerifyKnownSignature4) { - SIG_TEST_VECTOR_VERIFY(kTestVector4Spki, kTestVector4Data, kTestVector4Sig); -} -TEST_F(Pkcs11RsaPssVectorTest, SignAndVerify4) { - SIG_TEST_VECTOR_SIGN_VERIFY(kTestVector4Pkcs8, kTestVector4Spki, - kTestVector4Data); -} - -// RSA-PSS test vectors, pss-vect.txt, Example 5.1: A 1028-bit RSA Key Pair -// <ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip> -TEST_F(Pkcs11RsaPssVectorTest, VerifyKnownSignature5) { - SIG_TEST_VECTOR_VERIFY(kTestVector5Spki, kTestVector5Data, kTestVector5Sig); -} -TEST_F(Pkcs11RsaPssVectorTest, SignAndVerify5) { - SIG_TEST_VECTOR_SIGN_VERIFY(kTestVector5Pkcs8, kTestVector5Spki, - kTestVector5Data); -} - -// RSA-PSS test vectors, pss-vect.txt, Example 6.1: A 1029-bit RSA Key Pair -// <ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip> -TEST_F(Pkcs11RsaPssVectorTest, VerifyKnownSignature6) { - SIG_TEST_VECTOR_VERIFY(kTestVector6Spki, kTestVector6Data, kTestVector6Sig); -} -TEST_F(Pkcs11RsaPssVectorTest, SignAndVerify6) { - SIG_TEST_VECTOR_SIGN_VERIFY(kTestVector6Pkcs8, kTestVector6Spki, - kTestVector6Data); -} - -// RSA-PSS test vectors, pss-vect.txt, Example 7.1: A 1030-bit RSA Key Pair -// <ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip> -TEST_F(Pkcs11RsaPssVectorTest, VerifyKnownSignature7) { - SIG_TEST_VECTOR_VERIFY(kTestVector7Spki, kTestVector7Data, kTestVector7Sig); -} -TEST_F(Pkcs11RsaPssVectorTest, SignAndVerify7) { - SIG_TEST_VECTOR_SIGN_VERIFY(kTestVector7Pkcs8, kTestVector7Spki, - kTestVector7Data); -} - -// RSA-PSS test vectors, pss-vect.txt, Example 8.1: A 1031-bit RSA Key Pair -// <ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip> -TEST_F(Pkcs11RsaPssVectorTest, VerifyKnownSignature8) { - SIG_TEST_VECTOR_VERIFY(kTestVector8Spki, kTestVector8Data, kTestVector8Sig); -} -TEST_F(Pkcs11RsaPssVectorTest, SignAndVerify8) { - SIG_TEST_VECTOR_SIGN_VERIFY(kTestVector8Pkcs8, kTestVector8Spki, - kTestVector8Data); -} - -// RSA-PSS test vectors, pss-vect.txt, Example 9.1: A 1536-bit RSA Key Pair -// <ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip> -TEST_F(Pkcs11RsaPssVectorTest, VerifyKnownSignature9) { - SIG_TEST_VECTOR_VERIFY(kTestVector9Spki, kTestVector9Data, kTestVector9Sig); -} -TEST_F(Pkcs11RsaPssVectorTest, SignAndVerify9) { - SIG_TEST_VECTOR_SIGN_VERIFY(kTestVector9Pkcs8, kTestVector9Spki, - kTestVector9Data); -} - -// RSA-PSS test vectors, pss-vect.txt, Example 10.1: A 2048-bit RSA Key Pair -// <ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip> -TEST_F(Pkcs11RsaPssVectorTest, VerifyKnownSignature10) { - SIG_TEST_VECTOR_VERIFY(kTestVector10Spki, kTestVector10Data, - kTestVector10Sig); -} -TEST_F(Pkcs11RsaPssVectorTest, SignAndVerify10) { - SIG_TEST_VECTOR_SIGN_VERIFY(kTestVector10Pkcs8, kTestVector10Spki, - kTestVector10Data); -} +#define VECTOR(pkcs8, spki, data, sig) \ + { \ + DataBuffer(pkcs8, sizeof(pkcs8)), DataBuffer(spki, sizeof(spki)), \ + DataBuffer(data, sizeof(data)), DataBuffer(sig, sizeof(sig)) \ + } +#define VECTOR_N(n) \ + VECTOR(kTestVector##n##Pkcs8, kTestVector##n##Spki, kTestVector##n##Data, \ + kTestVector##n##Sig) + +static const Pkcs11SignatureTestParams kRsaPssVectors[] = { + // RSA-PSS test vectors, pss-vect.txt, Example 1.1: A 1024-bit RSA Key Pair + // <ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip> + VECTOR_N(1), + // RSA-PSS test vectors, pss-vect.txt, Example 2.1: A 1025-bit RSA Key Pair + // <ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip> + VECTOR_N(2), + // RSA-PSS test vectors, pss-vect.txt, Example 3.1: A 1026-bit RSA Key Pair + // <ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip> + VECTOR_N(3), + // RSA-PSS test vectors, pss-vect.txt, Example 4.1: A 1027-bit RSA Key Pair + // <ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip> + VECTOR_N(4), + // RSA-PSS test vectors, pss-vect.txt, Example 5.1: A 1028-bit RSA Key Pair + // <ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip> + VECTOR_N(5), + // RSA-PSS test vectors, pss-vect.txt, Example 6.1: A 1029-bit RSA Key Pair + // <ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip> + VECTOR_N(6), + // RSA-PSS test vectors, pss-vect.txt, Example 7.1: A 1030-bit RSA Key Pair + // <ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip> + VECTOR_N(7), + // RSA-PSS test vectors, pss-vect.txt, Example 8.1: A 1031-bit RSA Key Pair + // <ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip> + VECTOR_N(8), + // RSA-PSS test vectors, pss-vect.txt, Example 9.1: A 1536-bit RSA Key Pair + // <ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip> + VECTOR_N(9), + // RSA-PSS test vectors, pss-vect.txt, Example 10.1: A 2048-bit RSA Key Pair + // <ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip> + VECTOR_N(10)}; + +INSTANTIATE_TEST_CASE_P(RsaPssSignVerify, Pkcs11RsaPssVectorTest, + ::testing::ValuesIn(kRsaPssVectors)); } // namespace nss_test diff --git a/security/nss/gtests/pk11_gtest/pk11_signature_test.h b/security/nss/gtests/pk11_gtest/pk11_signature_test.h index e6a0a9c57..b14104371 100644 --- a/security/nss/gtests/pk11_gtest/pk11_signature_test.h +++ b/security/nss/gtests/pk11_gtest/pk11_signature_test.h @@ -9,26 +9,37 @@ #include "cpputil.h" #include "scoped_ptrs.h" +#include "databuffer.h" #include "gtest/gtest.h" namespace nss_test { +// For test vectors. +struct Pkcs11SignatureTestParams { + const DataBuffer pkcs8_; + const DataBuffer spki_; + const DataBuffer data_; + const DataBuffer signature_; +}; + class Pk11SignatureTest : public ::testing::Test { protected: - virtual CK_MECHANISM_TYPE mechanism() = 0; - virtual SECItem* parameters() = 0; - virtual SECOidTag hashOID() = 0; + Pk11SignatureTest(CK_MECHANISM_TYPE mechanism, SECOidTag hash_oid) + : mechanism_(mechanism), hash_oid_(hash_oid) {} - ScopedSECKEYPrivateKey ImportPrivateKey(const uint8_t* pkcs8, - size_t pkcs8_len) { + virtual const SECItem* parameters() const { return nullptr; } + CK_MECHANISM_TYPE mechanism() const { return mechanism_; } + + ScopedSECKEYPrivateKey ImportPrivateKey(const DataBuffer& pkcs8) { ScopedPK11SlotInfo slot(PK11_GetInternalSlot()); if (!slot) { + ADD_FAILURE() << "No slot"; return nullptr; } - SECItem pkcs8Item = {siBuffer, toUcharPtr(pkcs8), - static_cast<unsigned int>(pkcs8_len)}; + SECItem pkcs8Item = {siBuffer, toUcharPtr(pkcs8.data()), + static_cast<unsigned int>(pkcs8.len())}; SECKEYPrivateKey* key = nullptr; SECStatus rv = PK11_ImportDERPrivateKeyInfoAndReturnKey( @@ -42,9 +53,9 @@ class Pk11SignatureTest : public ::testing::Test { return ScopedSECKEYPrivateKey(key); } - ScopedSECKEYPublicKey ImportPublicKey(const uint8_t* spki, size_t spki_len) { - SECItem spkiItem = {siBuffer, toUcharPtr(spki), - static_cast<unsigned int>(spki_len)}; + ScopedSECKEYPublicKey ImportPublicKey(const DataBuffer& spki) { + SECItem spkiItem = {siBuffer, toUcharPtr(spki.data()), + static_cast<unsigned int>(spki.len())}; ScopedCERTSubjectPublicKeyInfo certSpki( SECKEY_DecodeDERSubjectPublicKeyInfo(&spkiItem)); @@ -52,87 +63,74 @@ class Pk11SignatureTest : public ::testing::Test { return ScopedSECKEYPublicKey(SECKEY_ExtractPublicKey(certSpki.get())); } - ScopedSECItem ComputeHash(const uint8_t* data, size_t len) { - unsigned int hLen = HASH_ResultLenByOidTag(hashOID()); - ScopedSECItem hash(SECITEM_AllocItem(nullptr, nullptr, hLen)); - if (!hash) { - return nullptr; - } - - SECStatus rv = PK11_HashBuf(hashOID(), hash->data, data, len); - if (rv != SECSuccess) { - return nullptr; - } - - return hash; + bool ComputeHash(const DataBuffer& data, DataBuffer* hash) { + hash->Allocate(static_cast<size_t>(HASH_ResultLenByOidTag(hash_oid_))); + SECStatus rv = + PK11_HashBuf(hash_oid_, hash->data(), data.data(), data.len()); + return rv == SECSuccess; } - ScopedSECItem SignHashedData(ScopedSECKEYPrivateKey& privKey, - ScopedSECItem& hash) { - unsigned int sLen = PK11_SignatureLen(privKey.get()); - ScopedSECItem sig(SECITEM_AllocItem(nullptr, nullptr, sLen)); - if (!sig) { - return nullptr; - } - - SECStatus rv = PK11_SignWithMechanism(privKey.get(), mechanism(), - parameters(), sig.get(), hash.get()); - if (rv != SECSuccess) { - return nullptr; - } - - return sig; + bool SignHashedData(ScopedSECKEYPrivateKey& privKey, const DataBuffer& hash, + DataBuffer* sig) { + SECItem hashItem = {siBuffer, toUcharPtr(hash.data()), + static_cast<unsigned int>(hash.len())}; + int sigLen = PK11_SignatureLen(privKey.get()); + EXPECT_LT(0, sigLen); + sig->Allocate(static_cast<size_t>(sigLen)); + SECItem sigItem = {siBuffer, toUcharPtr(sig->data()), + static_cast<unsigned int>(sig->len())}; + SECStatus rv = PK11_SignWithMechanism(privKey.get(), mechanism_, + parameters(), &sigItem, &hashItem); + return rv == SECSuccess; } - ScopedSECItem ImportPrivateKeyAndSignHashedData(const uint8_t* pkcs8, - size_t pkcs8_len, - const uint8_t* data, - size_t data_len) { - ScopedSECKEYPrivateKey privKey(ImportPrivateKey(pkcs8, pkcs8_len)); + bool ImportPrivateKeyAndSignHashedData(const DataBuffer& pkcs8, + const DataBuffer& data, + DataBuffer* sig) { + ScopedSECKEYPrivateKey privKey(ImportPrivateKey(pkcs8)); if (!privKey) { - return nullptr; + return false; } - ScopedSECItem hash(ComputeHash(data, data_len)); - if (!hash) { - return nullptr; + DataBuffer hash; + if (!ComputeHash(data, &hash)) { + ADD_FAILURE() << "Failed to compute hash"; + return false; } - - return ScopedSECItem(SignHashedData(privKey, hash)); + return SignHashedData(privKey, hash, sig); } - void Verify(const uint8_t* spki, size_t spki_len, const uint8_t* data, - size_t data_len, const uint8_t* sig, size_t sig_len) { - ScopedSECKEYPublicKey pubKey(ImportPublicKey(spki, spki_len)); + void Verify(const Pkcs11SignatureTestParams& params, const DataBuffer& sig) { + ScopedSECKEYPublicKey pubKey(ImportPublicKey(params.spki_)); ASSERT_TRUE(pubKey); - ScopedSECItem hash(ComputeHash(data, data_len)); - ASSERT_TRUE(hash); - - SECItem sigItem = {siBuffer, toUcharPtr(sig), - static_cast<unsigned int>(sig_len)}; + DataBuffer hash; + ASSERT_TRUE(ComputeHash(params.data_, &hash)); // Verify. + SECItem hashItem = {siBuffer, toUcharPtr(hash.data()), + static_cast<unsigned int>(hash.len())}; + SECItem sigItem = {siBuffer, toUcharPtr(sig.data()), + static_cast<unsigned int>(sig.len())}; SECStatus rv = PK11_VerifyWithMechanism( - pubKey.get(), mechanism(), parameters(), &sigItem, hash.get(), nullptr); + pubKey.get(), mechanism_, parameters(), &sigItem, &hashItem, nullptr); EXPECT_EQ(rv, SECSuccess); } - void SignAndVerify(const uint8_t* pkcs8, size_t pkcs8_len, - const uint8_t* spki, size_t spki_len, const uint8_t* data, - size_t data_len) { - ScopedSECItem sig( - ImportPrivateKeyAndSignHashedData(pkcs8, pkcs8_len, data, data_len)); - ASSERT_TRUE(sig); - - Verify(spki, spki_len, data, data_len, sig->data, sig->len); + void Verify(const Pkcs11SignatureTestParams& params) { + Verify(params, params.signature_); } -}; -#define SIG_TEST_VECTOR_VERIFY(spki, data, sig) \ - Verify(spki, sizeof(spki), data, sizeof(data), sig, sizeof(sig)); + void SignAndVerify(const Pkcs11SignatureTestParams& params) { + DataBuffer sig; + ASSERT_TRUE( + ImportPrivateKeyAndSignHashedData(params.pkcs8_, params.data_, &sig)); + Verify(params, sig); + } -#define SIG_TEST_VECTOR_SIGN_VERIFY(pkcs8, spki, data) \ - SignAndVerify(pkcs8, sizeof(pkcs8), spki, sizeof(spki), data, sizeof(data)); + private: + CK_MECHANISM_TYPE mechanism_; + SECOidTag hash_oid_; +}; } // namespace nss_test diff --git a/security/nss/gtests/softoken_gtest/Makefile b/security/nss/gtests/softoken_gtest/Makefile new file mode 100644 index 000000000..996669782 --- /dev/null +++ b/security/nss/gtests/softoken_gtest/Makefile @@ -0,0 +1,45 @@ +#! gmake +# +# 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/. + +####################################################################### +# (1) Include initial platform-independent assignments (MANDATORY). # +####################################################################### + +include manifest.mn + +####################################################################### +# (2) Include "global" configuration information. (OPTIONAL) # +####################################################################### + +include $(CORE_DEPTH)/coreconf/config.mk + +####################################################################### +# (3) Include "component" configuration information. (OPTIONAL) # +####################################################################### + + +####################################################################### +# (4) Include "local" platform-dependent assignments (OPTIONAL). # +####################################################################### + +include ../common/gtest.mk + +CFLAGS += -I$(CORE_DEPTH)/lib/util + +####################################################################### +# (5) Execute "global" rules. (OPTIONAL) # +####################################################################### + +include $(CORE_DEPTH)/coreconf/rules.mk + +####################################################################### +# (6) Execute "component" rules. (OPTIONAL) # +####################################################################### + + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### diff --git a/security/nss/gtests/softoken_gtest/manifest.mn b/security/nss/gtests/softoken_gtest/manifest.mn new file mode 100644 index 000000000..4b34c099f --- /dev/null +++ b/security/nss/gtests/softoken_gtest/manifest.mn @@ -0,0 +1,25 @@ +# -*- makefile -*- +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +CORE_DEPTH = ../.. +DEPTH = ../.. +MODULE = nss + +CPPSRCS = \ + softoken_gtest.cc \ + $(NULL) + +INCLUDES += \ + -I$(CORE_DEPTH)/gtests/google_test/gtest/include \ + -I$(CORE_DEPTH)/cpputil \ + $(NULL) + +REQUIRES = nspr gtest + +PROGRAM = softoken_gtest + +EXTRA_LIBS = \ + $(DIST)/lib/$(LIB_PREFIX)gtest.$(LIB_SUFFIX) \ + $(DIST)/lib/$(LIB_PREFIX)gtestutil.$(LIB_SUFFIX) \ + $(NULL) diff --git a/security/nss/gtests/softoken_gtest/softoken_gtest.cc b/security/nss/gtests/softoken_gtest/softoken_gtest.cc new file mode 100644 index 000000000..d61e2e75f --- /dev/null +++ b/security/nss/gtests/softoken_gtest/softoken_gtest.cc @@ -0,0 +1,360 @@ +#include <cstdlib> +#if defined(_WIN32) +#include <windows.h> +#include <codecvt> +#endif + +#include "cert.h" +#include "certdb.h" +#include "nspr.h" +#include "nss.h" +#include "pk11pub.h" +#include "secerr.h" + +#include "scoped_ptrs.h" + +#define GTEST_HAS_RTTI 0 +#include "gtest/gtest.h" + +namespace nss_test { + +// Given a prefix, attempts to create a unique directory that the user can do +// work in without impacting other tests. For example, if given the prefix +// "scratch", a directory like "scratch05c17b25" will be created in the current +// working directory (or the location specified by NSS_GTEST_WORKDIR, if +// defined). +// Upon destruction, the implementation will attempt to delete the directory. +// However, no attempt is made to first remove files in the directory - the +// user is responsible for this. If the directory is not empty, deleting it will +// fail. +// Statistically, it is technically possible to fail to create a unique +// directory name, but this is extremely unlikely given the expected workload of +// this implementation. +class ScopedUniqueDirectory { + public: + explicit ScopedUniqueDirectory(const std::string &prefix); + + // NB: the directory must be empty upon destruction + ~ScopedUniqueDirectory() { assert(rmdir(mPath.c_str()) == 0); } + + const std::string &GetPath() { return mPath; } + const std::string &GetUTF8Path() { return mUTF8Path; } + + private: + static const int RETRY_LIMIT = 5; + static void GenerateRandomName(/*in/out*/ std::string &prefix); + static bool TryMakingDirectory(/*in/out*/ std::string &prefix); + + std::string mPath; + std::string mUTF8Path; +}; + +ScopedUniqueDirectory::ScopedUniqueDirectory(const std::string &prefix) { + std::string path; + const char *workingDirectory = PR_GetEnvSecure("NSS_GTEST_WORKDIR"); + if (workingDirectory) { + path.assign(workingDirectory); + } + path.append(prefix); + for (int i = 0; i < RETRY_LIMIT; i++) { + std::string pathCopy(path); + // TryMakingDirectory will modify its input. If it fails, we want to throw + // away the modified result. + if (TryMakingDirectory(pathCopy)) { + mPath.assign(pathCopy); + break; + } + } + assert(mPath.length() > 0); +#if defined(_WIN32) + // sqldb always uses UTF-8 regardless of the current system locale. + DWORD len = + MultiByteToWideChar(CP_ACP, 0, mPath.data(), mPath.size(), nullptr, 0); + std::vector<wchar_t> buf(len, L'\0'); + MultiByteToWideChar(CP_ACP, 0, mPath.data(), mPath.size(), buf.data(), + buf.size()); + std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter; + mUTF8Path = converter.to_bytes(std::wstring(buf.begin(), buf.end())); +#else + mUTF8Path = mPath; +#endif +} + +void ScopedUniqueDirectory::GenerateRandomName(std::string &prefix) { + std::stringstream ss; + ss << prefix; + // RAND_MAX is at least 32767. + ss << std::setfill('0') << std::setw(4) << std::hex << rand() << rand(); + // This will overwrite the value of prefix. This is a little inefficient, but + // at least it makes the code simple. + ss >> prefix; +} + +bool ScopedUniqueDirectory::TryMakingDirectory(std::string &prefix) { + GenerateRandomName(prefix); +#if defined(_WIN32) + return _mkdir(prefix.c_str()) == 0; +#else + return mkdir(prefix.c_str(), 0777) == 0; +#endif +} + +class SoftokenTest : public ::testing::Test { + protected: + SoftokenTest() : mNSSDBDir("SoftokenTest.d-") {} + SoftokenTest(const std::string &prefix) : mNSSDBDir(prefix) {} + + virtual void SetUp() { + std::string nssInitArg("sql:"); + nssInitArg.append(mNSSDBDir.GetUTF8Path()); + ASSERT_EQ(SECSuccess, NSS_Initialize(nssInitArg.c_str(), "", "", SECMOD_DB, + NSS_INIT_NOROOTINIT)); + } + + virtual void TearDown() { + ASSERT_EQ(SECSuccess, NSS_Shutdown()); + const std::string &nssDBDirPath = mNSSDBDir.GetPath(); + ASSERT_EQ(0, unlink((nssDBDirPath + "/cert9.db").c_str())); + ASSERT_EQ(0, unlink((nssDBDirPath + "/key4.db").c_str())); + ASSERT_EQ(0, unlink((nssDBDirPath + "/pkcs11.txt").c_str())); + } + + ScopedUniqueDirectory mNSSDBDir; +}; + +TEST_F(SoftokenTest, ResetSoftokenEmptyPassword) { + ScopedPK11SlotInfo slot(PK11_GetInternalKeySlot()); + ASSERT_TRUE(slot); + EXPECT_EQ(SECSuccess, PK11_InitPin(slot.get(), nullptr, nullptr)); + EXPECT_EQ(SECSuccess, PK11_ResetToken(slot.get(), nullptr)); + EXPECT_EQ(SECSuccess, PK11_InitPin(slot.get(), nullptr, nullptr)); +} + +TEST_F(SoftokenTest, ResetSoftokenNonEmptyPassword) { + ScopedPK11SlotInfo slot(PK11_GetInternalKeySlot()); + ASSERT_TRUE(slot); + EXPECT_EQ(SECSuccess, PK11_InitPin(slot.get(), nullptr, "password")); + EXPECT_EQ(SECSuccess, PK11_ResetToken(slot.get(), nullptr)); + EXPECT_EQ(SECSuccess, PK11_InitPin(slot.get(), nullptr, "password2")); +} + +// Test certificate to use in the CreateObject tests. +static const CK_OBJECT_CLASS cko_nss_trust = CKO_NSS_TRUST; +static const CK_BBOOL ck_false = CK_FALSE; +static const CK_BBOOL ck_true = CK_TRUE; +static const CK_TRUST ckt_nss_must_verify_trust = CKT_NSS_MUST_VERIFY_TRUST; +static const CK_TRUST ckt_nss_trusted_delegator = CKT_NSS_TRUSTED_DELEGATOR; +static const CK_ATTRIBUTE attributes[] = { + {CKA_CLASS, (void *)&cko_nss_trust, (PRUint32)sizeof(CK_OBJECT_CLASS)}, + {CKA_TOKEN, (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL)}, + {CKA_PRIVATE, (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL)}, + {CKA_MODIFIABLE, (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL)}, + {CKA_LABEL, + (void *)"Symantec Class 2 Public Primary Certification Authority - G4", + (PRUint32)61}, + {CKA_CERT_SHA1_HASH, + (void *)"\147\044\220\056\110\001\260\042\226\100\020\106\264\261\147\054" + "\251\165\375\053", + (PRUint32)20}, + {CKA_CERT_MD5_HASH, + (void *)"\160\325\060\361\332\224\227\324\327\164\337\276\355\150\336\226", + (PRUint32)16}, + {CKA_ISSUER, + (void *)"\060\201\224\061\013\060\011\006\003\125\004\006\023\002\125\123" + "\061\035\060\033\006\003\125\004\012\023\024\123\171\155\141\156" + "\164\145\143\040\103\157\162\160\157\162\141\164\151\157\156\061" + "\037\060\035\006\003\125\004\013\023\026\123\171\155\141\156\164" + "\145\143\040\124\162\165\163\164\040\116\145\164\167\157\162\153" + "\061\105\060\103\006\003\125\004\003\023\074\123\171\155\141\156" + "\164\145\143\040\103\154\141\163\163\040\062\040\120\165\142\154" + "\151\143\040\120\162\151\155\141\162\171\040\103\145\162\164\151" + "\146\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151" + "\164\171\040\055\040\107\064", + (PRUint32)151}, + {CKA_SERIAL_NUMBER, + (void *)"\002\020\064\027\145\022\100\073\267\126\200\055\200\313\171\125" + "\246\036", + (PRUint32)18}, + {CKA_TRUST_SERVER_AUTH, (void *)&ckt_nss_must_verify_trust, + (PRUint32)sizeof(CK_TRUST)}, + {CKA_TRUST_EMAIL_PROTECTION, (void *)&ckt_nss_trusted_delegator, + (PRUint32)sizeof(CK_TRUST)}, + {CKA_TRUST_CODE_SIGNING, (void *)&ckt_nss_must_verify_trust, + (PRUint32)sizeof(CK_TRUST)}, + {CKA_TRUST_STEP_UP_APPROVED, (void *)&ck_false, + (PRUint32)sizeof(CK_BBOOL)}}; + +TEST_F(SoftokenTest, CreateObjectNonEmptyPassword) { + ScopedPK11SlotInfo slot(PK11_GetInternalKeySlot()); + ASSERT_TRUE(slot); + EXPECT_EQ(SECSuccess, PK11_InitPin(slot.get(), nullptr, "password")); + EXPECT_EQ(SECSuccess, PK11_Logout(slot.get())); + ScopedPK11GenericObject obj(PK11_CreateGenericObject( + slot.get(), attributes, PR_ARRAY_SIZE(attributes), true)); + EXPECT_EQ(nullptr, obj); +} + +TEST_F(SoftokenTest, CreateObjectChangePassword) { + ScopedPK11SlotInfo slot(PK11_GetInternalKeySlot()); + ASSERT_TRUE(slot); + EXPECT_EQ(SECSuccess, PK11_InitPin(slot.get(), nullptr, nullptr)); + EXPECT_EQ(SECSuccess, PK11_ChangePW(slot.get(), "", "password")); + EXPECT_EQ(SECSuccess, PK11_Logout(slot.get())); + ScopedPK11GenericObject obj(PK11_CreateGenericObject( + slot.get(), attributes, PR_ARRAY_SIZE(attributes), true)); + EXPECT_EQ(nullptr, obj); +} + +TEST_F(SoftokenTest, CreateObjectChangeToEmptyPassword) { + ScopedPK11SlotInfo slot(PK11_GetInternalKeySlot()); + ASSERT_TRUE(slot); + EXPECT_EQ(SECSuccess, PK11_InitPin(slot.get(), nullptr, "password")); + EXPECT_EQ(SECSuccess, PK11_ChangePW(slot.get(), "password", "")); + // PK11_Logout returnes an error and SEC_ERROR_TOKEN_NOT_LOGGED_IN if the user + // is not "logged in". + EXPECT_EQ(SECFailure, PK11_Logout(slot.get())); + EXPECT_EQ(SEC_ERROR_TOKEN_NOT_LOGGED_IN, PORT_GetError()); + ScopedPK11GenericObject obj(PK11_CreateGenericObject( + slot.get(), attributes, PR_ARRAY_SIZE(attributes), true)); + // Because there's no password we can't logout and the operation should have + // succeeded. + EXPECT_NE(nullptr, obj); +} + +class SoftokenNonAsciiTest : public SoftokenTest { + protected: + SoftokenNonAsciiTest() : SoftokenTest("SoftokenTest.\xF7-") {} +}; + +TEST_F(SoftokenNonAsciiTest, NonAsciiPathWorking) { + ScopedPK11SlotInfo slot(PK11_GetInternalKeySlot()); + ASSERT_TRUE(slot); + EXPECT_EQ(SECSuccess, PK11_InitPin(slot.get(), nullptr, nullptr)); + EXPECT_EQ(SECSuccess, PK11_ResetToken(slot.get(), nullptr)); + EXPECT_EQ(SECSuccess, PK11_InitPin(slot.get(), nullptr, nullptr)); +} + +// This is just any X509 certificate. Its contents don't matter. +static unsigned char certDER[] = { + 0x30, 0x82, 0x01, 0xEF, 0x30, 0x82, 0x01, 0x94, 0xA0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x14, 0x49, 0xC4, 0xC4, 0x4A, 0xB6, 0x86, 0x07, 0xA3, 0x06, + 0xDC, 0x4D, 0xC8, 0xC3, 0xFE, 0xC7, 0x21, 0x3A, 0x2D, 0xE4, 0xDA, 0x30, + 0x0B, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B, + 0x30, 0x0F, 0x31, 0x0D, 0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x04, 0x74, 0x65, 0x73, 0x74, 0x30, 0x22, 0x18, 0x0F, 0x32, 0x30, 0x31, + 0x35, 0x31, 0x31, 0x32, 0x38, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5A, + 0x18, 0x0F, 0x32, 0x30, 0x31, 0x38, 0x30, 0x32, 0x30, 0x35, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x5A, 0x30, 0x0F, 0x31, 0x0D, 0x30, 0x0B, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x04, 0x74, 0x65, 0x73, 0x74, 0x30, 0x82, + 0x01, 0x22, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, + 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0F, 0x00, 0x30, 0x82, + 0x01, 0x0A, 0x02, 0x82, 0x01, 0x01, 0x00, 0xBA, 0x88, 0x51, 0xA8, 0x44, + 0x8E, 0x16, 0xD6, 0x41, 0xFD, 0x6E, 0xB6, 0x88, 0x06, 0x36, 0x10, 0x3D, + 0x3C, 0x13, 0xD9, 0xEA, 0xE4, 0x35, 0x4A, 0xB4, 0xEC, 0xF5, 0x68, 0x57, + 0x6C, 0x24, 0x7B, 0xC1, 0xC7, 0x25, 0xA8, 0xE0, 0xD8, 0x1F, 0xBD, 0xB1, + 0x9C, 0x06, 0x9B, 0x6E, 0x1A, 0x86, 0xF2, 0x6B, 0xE2, 0xAF, 0x5A, 0x75, + 0x6B, 0x6A, 0x64, 0x71, 0x08, 0x7A, 0xA5, 0x5A, 0xA7, 0x45, 0x87, 0xF7, + 0x1C, 0xD5, 0x24, 0x9C, 0x02, 0x7E, 0xCD, 0x43, 0xFC, 0x1E, 0x69, 0xD0, + 0x38, 0x20, 0x29, 0x93, 0xAB, 0x20, 0xC3, 0x49, 0xE4, 0xDB, 0xB9, 0x4C, + 0xC2, 0x6B, 0x6C, 0x0E, 0xED, 0x15, 0x82, 0x0F, 0xF1, 0x7E, 0xAD, 0x69, + 0x1A, 0xB1, 0xD3, 0x02, 0x3A, 0x8B, 0x2A, 0x41, 0xEE, 0xA7, 0x70, 0xE0, + 0x0F, 0x0D, 0x8D, 0xFD, 0x66, 0x0B, 0x2B, 0xB0, 0x24, 0x92, 0xA4, 0x7D, + 0xB9, 0x88, 0x61, 0x79, 0x90, 0xB1, 0x57, 0x90, 0x3D, 0xD2, 0x3B, 0xC5, + 0xE0, 0xB8, 0x48, 0x1F, 0xA8, 0x37, 0xD3, 0x88, 0x43, 0xEF, 0x27, 0x16, + 0xD8, 0x55, 0xB7, 0x66, 0x5A, 0xAA, 0x7E, 0x02, 0x90, 0x2F, 0x3A, 0x7B, + 0x10, 0x80, 0x06, 0x24, 0xCC, 0x1C, 0x6C, 0x97, 0xAD, 0x96, 0x61, 0x5B, + 0xB7, 0xE2, 0x96, 0x12, 0xC0, 0x75, 0x31, 0xA3, 0x0C, 0x91, 0xDD, 0xB4, + 0xCA, 0xF7, 0xFC, 0xAD, 0x1D, 0x25, 0xD3, 0x09, 0xEF, 0xB9, 0x17, 0x0E, + 0xA7, 0x68, 0xE1, 0xB3, 0x7B, 0x2F, 0x22, 0x6F, 0x69, 0xE3, 0xB4, 0x8A, + 0x95, 0x61, 0x1D, 0xEE, 0x26, 0xD6, 0x25, 0x9D, 0xAB, 0x91, 0x08, 0x4E, + 0x36, 0xCB, 0x1C, 0x24, 0x04, 0x2C, 0xBF, 0x16, 0x8B, 0x2F, 0xE5, 0xF1, + 0x8F, 0x99, 0x17, 0x31, 0xB8, 0xB3, 0xFE, 0x49, 0x23, 0xFA, 0x72, 0x51, + 0xC4, 0x31, 0xD5, 0x03, 0xAC, 0xDA, 0x18, 0x0A, 0x35, 0xED, 0x8D, 0x02, + 0x03, 0x01, 0x00, 0x01, 0x30, 0x0B, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, + 0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x03, 0x48, 0x00, 0x30, 0x45, 0x02, 0x20, + 0x5C, 0x75, 0x51, 0x9F, 0x13, 0x11, 0x50, 0xCD, 0x5D, 0x8A, 0xDE, 0x20, + 0xA3, 0xBC, 0x06, 0x30, 0x91, 0xFF, 0xB2, 0x73, 0x75, 0x5F, 0x31, 0x64, + 0xEC, 0xFD, 0xCB, 0x42, 0x80, 0x0A, 0x70, 0xE6, 0x02, 0x21, 0x00, 0x82, + 0x12, 0xF7, 0xE5, 0xEA, 0x40, 0x27, 0xFD, 0xF7, 0xC0, 0x0E, 0x25, 0xF3, + 0x3E, 0x34, 0x95, 0x80, 0xB9, 0xA3, 0x38, 0xE0, 0x56, 0x68, 0xDA, 0xE5, + 0xC1, 0xF5, 0x37, 0xC7, 0xB5, 0xCE, 0x0D}; + +struct PasswordPair { + const char *mInitialPassword; + const char *mSecondPassword; +}; + +class SoftokenPasswordChangeTest + : public SoftokenTest, + public ::testing::WithParamInterface<PasswordPair> {}; + +TEST_P(SoftokenPasswordChangeTest, KeepTrustAfterPasswordChange) { + const PasswordPair &passwords = GetParam(); + ScopedPK11SlotInfo slot(PK11_GetInternalKeySlot()); + ASSERT_TRUE(slot); + // Set a password. + EXPECT_EQ(SECSuccess, + PK11_InitPin(slot.get(), nullptr, passwords.mInitialPassword)); + SECItem certDERItem = {siBuffer, certDER, sizeof(certDER)}; + // Import a certificate. + ScopedCERTCertificate cert(CERT_NewTempCertificate( + CERT_GetDefaultCertDB(), &certDERItem, nullptr, true, true)); + EXPECT_TRUE(cert); + SECStatus result = + PK11_ImportCert(slot.get(), cert.get(), CK_INVALID_HANDLE, "test", false); + EXPECT_EQ(SECSuccess, result); + // Set a trust value. + CERTCertTrust trust = {CERTDB_TRUSTED_CLIENT_CA | CERTDB_NS_TRUSTED_CA | + CERTDB_TRUSTED_CA | CERTDB_VALID_CA, + 0, 0}; + result = CERT_ChangeCertTrust(nullptr, cert.get(), &trust); + EXPECT_EQ(SECSuccess, result); + // Release the certificate to ensure we get it from the DB rather than an + // in-memory cache, below. + cert = nullptr; + // Change the password. + result = PK11_ChangePW(slot.get(), passwords.mInitialPassword, + passwords.mSecondPassword); + EXPECT_EQ(SECSuccess, result); + // Look up the certificate again. + ScopedCERTCertificate newCert( + PK11_FindCertFromDERCertItem(slot.get(), &certDERItem, nullptr)); + EXPECT_TRUE(newCert.get()); + // The trust should be the same as before. + CERTCertTrust newTrust = {0, 0, 0}; + result = CERT_GetCertTrust(newCert.get(), &newTrust); + EXPECT_EQ(SECSuccess, result); + EXPECT_EQ(trust.sslFlags, newTrust.sslFlags); + EXPECT_EQ(trust.emailFlags, newTrust.emailFlags); + EXPECT_EQ(trust.objectSigningFlags, newTrust.objectSigningFlags); +} + +static const PasswordPair PASSWORD_CHANGE_TESTS[] = { + {"password", ""}, // non-empty to empty password + {"", "password"}, // empty to non-empty password + {"password", "password2"}, // non-empty to non-empty password +}; + +INSTANTIATE_TEST_CASE_P(SoftokenPasswordChangeTests, SoftokenPasswordChangeTest, + ::testing::ValuesIn(PASSWORD_CHANGE_TESTS)); + +class SoftokenNoDBTest : public ::testing::Test {}; + +TEST_F(SoftokenNoDBTest, NeedUserInitNoDB) { + ASSERT_EQ(SECSuccess, NSS_NoDB_Init(".")); + ScopedPK11SlotInfo slot(PK11_GetInternalKeySlot()); + ASSERT_TRUE(slot); + EXPECT_EQ(PR_FALSE, PK11_NeedUserInit(slot.get())); + + // When shutting down in here we have to release the slot first. + slot = nullptr; + ASSERT_EQ(SECSuccess, NSS_Shutdown()); +} + +} // namespace nss_test + +int main(int argc, char **argv) { + ::testing::InitGoogleTest(&argc, argv); + + return RUN_ALL_TESTS(); +} diff --git a/security/nss/gtests/softoken_gtest/softoken_gtest.gyp b/security/nss/gtests/softoken_gtest/softoken_gtest.gyp new file mode 100644 index 000000000..cff0ea414 --- /dev/null +++ b/security/nss/gtests/softoken_gtest/softoken_gtest.gyp @@ -0,0 +1,51 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +{ + 'includes': [ + '../../coreconf/config.gypi', + '../common/gtest.gypi', + ], + 'targets': [ + { + 'target_name': 'softoken_gtest', + 'type': 'executable', + 'sources': [ + 'softoken_gtest.cc', + ], + 'dependencies': [ + '<(DEPTH)/exports.gyp:nss_exports', + '<(DEPTH)/lib/util/util.gyp:nssutil3', + '<(DEPTH)/gtests/google_test/google_test.gyp:gtest', + ], + 'conditions': [ + [ 'test_build==1', { + 'dependencies': [ + '<(DEPTH)/lib/nss/nss.gyp:nss_static', + '<(DEPTH)/lib/pk11wrap/pk11wrap.gyp:pk11wrap_static', + '<(DEPTH)/lib/cryptohi/cryptohi.gyp:cryptohi', + '<(DEPTH)/lib/certhigh/certhigh.gyp:certhi', + '<(DEPTH)/lib/certdb/certdb.gyp:certdb', + '<(DEPTH)/lib/base/base.gyp:nssb', + '<(DEPTH)/lib/dev/dev.gyp:nssdev', + '<(DEPTH)/lib/pki/pki.gyp:nsspki', + '<(DEPTH)/lib/ssl/ssl.gyp:ssl', + ], + }, { + 'dependencies': [ + '<(DEPTH)/lib/nss/nss.gyp:nss3', + '<(DEPTH)/lib/ssl/ssl.gyp:ssl3', + ], + }], + ], + } + ], + 'target_defaults': { + 'include_dirs': [ + '../../lib/util' + ] + }, + 'variables': { + 'module': 'nss' + } +} diff --git a/security/nss/gtests/ssl_gtest/Makefile b/security/nss/gtests/ssl_gtest/Makefile index a9a9290e0..95c111aeb 100644 --- a/security/nss/gtests/ssl_gtest/Makefile +++ b/security/nss/gtests/ssl_gtest/Makefile @@ -29,10 +29,6 @@ include ../common/gtest.mk CFLAGS += -I$(CORE_DEPTH)/lib/ssl -ifdef NSS_SSL_ENABLE_ZLIB -include $(CORE_DEPTH)/coreconf/zlib.mk -endif - ifdef NSS_DISABLE_TLS_1_3 NSS_DISABLE_TLS_1_3=1 # Run parameterized tests only, for which we can easily exclude TLS 1.3 diff --git a/security/nss/gtests/ssl_gtest/bloomfilter_unittest.cc b/security/nss/gtests/ssl_gtest/bloomfilter_unittest.cc new file mode 100644 index 000000000..6efe06ec7 --- /dev/null +++ b/security/nss/gtests/ssl_gtest/bloomfilter_unittest.cc @@ -0,0 +1,108 @@ +/* -*- 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/. */ + +extern "C" { +#include "sslbloom.h" +} + +#include "gtest_utils.h" + +namespace nss_test { + +// Some random-ish inputs to test with. These don't result in collisions in any +// of the configurations that are tested below. +static const uint8_t kHashes1[] = { + 0x79, 0x53, 0xb8, 0xdd, 0x6b, 0x98, 0xce, 0x00, 0xb7, 0xdc, 0xe8, + 0x03, 0x70, 0x8c, 0xe3, 0xac, 0x06, 0x8b, 0x22, 0xfd, 0x0e, 0x34, + 0x48, 0xe6, 0xe5, 0xe0, 0x8a, 0xd6, 0x16, 0x18, 0xe5, 0x48}; +static const uint8_t kHashes2[] = { + 0xc6, 0xdd, 0x6e, 0xc4, 0x76, 0xb8, 0x55, 0xf2, 0xa4, 0xfc, 0x59, + 0x04, 0xa4, 0x90, 0xdc, 0xa7, 0xa7, 0x0d, 0x94, 0x8f, 0xc2, 0xdc, + 0x15, 0x6d, 0x48, 0x93, 0x9d, 0x05, 0xbb, 0x9a, 0xbc, 0xc1}; + +typedef struct { + unsigned int k; + unsigned int bits; +} BloomFilterConfig; + +class BloomFilterTest + : public ::testing::Test, + public ::testing::WithParamInterface<BloomFilterConfig> { + public: + BloomFilterTest() : filter_() {} + + void SetUp() { Init(); } + + void TearDown() { sslBloom_Destroy(&filter_); } + + protected: + void Init() { + if (filter_.filter) { + sslBloom_Destroy(&filter_); + } + ASSERT_EQ(SECSuccess, + sslBloom_Init(&filter_, GetParam().k, GetParam().bits)); + } + + bool Check(const uint8_t* hashes) { + return sslBloom_Check(&filter_, hashes) ? true : false; + } + + void Add(const uint8_t* hashes, bool expect_collision = false) { + EXPECT_EQ(expect_collision, sslBloom_Add(&filter_, hashes) ? true : false); + EXPECT_TRUE(Check(hashes)); + } + + sslBloomFilter filter_; +}; + +TEST_P(BloomFilterTest, InitOnly) {} + +TEST_P(BloomFilterTest, AddToEmpty) { + EXPECT_FALSE(Check(kHashes1)); + Add(kHashes1); +} + +TEST_P(BloomFilterTest, AddTwo) { + Add(kHashes1); + Add(kHashes2); +} + +TEST_P(BloomFilterTest, AddOneTwice) { + Add(kHashes1); + Add(kHashes1, true); +} + +TEST_P(BloomFilterTest, Zero) { + Add(kHashes1); + sslBloom_Zero(&filter_); + EXPECT_FALSE(Check(kHashes1)); + EXPECT_FALSE(Check(kHashes2)); +} + +TEST_P(BloomFilterTest, Fill) { + sslBloom_Fill(&filter_); + EXPECT_TRUE(Check(kHashes1)); + EXPECT_TRUE(Check(kHashes2)); +} + +static const BloomFilterConfig kBloomFilterConfigurations[] = { + {1, 1}, // 1 hash, 1 bit input - high chance of collision. + {1, 2}, // 1 hash, 2 bits - smaller than the basic unit size. + {1, 3}, // 1 hash, 3 bits - same as basic unit size. + {1, 4}, // 1 hash, 4 bits - 2 octets each. + {3, 10}, // 3 hashes over a reasonable number of bits. + {3, 3}, // Test that we can read multiple bits. + {4, 15}, // A credible filter. + {2, 18}, // A moderately large allocation. + {16, 16}, // Insane, use all of the bits from the hashes. + {16, 9}, // This also uses all of the bits from the hashes. +}; + +INSTANTIATE_TEST_CASE_P(BloomFilterConfigurations, BloomFilterTest, + ::testing::ValuesIn(kBloomFilterConfigurations)); + +} // namespace nss_test diff --git a/security/nss/gtests/ssl_gtest/libssl_internals.c b/security/nss/gtests/ssl_gtest/libssl_internals.c index 97b8354ae..17b4ffe49 100644 --- a/security/nss/gtests/ssl_gtest/libssl_internals.c +++ b/security/nss/gtests/ssl_gtest/libssl_internals.c @@ -34,18 +34,17 @@ SECStatus SSLInt_UpdateSSLv2ClientRandom(PRFileDesc *fd, uint8_t *rnd, return SECFailure; } - ssl3_InitState(ss); ssl3_RestartHandshakeHashes(ss); // Ensure we don't overrun hs.client_random. rnd_len = PR_MIN(SSL3_RANDOM_LENGTH, rnd_len); - // Zero the client_random struct. - PORT_Memset(&ss->ssl3.hs.client_random, 0, SSL3_RANDOM_LENGTH); + // Zero the client_random. + PORT_Memset(ss->ssl3.hs.client_random, 0, SSL3_RANDOM_LENGTH); // Copy over the challenge bytes. size_t offset = SSL3_RANDOM_LENGTH - rnd_len; - PORT_Memcpy(&ss->ssl3.hs.client_random.rand[offset], rnd, rnd_len); + PORT_Memcpy(ss->ssl3.hs.client_random + offset, rnd, rnd_len); // Rehash the SSLv2 client hello message. return ssl3_UpdateHandshakeHashes(ss, msg, msg_len); @@ -73,10 +72,11 @@ SECStatus SSLInt_SetMTU(PRFileDesc *fd, PRUint16 mtu) { return SECFailure; } ss->ssl3.mtu = mtu; + ss->ssl3.hs.rtRetries = 0; /* Avoid DTLS shrinking the MTU any more. */ return SECSuccess; } -PRInt32 SSLInt_CountTls13CipherSpecs(PRFileDesc *fd) { +PRInt32 SSLInt_CountCipherSpecs(PRFileDesc *fd) { PRCList *cur_p; PRInt32 ct = 0; @@ -92,7 +92,7 @@ PRInt32 SSLInt_CountTls13CipherSpecs(PRFileDesc *fd) { return ct; } -void SSLInt_PrintTls13CipherSpecs(PRFileDesc *fd) { +void SSLInt_PrintCipherSpecs(const char *label, PRFileDesc *fd) { PRCList *cur_p; sslSocket *ss = ssl_FindSocket(fd); @@ -100,27 +100,31 @@ void SSLInt_PrintTls13CipherSpecs(PRFileDesc *fd) { return; } - fprintf(stderr, "Cipher specs\n"); + fprintf(stderr, "Cipher specs for %s\n", label); for (cur_p = PR_NEXT_LINK(&ss->ssl3.hs.cipherSpecs); cur_p != &ss->ssl3.hs.cipherSpecs; cur_p = PR_NEXT_LINK(cur_p)) { ssl3CipherSpec *spec = (ssl3CipherSpec *)cur_p; - fprintf(stderr, " %s\n", spec->phase); + fprintf(stderr, " %s spec epoch=%d (%s) refct=%d\n", SPEC_DIR(spec), + spec->epoch, spec->phase, spec->refCt); } } -/* Force a timer expiry by backdating when the timer was started. - * We could set the remaining time to 0 but then backoff would not - * work properly if we decide to test it. */ -void SSLInt_ForceTimerExpiry(PRFileDesc *fd) { +/* Force a timer expiry by backdating when all active timers were started. We + * could set the remaining time to 0 but then backoff would not work properly if + * we decide to test it. */ +SECStatus SSLInt_ShiftDtlsTimers(PRFileDesc *fd, PRIntervalTime shift) { + size_t i; sslSocket *ss = ssl_FindSocket(fd); if (!ss) { - return; + return SECFailure; } - if (!ss->ssl3.hs.rtTimerCb) return; - - ss->ssl3.hs.rtTimerStarted = - PR_IntervalNow() - PR_MillisecondsToInterval(ss->ssl3.hs.rtTimeoutMs + 1); + for (i = 0; i < PR_ARRAY_SIZE(ss->ssl3.hs.timers); ++i) { + if (ss->ssl3.hs.timers[i].cb) { + ss->ssl3.hs.timers[i].started -= shift; + } + } + return SECSuccess; } #define CHECK_SECRET(secret) \ @@ -136,7 +140,6 @@ PRBool SSLInt_CheckSecretsDestroyed(PRFileDesc *fd) { } CHECK_SECRET(currentSecret); - CHECK_SECRET(resumptionMasterSecret); CHECK_SECRET(dheSecret); CHECK_SECRET(clientEarlyTrafficSecret); CHECK_SECRET(clientHsTrafficSecret); @@ -226,28 +229,7 @@ PRBool SSLInt_SendAlert(PRFileDesc *fd, uint8_t level, uint8_t type) { return PR_TRUE; } -PRBool SSLInt_SendNewSessionTicket(PRFileDesc *fd) { - sslSocket *ss = ssl_FindSocket(fd); - if (!ss) { - return PR_FALSE; - } - - ssl_GetSSL3HandshakeLock(ss); - ssl_GetXmitBufLock(ss); - - SECStatus rv = tls13_SendNewSessionTicket(ss); - if (rv == SECSuccess) { - rv = ssl3_FlushHandshake(ss, 0); - } - - ssl_ReleaseXmitBufLock(ss); - ssl_ReleaseSSL3HandshakeLock(ss); - - return rv == SECSuccess; -} - SECStatus SSLInt_AdvanceReadSeqNum(PRFileDesc *fd, PRUint64 to) { - PRUint64 epoch; sslSocket *ss; ssl3CipherSpec *spec; @@ -255,43 +237,40 @@ SECStatus SSLInt_AdvanceReadSeqNum(PRFileDesc *fd, PRUint64 to) { if (!ss) { return SECFailure; } - if (to >= (1ULL << 48)) { + if (to >= RECORD_SEQ_MAX) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } ssl_GetSpecWriteLock(ss); spec = ss->ssl3.crSpec; - epoch = spec->read_seq_num >> 48; - spec->read_seq_num = (epoch << 48) | to; + spec->seqNum = 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 (to <= spec->recvdRecords.right + DTLS_RECVD_RECORDS_WINDOW) { + if (spec->seqNum <= spec->recvdRecords.right + DTLS_RECVD_RECORDS_WINDOW) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } - dtls_RecordSetRecvd(&spec->recvdRecords, to); + dtls_RecordSetRecvd(&spec->recvdRecords, spec->seqNum); ssl_ReleaseSpecWriteLock(ss); return SECSuccess; } SECStatus SSLInt_AdvanceWriteSeqNum(PRFileDesc *fd, PRUint64 to) { - PRUint64 epoch; sslSocket *ss; ss = ssl_FindSocket(fd); if (!ss) { return SECFailure; } - if (to >= (1ULL << 48)) { + if (to >= RECORD_SEQ_MAX) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } ssl_GetSpecWriteLock(ss); - epoch = ss->ssl3.cwSpec->write_seq_num >> 48; - ss->ssl3.cwSpec->write_seq_num = (epoch << 48) | to; + ss->ssl3.cwSpec->seqNum = to; ssl_ReleaseSpecWriteLock(ss); return SECSuccess; } @@ -305,9 +284,9 @@ SECStatus SSLInt_AdvanceWriteSeqByAWindow(PRFileDesc *fd, PRInt32 extra) { return SECFailure; } ssl_GetSpecReadLock(ss); - to = ss->ssl3.cwSpec->write_seq_num + DTLS_RECVD_RECORDS_WINDOW + extra; + to = ss->ssl3.cwSpec->seqNum + DTLS_RECVD_RECORDS_WINDOW + extra; ssl_ReleaseSpecReadLock(ss); - return SSLInt_AdvanceWriteSeqNum(fd, to & RECORD_SEQ_MAX); + return SSLInt_AdvanceWriteSeqNum(fd, to); } SSLKEAType SSLInt_GetKEAType(SSLNamedGroup group) { @@ -333,56 +312,26 @@ SECStatus SSLInt_SetCipherSpecChangeFunc(PRFileDesc *fd, return SECSuccess; } -static ssl3KeyMaterial *GetKeyingMaterial(PRBool isServer, - ssl3CipherSpec *spec) { - return isServer ? &spec->server : &spec->client; +PK11SymKey *SSLInt_CipherSpecToKey(const ssl3CipherSpec *spec) { + return spec->keyMaterial.key; } -PK11SymKey *SSLInt_CipherSpecToKey(PRBool isServer, ssl3CipherSpec *spec) { - return GetKeyingMaterial(isServer, spec)->write_key; +SSLCipherAlgorithm SSLInt_CipherSpecToAlgorithm(const ssl3CipherSpec *spec) { + return spec->cipherDef->calg; } -SSLCipherAlgorithm SSLInt_CipherSpecToAlgorithm(PRBool isServer, - ssl3CipherSpec *spec) { - return spec->cipher_def->calg; +const PRUint8 *SSLInt_CipherSpecToIv(const ssl3CipherSpec *spec) { + return spec->keyMaterial.iv; } -unsigned char *SSLInt_CipherSpecToIv(PRBool isServer, ssl3CipherSpec *spec) { - return GetKeyingMaterial(isServer, spec)->write_iv; -} - -SECStatus SSLInt_EnableShortHeaders(PRFileDesc *fd) { - sslSocket *ss; - - ss = ssl_FindSocket(fd); - if (!ss) { - return SECFailure; - } - - ss->opt.enableShortHeaders = PR_TRUE; - return SECSuccess; -} - -SECStatus SSLInt_UsingShortHeaders(PRFileDesc *fd, PRBool *result) { - sslSocket *ss; - - ss = ssl_FindSocket(fd); - if (!ss) { - return SECFailure; - } - - *result = ss->ssl3.hs.shortHeaders; - return SECSuccess; +PRUint16 SSLInt_CipherSpecToEpoch(const ssl3CipherSpec *spec) { + return spec->epoch; } void SSLInt_SetTicketLifetime(uint32_t lifetime) { ssl_ticket_lifetime = lifetime; } -void SSLInt_SetMaxEarlyDataSize(uint32_t size) { - ssl_max_early_data_size = size; -} - SECStatus SSLInt_SetSocketMaxEarlyDataSize(PRFileDesc *fd, uint32_t size) { sslSocket *ss; @@ -405,3 +354,21 @@ SECStatus SSLInt_SetSocketMaxEarlyDataSize(PRFileDesc *fd, uint32_t size) { return SECSuccess; } + +void SSLInt_RolloverAntiReplay(void) { + tls13_AntiReplayRollover(ssl_TimeUsec()); +} + +SECStatus SSLInt_GetEpochs(PRFileDesc *fd, PRUint16 *readEpoch, + PRUint16 *writeEpoch) { + sslSocket *ss = ssl_FindSocket(fd); + if (!ss || !readEpoch || !writeEpoch) { + return SECFailure; + } + + ssl_GetSpecReadLock(ss); + *readEpoch = ss->ssl3.crSpec->epoch; + *writeEpoch = ss->ssl3.cwSpec->epoch; + ssl_ReleaseSpecReadLock(ss); + return SECSuccess; +} diff --git a/security/nss/gtests/ssl_gtest/libssl_internals.h b/security/nss/gtests/ssl_gtest/libssl_internals.h index 33709c4b4..3efb362c2 100644 --- a/security/nss/gtests/ssl_gtest/libssl_internals.h +++ b/security/nss/gtests/ssl_gtest/libssl_internals.h @@ -24,9 +24,9 @@ SECStatus SSLInt_UpdateSSLv2ClientRandom(PRFileDesc *fd, uint8_t *rnd, PRBool SSLInt_ExtensionNegotiated(PRFileDesc *fd, PRUint16 ext); void SSLInt_ClearSelfEncryptKey(); void SSLInt_SetSelfEncryptMacKey(PK11SymKey *key); -PRInt32 SSLInt_CountTls13CipherSpecs(PRFileDesc *fd); -void SSLInt_PrintTls13CipherSpecs(PRFileDesc *fd); -void SSLInt_ForceTimerExpiry(PRFileDesc *fd); +PRInt32 SSLInt_CountCipherSpecs(PRFileDesc *fd); +void SSLInt_PrintCipherSpecs(const char *label, PRFileDesc *fd); +SECStatus SSLInt_ShiftDtlsTimers(PRFileDesc *fd, PRIntervalTime shift); SECStatus SSLInt_SetMTU(PRFileDesc *fd, PRUint16 mtu); PRBool SSLInt_CheckSecretsDestroyed(PRFileDesc *fd); PRBool SSLInt_DamageClientHsTrafficSecret(PRFileDesc *fd); @@ -35,23 +35,22 @@ PRBool SSLInt_DamageEarlyTrafficSecret(PRFileDesc *fd); SECStatus SSLInt_Set0RttAlpn(PRFileDesc *fd, PRUint8 *data, unsigned int len); PRBool SSLInt_HasCertWithAuthType(PRFileDesc *fd, SSLAuthType authType); PRBool SSLInt_SendAlert(PRFileDesc *fd, uint8_t level, uint8_t type); -PRBool SSLInt_SendNewSessionTicket(PRFileDesc *fd); SECStatus SSLInt_AdvanceWriteSeqNum(PRFileDesc *fd, PRUint64 to); SECStatus SSLInt_AdvanceReadSeqNum(PRFileDesc *fd, PRUint64 to); SECStatus SSLInt_AdvanceWriteSeqByAWindow(PRFileDesc *fd, PRInt32 extra); SSLKEAType SSLInt_GetKEAType(SSLNamedGroup group); +SECStatus SSLInt_GetEpochs(PRFileDesc *fd, PRUint16 *readEpoch, + PRUint16 *writeEpoch); SECStatus SSLInt_SetCipherSpecChangeFunc(PRFileDesc *fd, sslCipherSpecChangedFunc func, void *arg); -PK11SymKey *SSLInt_CipherSpecToKey(PRBool isServer, ssl3CipherSpec *spec); -SSLCipherAlgorithm SSLInt_CipherSpecToAlgorithm(PRBool isServer, - ssl3CipherSpec *spec); -unsigned char *SSLInt_CipherSpecToIv(PRBool isServer, ssl3CipherSpec *spec); -SECStatus SSLInt_EnableShortHeaders(PRFileDesc *fd); -SECStatus SSLInt_UsingShortHeaders(PRFileDesc *fd, PRBool *result); +PRUint16 SSLInt_CipherSpecToEpoch(const ssl3CipherSpec *spec); +PK11SymKey *SSLInt_CipherSpecToKey(const ssl3CipherSpec *spec); +SSLCipherAlgorithm SSLInt_CipherSpecToAlgorithm(const ssl3CipherSpec *spec); +const PRUint8 *SSLInt_CipherSpecToIv(const ssl3CipherSpec *spec); void SSLInt_SetTicketLifetime(uint32_t lifetime); -void SSLInt_SetMaxEarlyDataSize(uint32_t size); SECStatus SSLInt_SetSocketMaxEarlyDataSize(PRFileDesc *fd, uint32_t size); +void SSLInt_RolloverAntiReplay(void); #endif // ndef libssl_internals_h_ diff --git a/security/nss/gtests/ssl_gtest/manifest.mn b/security/nss/gtests/ssl_gtest/manifest.mn index cc729c0f1..5d893bab3 100644 --- a/security/nss/gtests/ssl_gtest/manifest.mn +++ b/security/nss/gtests/ssl_gtest/manifest.mn @@ -12,11 +12,13 @@ CSRCS = \ $(NULL) CPPSRCS = \ + bloomfilter_unittest.cc \ ssl_0rtt_unittest.cc \ ssl_agent_unittest.cc \ ssl_auth_unittest.cc \ ssl_cert_ext_unittest.cc \ ssl_ciphersuite_unittest.cc \ + ssl_custext_unittest.cc \ ssl_damage_unittest.cc \ ssl_dhe_unittest.cc \ ssl_drop_unittest.cc \ @@ -29,11 +31,16 @@ CPPSRCS = \ ssl_gather_unittest.cc \ ssl_gtest.cc \ ssl_hrr_unittest.cc \ + ssl_keylog_unittest.cc \ + ssl_keyupdate_unittest.cc \ ssl_loopback_unittest.cc \ + ssl_misc_unittest.cc \ ssl_record_unittest.cc \ ssl_resumption_unittest.cc \ + ssl_renegotiation_unittest.cc \ ssl_skip_unittest.cc \ ssl_staticrsa_unittest.cc \ + ssl_tls13compat_unittest.cc \ ssl_v2_client_hello_unittest.cc \ ssl_version_unittest.cc \ ssl_versionpolicy_unittest.cc \ diff --git a/security/nss/gtests/ssl_gtest/ssl_0rtt_unittest.cc b/security/nss/gtests/ssl_gtest/ssl_0rtt_unittest.cc index 85b7011a1..08781af71 100644 --- a/security/nss/gtests/ssl_gtest/ssl_0rtt_unittest.cc +++ b/security/nss/gtests/ssl_gtest/ssl_0rtt_unittest.cc @@ -7,6 +7,7 @@ #include "secerr.h" #include "ssl.h" #include "sslerr.h" +#include "sslexp.h" #include "sslproto.h" extern "C" { @@ -44,6 +45,92 @@ TEST_P(TlsConnectTls13, ZeroRttServerRejectByOption) { SendReceive(); } +TEST_P(TlsConnectTls13, ZeroRttApparentReplayAfterRestart) { + // The test fixtures call SSL_SetupAntiReplay() in SetUp(). This results in + // 0-RTT being rejected until at least one window passes. SetupFor0Rtt() + // forces a rollover of the anti-replay filters, which clears this state. + // Here, we do the setup manually here without that forced rollover. + + ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET); + ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3); + server_->Set0RttEnabled(true); // So we signal that we allow 0-RTT. + Connect(); + SendReceive(); // Need to read so that we absorb the session ticket. + CheckKeys(); + + Reset(); + StartConnect(); + client_->Set0RttEnabled(true); + server_->Set0RttEnabled(true); + ExpectResumption(RESUME_TICKET); + ZeroRttSendReceive(true, false); + Handshake(); + CheckConnected(); + SendReceive(); +} + +class TlsZeroRttReplayTest : public TlsConnectTls13 { + private: + class SaveFirstPacket : public PacketFilter { + public: + PacketFilter::Action Filter(const DataBuffer& input, + DataBuffer* output) override { + if (!packet_.len() && input.len()) { + packet_ = input; + } + return KEEP; + } + + const DataBuffer& packet() const { return packet_; } + + private: + DataBuffer packet_; + }; + + protected: + void RunTest(bool rollover) { + // Run the initial handshake + SetupForZeroRtt(); + + // Now run a true 0-RTT handshake, but capture the first packet. + auto first_packet = std::make_shared<SaveFirstPacket>(); + client_->SetFilter(first_packet); + client_->Set0RttEnabled(true); + server_->Set0RttEnabled(true); + ExpectResumption(RESUME_TICKET); + ZeroRttSendReceive(true, true); + Handshake(); + EXPECT_LT(0U, first_packet->packet().len()); + ExpectEarlyDataAccepted(true); + CheckConnected(); + SendReceive(); + + if (rollover) { + SSLInt_RolloverAntiReplay(); + } + + // Now replay that packet against the server. + Reset(); + server_->StartConnect(); + server_->Set0RttEnabled(true); + + // Capture the early_data extension, which should not appear. + auto early_data_ext = + MakeTlsFilter<TlsExtensionCapture>(server_, ssl_tls13_early_data_xtn); + + // Finally, replay the ClientHello and force the server to consume it. Stop + // after the server sends its first flight; the client will not be able to + // complete this handshake. + server_->adapter()->PacketReceived(first_packet->packet()); + server_->Handshake(); + EXPECT_FALSE(early_data_ext->captured()); + } +}; + +TEST_P(TlsZeroRttReplayTest, ZeroRttReplay) { RunTest(false); } + +TEST_P(TlsZeroRttReplayTest, ZeroRttReplayAfterRollover) { RunTest(true); } + // Test that we don't try to send 0-RTT data when the server sent // us a ticket without the 0-RTT flags. TEST_P(TlsConnectTls13, ZeroRttOptionsSetLate) { @@ -52,8 +139,7 @@ TEST_P(TlsConnectTls13, ZeroRttOptionsSetLate) { SendReceive(); // Need to read so that we absorb the session ticket. CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign); Reset(); - server_->StartConnect(); - client_->StartConnect(); + StartConnect(); // Now turn on 0-RTT but too late for the ticket. client_->Set0RttEnabled(true); server_->Set0RttEnabled(true); @@ -80,8 +166,7 @@ TEST_P(TlsConnectTls13, ZeroRttServerForgetTicket) { TEST_P(TlsConnectTls13, ZeroRttServerOnly) { ExpectResumption(RESUME_NONE); server_->Set0RttEnabled(true); - client_->StartConnect(); - server_->StartConnect(); + StartConnect(); // Client sends ordinary ClientHello. client_->Handshake(); @@ -99,6 +184,61 @@ TEST_P(TlsConnectTls13, ZeroRttServerOnly) { CheckKeys(); } +// A small sleep after sending the ClientHello means that the ticket age that +// arrives at the server is too low. With a small tolerance for variation in +// ticket age (which is determined by the |window| parameter that is passed to +// SSL_SetupAntiReplay()), the server then rejects early data. +TEST_P(TlsConnectTls13, ZeroRttRejectOldTicket) { + SetupForZeroRtt(); + client_->Set0RttEnabled(true); + server_->Set0RttEnabled(true); + EXPECT_EQ(SECSuccess, SSL_SetupAntiReplay(1, 1, 3)); + SSLInt_RolloverAntiReplay(); // Make sure to flush replay state. + SSLInt_RolloverAntiReplay(); + ExpectResumption(RESUME_TICKET); + ZeroRttSendReceive(true, false, []() { + PR_Sleep(PR_MillisecondsToInterval(10)); + return true; + }); + Handshake(); + ExpectEarlyDataAccepted(false); + CheckConnected(); + SendReceive(); +} + +// In this test, we falsely inflate the estimate of the RTT by delaying the +// ServerHello on the first handshake. This results in the server estimating a +// higher value of the ticket age than the client ultimately provides. Add a +// small tolerance for variation in ticket age and the ticket will appear to +// arrive prematurely, causing the server to reject early data. +TEST_P(TlsConnectTls13, ZeroRttRejectPrematureTicket) { + ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET); + ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3); + server_->Set0RttEnabled(true); + StartConnect(); + client_->Handshake(); // ClientHello + server_->Handshake(); // ServerHello + PR_Sleep(PR_MillisecondsToInterval(10)); + Handshake(); // Remainder of handshake + CheckConnected(); + SendReceive(); + CheckKeys(); + + Reset(); + client_->Set0RttEnabled(true); + server_->Set0RttEnabled(true); + EXPECT_EQ(SECSuccess, SSL_SetupAntiReplay(1, 1, 3)); + SSLInt_RolloverAntiReplay(); // Make sure to flush replay state. + SSLInt_RolloverAntiReplay(); + ExpectResumption(RESUME_TICKET); + ExpectEarlyDataAccepted(false); + StartConnect(); + ZeroRttSendReceive(true, false); + Handshake(); + CheckConnected(); + SendReceive(); +} + TEST_P(TlsConnectTls13, TestTls13ZeroRttAlpn) { EnableAlpn(); SetupForZeroRtt(); @@ -117,6 +257,14 @@ TEST_P(TlsConnectTls13, TestTls13ZeroRttAlpn) { CheckAlpn("a"); } +// NOTE: In this test and those below, the client always sends +// post-ServerHello alerts with the handshake keys, even if the server +// has accepted 0-RTT. In some cases, as with errors in +// EncryptedExtensions, the client can't know the server's behavior, +// and in others it's just simpler. What the server is expecting +// depends on whether it accepted 0-RTT or not. Eventually, we may +// make the server trial decrypt. +// // Have the server negotiate a different ALPN value, and therefore // reject 0-RTT. TEST_P(TlsConnectTls13, TestTls13ZeroRttAlpnChangeServer) { @@ -155,12 +303,17 @@ TEST_P(TlsConnectTls13, TestTls13ZeroRttNoAlpnServer) { client_->CheckAlpn(SSL_NEXT_PROTO_EARLY_VALUE, "a"); EXPECT_EQ(SECSuccess, SSLInt_Set0RttAlpn(client_->ssl_fd(), b, sizeof(b))); client_->CheckAlpn(SSL_NEXT_PROTO_EARLY_VALUE, "b"); - ExpectAlert(client_, kTlsAlertIllegalParameter); + client_->ExpectSendAlert(kTlsAlertIllegalParameter); return true; }); - Handshake(); + if (variant_ == ssl_variant_stream) { + server_->ExpectSendAlert(kTlsAlertBadRecordMac); + Handshake(); + server_->CheckErrorCode(SSL_ERROR_BAD_MAC_READ); + } else { + client_->Handshake(); + } client_->CheckErrorCode(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID); - server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT); } // Set up with no ALPN and then set the client so it thinks it has ALPN. @@ -175,12 +328,17 @@ TEST_P(TlsConnectTls13, TestTls13ZeroRttNoAlpnClient) { PRUint8 b[] = {'b'}; EXPECT_EQ(SECSuccess, SSLInt_Set0RttAlpn(client_->ssl_fd(), b, 1)); client_->CheckAlpn(SSL_NEXT_PROTO_EARLY_VALUE, "b"); - ExpectAlert(client_, kTlsAlertIllegalParameter); + client_->ExpectSendAlert(kTlsAlertIllegalParameter); return true; }); - Handshake(); + if (variant_ == ssl_variant_stream) { + server_->ExpectSendAlert(kTlsAlertBadRecordMac); + Handshake(); + server_->CheckErrorCode(SSL_ERROR_BAD_MAC_READ); + } else { + client_->Handshake(); + } client_->CheckErrorCode(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID); - server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT); } // Remove the old ALPN value and so the client will not offer early data. @@ -218,9 +376,7 @@ TEST_P(TlsConnectTls13, TestTls13ZeroRttDowngrade) { SSL_LIBRARY_VERSION_TLS_1_3); server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2, SSL_LIBRARY_VERSION_TLS_1_2); - client_->StartConnect(); - server_->StartConnect(); - + StartConnect(); // We will send the early data xtn without sending actual early data. Thus // a 1.2 server shouldn't fail until the client sends an alert because the // client sends end_of_early_data only after reading the server's flight. @@ -248,6 +404,9 @@ TEST_P(TlsConnectTls13, TestTls13ZeroRttDowngrade) { // The client should abort the connection when sending a 0-rtt handshake but // the servers responds with a TLS 1.2 ServerHello. (with app data) TEST_P(TlsConnectTls13, TestTls13ZeroRttDowngradeEarlyData) { + const char* k0RttData = "ABCDEF"; + const PRInt32 k0RttDataLen = static_cast<PRInt32>(strlen(k0RttData)); + ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET); server_->Set0RttEnabled(true); // set ticket_allow_early_data Connect(); @@ -261,33 +420,32 @@ TEST_P(TlsConnectTls13, TestTls13ZeroRttDowngradeEarlyData) { SSL_LIBRARY_VERSION_TLS_1_3); server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2, SSL_LIBRARY_VERSION_TLS_1_2); - client_->StartConnect(); - server_->StartConnect(); - + StartConnect(); // Send the early data xtn in the CH, followed by early app data. The server // will fail right after sending its flight, when receiving the early data. client_->Set0RttEnabled(true); - ZeroRttSendReceive(true, false, [this]() { - client_->ExpectSendAlert(kTlsAlertIllegalParameter); - if (variant_ == ssl_variant_stream) { - server_->ExpectSendAlert(kTlsAlertUnexpectedMessage); - } - return true; - }); - - client_->Handshake(); - server_->Handshake(); - ASSERT_TRUE_WAIT( - (client_->error_code() == SSL_ERROR_DOWNGRADE_WITH_EARLY_DATA), 2000); + client_->Handshake(); // Send ClientHello. + PRInt32 rv = + PR_Write(client_->ssl_fd(), k0RttData, k0RttDataLen); // 0-RTT write. + EXPECT_EQ(k0RttDataLen, rv); - // DTLS will timeout as we bump the epoch when installing the early app data - // cipher suite. Thus the encrypted alert will be ignored. if (variant_ == ssl_variant_stream) { - // The server sends an alert when receiving the early app data record. - ASSERT_TRUE_WAIT( - (server_->error_code() == SSL_ERROR_RX_UNEXPECTED_APPLICATION_DATA), - 2000); + // When the server receives the early data, it will fail. + server_->ExpectSendAlert(kTlsAlertUnexpectedMessage); + server_->Handshake(); // Consume ClientHello + EXPECT_EQ(TlsAgent::STATE_ERROR, server_->state()); + server_->CheckErrorCode(SSL_ERROR_RX_UNEXPECTED_APPLICATION_DATA); + } else { + // If it's datagram, we just discard the early data. + server_->Handshake(); // Consume ClientHello + EXPECT_EQ(TlsAgent::STATE_CONNECTING, server_->state()); } + + // The client now reads the ServerHello and fails. + ASSERT_EQ(TlsAgent::STATE_CONNECTING, client_->state()); + client_->ExpectSendAlert(kTlsAlertIllegalParameter); + client_->Handshake(); + client_->CheckErrorCode(SSL_ERROR_DOWNGRADE_WITH_EARLY_DATA); } static void CheckEarlyDataLimit(const std::shared_ptr<TlsAgent>& agent, @@ -300,17 +458,19 @@ static void CheckEarlyDataLimit(const std::shared_ptr<TlsAgent>& agent, } TEST_P(TlsConnectTls13, SendTooMuchEarlyData) { + EnsureTlsSetup(); const char* big_message = "0123456789abcdef"; const size_t short_size = strlen(big_message) - 1; const PRInt32 short_length = static_cast<PRInt32>(short_size); - SSLInt_SetMaxEarlyDataSize(static_cast<PRUint32>(short_size)); + EXPECT_EQ(SECSuccess, + SSL_SetMaxEarlyDataSize(server_->ssl_fd(), + static_cast<PRUint32>(short_size))); SetupForZeroRtt(); client_->Set0RttEnabled(true); server_->Set0RttEnabled(true); ExpectResumption(RESUME_TICKET); - ExpectAlert(client_, kTlsAlertEndOfEarlyData); client_->Handshake(); CheckEarlyDataLimit(client_, short_size); @@ -356,18 +516,21 @@ TEST_P(TlsConnectTls13, SendTooMuchEarlyData) { } TEST_P(TlsConnectTls13, ReceiveTooMuchEarlyData) { + EnsureTlsSetup(); + const size_t limit = 5; - SSLInt_SetMaxEarlyDataSize(limit); + EXPECT_EQ(SECSuccess, SSL_SetMaxEarlyDataSize(server_->ssl_fd(), limit)); SetupForZeroRtt(); client_->Set0RttEnabled(true); server_->Set0RttEnabled(true); ExpectResumption(RESUME_TICKET); - client_->ExpectSendAlert(kTlsAlertEndOfEarlyData); client_->Handshake(); // Send ClientHello CheckEarlyDataLimit(client_, limit); + server_->Handshake(); // Process ClientHello, send server flight. + // Lift the limit on the client. EXPECT_EQ(SECSuccess, SSLInt_SetSocketMaxEarlyDataSize(client_->ssl_fd(), 1000)); @@ -381,22 +544,114 @@ TEST_P(TlsConnectTls13, ReceiveTooMuchEarlyData) { // This error isn't fatal for DTLS. ExpectAlert(server_, kTlsAlertUnexpectedMessage); } - server_->Handshake(); // Process ClientHello, send server flight. - server_->Handshake(); // Just to make sure that we don't read ahead. + + server_->Handshake(); // This reads the early data and maybe throws an error. + if (variant_ == ssl_variant_stream) { + server_->CheckErrorCode(SSL_ERROR_TOO_MUCH_EARLY_DATA); + } else { + EXPECT_EQ(TlsAgent::STATE_CONNECTING, server_->state()); + } CheckEarlyDataLimit(server_, limit); - // Attempt to read early data. + // Attempt to read early data. This will get an error. std::vector<uint8_t> buf(strlen(message) + 1); EXPECT_GT(0, PR_Read(server_->ssl_fd(), buf.data(), buf.capacity())); if (variant_ == ssl_variant_stream) { - server_->CheckErrorCode(SSL_ERROR_TOO_MUCH_EARLY_DATA); + EXPECT_EQ(SSL_ERROR_HANDSHAKE_FAILED, PORT_GetError()); + } else { + EXPECT_EQ(PR_WOULD_BLOCK_ERROR, PORT_GetError()); } - client_->Handshake(); // Process the handshake. - client_->Handshake(); // Process the alert. + client_->Handshake(); // Process the server's first flight. if (variant_ == ssl_variant_stream) { + client_->Handshake(); // Process the alert. client_->CheckErrorCode(SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT); + } else { + server_->Handshake(); // Finish connecting. + EXPECT_EQ(TlsAgent::STATE_CONNECTED, server_->state()); } } +class PacketCoalesceFilter : public PacketFilter { + public: + PacketCoalesceFilter() : packet_data_() {} + + void SendCoalesced(std::shared_ptr<TlsAgent> agent) { + agent->SendDirect(packet_data_); + } + + protected: + PacketFilter::Action Filter(const DataBuffer& input, + DataBuffer* output) override { + packet_data_.Write(packet_data_.len(), input); + return DROP; + } + + private: + DataBuffer packet_data_; +}; + +TEST_P(TlsConnectTls13, ZeroRttOrdering) { + SetupForZeroRtt(); + client_->Set0RttEnabled(true); + server_->Set0RttEnabled(true); + ExpectResumption(RESUME_TICKET); + + // Send out the ClientHello. + client_->Handshake(); + + // Now, coalesce the next three things from the client: early data, second + // flight and 1-RTT data. + auto coalesce = std::make_shared<PacketCoalesceFilter>(); + client_->SetFilter(coalesce); + + // Send (and hold) early data. + static const std::vector<uint8_t> early_data = {3, 2, 1}; + EXPECT_EQ(static_cast<PRInt32>(early_data.size()), + PR_Write(client_->ssl_fd(), early_data.data(), early_data.size())); + + // Send (and hold) the second client handshake flight. + // The client sends EndOfEarlyData after seeing the server Finished. + server_->Handshake(); + client_->Handshake(); + + // Send (and hold) 1-RTT data. + static const std::vector<uint8_t> late_data = {7, 8, 9, 10}; + EXPECT_EQ(static_cast<PRInt32>(late_data.size()), + PR_Write(client_->ssl_fd(), late_data.data(), late_data.size())); + + // Now release them all at once. + coalesce->SendCoalesced(client_); + + // Now ensure that the three steps are exposed in the right order on the + // server: delivery of early data, handshake callback, delivery of 1-RTT. + size_t step = 0; + server_->SetHandshakeCallback([&step](TlsAgent*) { + EXPECT_EQ(1U, step); + ++step; + }); + + std::vector<uint8_t> buf(10); + PRInt32 read = PR_Read(server_->ssl_fd(), buf.data(), buf.size()); + ASSERT_EQ(static_cast<PRInt32>(early_data.size()), read); + buf.resize(read); + EXPECT_EQ(early_data, buf); + EXPECT_EQ(0U, step); + ++step; + + // The third read should be after the handshake callback and should return the + // data that was sent after the handshake completed. + buf.resize(10); + read = PR_Read(server_->ssl_fd(), buf.data(), buf.size()); + ASSERT_EQ(static_cast<PRInt32>(late_data.size()), read); + buf.resize(read); + EXPECT_EQ(late_data, buf); + EXPECT_EQ(2U, step); +} + +#ifndef NSS_DISABLE_TLS_1_3 +INSTANTIATE_TEST_CASE_P(Tls13ZeroRttReplayTest, TlsZeroRttReplayTest, + TlsConnectTestBase::kTlsVariantsAll); +#endif + } // namespace nss_test diff --git a/security/nss/gtests/ssl_gtest/ssl_agent_unittest.cc b/security/nss/gtests/ssl_gtest/ssl_agent_unittest.cc index 5035a338d..f0c57e8b1 100644 --- a/security/nss/gtests/ssl_gtest/ssl_agent_unittest.cc +++ b/security/nss/gtests/ssl_gtest/ssl_agent_unittest.cc @@ -31,7 +31,7 @@ const static uint8_t kCannedTls13ClientHello[] = { 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x09, 0x00, 0x00, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x12, 0x00, 0x10, 0x00, 0x17, 0x00, 0x18, 0x00, 0x19, 0x01, - 0x00, 0x01, 0x01, 0x01, 0x02, 0x01, 0x03, 0x01, 0x04, 0x00, 0x28, 0x00, + 0x00, 0x01, 0x01, 0x01, 0x02, 0x01, 0x03, 0x01, 0x04, 0x00, 0x33, 0x00, 0x47, 0x00, 0x45, 0x00, 0x17, 0x00, 0x41, 0x04, 0x86, 0x4a, 0xb9, 0xdc, 0x6a, 0x38, 0xa7, 0xce, 0xe7, 0xc2, 0x4f, 0xa6, 0x28, 0xb9, 0xdc, 0x65, 0xbf, 0x73, 0x47, 0x3c, 0x9c, 0x65, 0x8c, 0x47, 0x6d, 0x57, 0x22, 0x8a, @@ -44,13 +44,14 @@ const static uint8_t kCannedTls13ClientHello[] = { 0x02, 0x05, 0x02, 0x06, 0x02, 0x02, 0x02}; const static uint8_t kCannedTls13ServerHello[] = { - 0x7f, kD13, 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, 0x13, 0x01, - 0x00, 0x28, 0x00, 0x28, 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}; + 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 char *k0RttData = "ABCDEF"; TEST_P(TlsAgentTest, EarlyFinished) { @@ -159,9 +160,8 @@ TEST_F(TlsAgentStreamTestClient, Set0RttOptionThenWrite) { SSL_LIBRARY_VERSION_TLS_1_3); agent_->StartConnect(); agent_->Set0RttEnabled(true); - auto filter = std::make_shared<TlsInspectorRecordHandshakeMessage>( - kTlsHandshakeClientHello); - agent_->SetPacketFilter(filter); + auto filter = + MakeTlsFilter<TlsHandshakeRecorder>(agent_, kTlsHandshakeClientHello); PRInt32 rv = PR_Write(agent_->ssl_fd(), k0RttData, strlen(k0RttData)); EXPECT_EQ(-1, rv); int32_t err = PORT_GetError(); diff --git a/security/nss/gtests/ssl_gtest/ssl_auth_unittest.cc b/security/nss/gtests/ssl_gtest/ssl_auth_unittest.cc index dbcbc9aa3..7f2b2840d 100644 --- a/security/nss/gtests/ssl_gtest/ssl_auth_unittest.cc +++ b/security/nss/gtests/ssl_gtest/ssl_auth_unittest.cc @@ -29,7 +29,25 @@ TEST_P(TlsConnectGeneric, ServerAuthBigRsa) { } TEST_P(TlsConnectGeneric, ServerAuthRsaChain) { - Reset(TlsAgent::kServerRsaChain); + Reset("rsa_chain"); + Connect(); + CheckKeys(); + size_t chain_length; + EXPECT_TRUE(client_->GetPeerChainLength(&chain_length)); + EXPECT_EQ(2UL, chain_length); +} + +TEST_P(TlsConnectGeneric, ServerAuthRsaPssChain) { + Reset("rsa_pss_chain"); + Connect(); + CheckKeys(); + size_t chain_length; + EXPECT_TRUE(client_->GetPeerChainLength(&chain_length)); + EXPECT_EQ(2UL, chain_length); +} + +TEST_P(TlsConnectGeneric, ServerAuthRsaCARsaPssChain) { + Reset("rsa_ca_rsa_pss_chain"); Connect(); CheckKeys(); size_t chain_length; @@ -77,10 +95,9 @@ TEST_P(TlsConnectGeneric, ClientAuthBigRsa) { } // Offset is the position in the captured buffer where the signature sits. -static void CheckSigScheme( - std::shared_ptr<TlsInspectorRecordHandshakeMessage>& capture, size_t offset, - std::shared_ptr<TlsAgent>& peer, uint16_t expected_scheme, - size_t expected_size) { +static void CheckSigScheme(std::shared_ptr<TlsHandshakeRecorder>& capture, + size_t offset, std::shared_ptr<TlsAgent>& peer, + uint16_t expected_scheme, size_t expected_size) { EXPECT_LT(offset + 2U, capture->buffer().len()); uint32_t scheme = 0; @@ -96,9 +113,8 @@ static void CheckSigScheme( // in the default certificate. TEST_P(TlsConnectTls12, ServerAuthCheckSigAlg) { EnsureTlsSetup(); - auto capture_ske = std::make_shared<TlsInspectorRecordHandshakeMessage>( - kTlsHandshakeServerKeyExchange); - server_->SetPacketFilter(capture_ske); + auto capture_ske = MakeTlsFilter<TlsHandshakeRecorder>( + server_, kTlsHandshakeServerKeyExchange); Connect(); CheckKeys(); @@ -109,15 +125,14 @@ TEST_P(TlsConnectTls12, ServerAuthCheckSigAlg) { EXPECT_TRUE(buffer.Read(1, 2, &tmp)) << "read NamedCurve"; EXPECT_EQ(ssl_grp_ec_curve25519, tmp); EXPECT_TRUE(buffer.Read(3, 1, &tmp)) << " read ECPoint"; - CheckSigScheme(capture_ske, 4 + tmp, client_, ssl_sig_rsa_pss_sha256, 1024); + CheckSigScheme(capture_ske, 4 + tmp, client_, ssl_sig_rsa_pss_rsae_sha256, + 1024); } TEST_P(TlsConnectTls12, ClientAuthCheckSigAlg) { EnsureTlsSetup(); - auto capture_cert_verify = - std::make_shared<TlsInspectorRecordHandshakeMessage>( - kTlsHandshakeCertificateVerify); - client_->SetPacketFilter(capture_cert_verify); + auto capture_cert_verify = MakeTlsFilter<TlsHandshakeRecorder>( + client_, kTlsHandshakeCertificateVerify); client_->SetupClientAuth(); server_->RequestClientAuth(true); Connect(); @@ -128,26 +143,23 @@ TEST_P(TlsConnectTls12, ClientAuthCheckSigAlg) { TEST_P(TlsConnectTls12, ClientAuthBigRsaCheckSigAlg) { Reset(TlsAgent::kServerRsa, TlsAgent::kRsa2048); - auto capture_cert_verify = - std::make_shared<TlsInspectorRecordHandshakeMessage>( - kTlsHandshakeCertificateVerify); - client_->SetPacketFilter(capture_cert_verify); + auto capture_cert_verify = MakeTlsFilter<TlsHandshakeRecorder>( + client_, kTlsHandshakeCertificateVerify); client_->SetupClientAuth(); server_->RequestClientAuth(true); Connect(); CheckKeys(); - CheckSigScheme(capture_cert_verify, 0, server_, ssl_sig_rsa_pss_sha256, 2048); + CheckSigScheme(capture_cert_verify, 0, server_, ssl_sig_rsa_pss_rsae_sha256, + 2048); } class TlsZeroCertificateRequestSigAlgsFilter : public TlsHandshakeFilter { public: + TlsZeroCertificateRequestSigAlgsFilter(const std::shared_ptr<TlsAgent>& agent) + : TlsHandshakeFilter(agent, {kTlsHandshakeCertificateRequest}) {} virtual PacketFilter::Action FilterHandshake( const TlsHandshakeFilter::HandshakeHeader& header, const DataBuffer& input, DataBuffer* output) { - if (header.handshake_type() != kTlsHandshakeCertificateRequest) { - return KEEP; - } - TlsParser parser(input); std::cerr << "Zeroing CertReq.supported_signature_algorithms" << std::endl; @@ -189,12 +201,9 @@ class TlsZeroCertificateRequestSigAlgsFilter : public TlsHandshakeFilter { // supported_signature_algorithms in the CertificateRequest message. TEST_P(TlsConnectTls12, ClientAuthNoSigAlgsFallback) { EnsureTlsSetup(); - auto filter = std::make_shared<TlsZeroCertificateRequestSigAlgsFilter>(); - server_->SetPacketFilter(filter); - auto capture_cert_verify = - std::make_shared<TlsInspectorRecordHandshakeMessage>( - kTlsHandshakeCertificateVerify); - client_->SetPacketFilter(capture_cert_verify); + MakeTlsFilter<TlsZeroCertificateRequestSigAlgsFilter>(server_); + auto capture_cert_verify = MakeTlsFilter<TlsHandshakeRecorder>( + client_, kTlsHandshakeCertificateVerify); client_->SetupClientAuth(); server_->RequestClientAuth(true); @@ -342,8 +351,7 @@ TEST_P(TlsConnectPre12, SignatureAlgorithmNoOverlapEcdsa) { // The signature_algorithms extension is mandatory in TLS 1.3. TEST_P(TlsConnectTls13, SignatureAlgorithmDrop) { - client_->SetPacketFilter( - std::make_shared<TlsExtensionDropper>(ssl_signature_algorithms_xtn)); + MakeTlsFilter<TlsExtensionDropper>(client_, ssl_signature_algorithms_xtn); ConnectExpectAlert(server_, kTlsAlertMissingExtension); client_->CheckErrorCode(SSL_ERROR_MISSING_EXTENSION_ALERT); server_->CheckErrorCode(SSL_ERROR_MISSING_SIGNATURE_ALGORITHMS_EXTENSION); @@ -352,8 +360,7 @@ TEST_P(TlsConnectTls13, SignatureAlgorithmDrop) { // TLS 1.2 has trouble detecting this sort of modification: it uses SHA1 and // only fails when the Finished is checked. TEST_P(TlsConnectTls12, SignatureAlgorithmDrop) { - client_->SetPacketFilter( - std::make_shared<TlsExtensionDropper>(ssl_signature_algorithms_xtn)); + MakeTlsFilter<TlsExtensionDropper>(client_, ssl_signature_algorithms_xtn); ConnectExpectAlert(server_, kTlsAlertDecryptError); client_->CheckErrorCode(SSL_ERROR_DECRYPT_ERROR_ALERT); server_->CheckErrorCode(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE); @@ -371,11 +378,11 @@ class BeforeFinished : public TlsRecordFilter { enum HandshakeState { BEFORE_CCS, AFTER_CCS, DONE }; public: - BeforeFinished(std::shared_ptr<TlsAgent>& client, - std::shared_ptr<TlsAgent>& server, VoidFunction before_ccs, - VoidFunction before_finished) - : client_(client), - server_(server), + BeforeFinished(const std::shared_ptr<TlsAgent>& server, + const std::shared_ptr<TlsAgent>& client, + VoidFunction before_ccs, VoidFunction before_finished) + : TlsRecordFilter(server), + client_(client), before_ccs_(before_ccs), before_finished_(before_finished), state_(BEFORE_CCS) {} @@ -395,7 +402,7 @@ class BeforeFinished : public TlsRecordFilter { // but that means that they both get processed together. DataBuffer ccs; header.Write(&ccs, 0, body); - server_.lock()->SendDirect(ccs); + agent()->SendDirect(ccs); client_.lock()->Handshake(); state_ = AFTER_CCS; // Request that the original record be dropped by the filter. @@ -420,7 +427,6 @@ class BeforeFinished : public TlsRecordFilter { private: std::weak_ptr<TlsAgent> client_; - std::weak_ptr<TlsAgent> server_; VoidFunction before_ccs_; VoidFunction before_finished_; HandshakeState state_; @@ -445,11 +451,11 @@ class BeforeFinished13 : public PacketFilter { }; public: - BeforeFinished13(std::shared_ptr<TlsAgent>& client, - std::shared_ptr<TlsAgent>& server, + BeforeFinished13(const std::shared_ptr<TlsAgent>& server, + const std::shared_ptr<TlsAgent>& client, VoidFunction before_finished) - : client_(client), - server_(server), + : server_(server), + client_(client), before_finished_(before_finished), records_(0) {} @@ -481,8 +487,8 @@ class BeforeFinished13 : public PacketFilter { } private: - std::weak_ptr<TlsAgent> client_; std::weak_ptr<TlsAgent> server_; + std::weak_ptr<TlsAgent> client_; VoidFunction before_finished_; size_t records_; }; @@ -496,11 +502,9 @@ static SECStatus AuthCompleteBlock(TlsAgent*, PRBool, PRBool) { // processed by the client, SSL_AuthCertificateComplete() is called. TEST_F(TlsConnectDatagram13, AuthCompleteBeforeFinished) { client_->SetAuthCertificateCallback(AuthCompleteBlock); - server_->SetPacketFilter( - std::make_shared<BeforeFinished13>(client_, server_, [this]() { - EXPECT_EQ(SECSuccess, - SSL_AuthCertificateComplete(client_->ssl_fd(), 0)); - })); + MakeTlsFilter<BeforeFinished13>(server_, client_, [this]() { + EXPECT_EQ(SECSuccess, SSL_AuthCertificateComplete(client_->ssl_fd(), 0)); + }); Connect(); } @@ -528,13 +532,13 @@ TEST_F(TlsConnectDatagram13, AuthCompleteAfterFinished) { TEST_P(TlsConnectGenericPre13, ClientWriteBetweenCCSAndFinishedWithFalseStart) { client_->EnableFalseStart(); - server_->SetPacketFilter(std::make_shared<BeforeFinished>( - client_, server_, + MakeTlsFilter<BeforeFinished>( + server_, client_, [this]() { EXPECT_TRUE(client_->can_falsestart_hook_called()); }, [this]() { // Write something, which used to fail: bug 1235366. client_->SendData(10); - })); + }); Connect(); server_->SendData(10); @@ -544,8 +548,8 @@ TEST_P(TlsConnectGenericPre13, ClientWriteBetweenCCSAndFinishedWithFalseStart) { TEST_P(TlsConnectGenericPre13, AuthCompleteBeforeFinishedWithFalseStart) { client_->EnableFalseStart(); client_->SetAuthCertificateCallback(AuthCompleteBlock); - server_->SetPacketFilter(std::make_shared<BeforeFinished>( - client_, server_, + MakeTlsFilter<BeforeFinished>( + server_, client_, []() { // Do nothing before CCS }, @@ -556,7 +560,7 @@ TEST_P(TlsConnectGenericPre13, AuthCompleteBeforeFinishedWithFalseStart) { SSL_AuthCertificateComplete(client_->ssl_fd(), 0)); EXPECT_TRUE(client_->can_falsestart_hook_called()); client_->SendData(10); - })); + }); Connect(); server_->SendData(10); @@ -581,8 +585,7 @@ class EnforceNoActivity : public PacketFilter { TEST_P(TlsConnectGenericPre13, AuthCompleteDelayed) { client_->SetAuthCertificateCallback(AuthCompleteBlock); - server_->StartConnect(); - client_->StartConnect(); + StartConnect(); client_->Handshake(); // Send ClientHello server_->Handshake(); // Send ServerHello client_->Handshake(); // Send ClientKeyExchange and Finished @@ -591,7 +594,7 @@ TEST_P(TlsConnectGenericPre13, AuthCompleteDelayed) { EXPECT_EQ(TlsAgent::STATE_CONNECTED, server_->state()); // The client should send nothing from here on. - client_->SetPacketFilter(std::make_shared<EnforceNoActivity>()); + client_->SetFilter(std::make_shared<EnforceNoActivity>()); client_->Handshake(); EXPECT_EQ(TlsAgent::STATE_CONNECTING, client_->state()); @@ -601,8 +604,33 @@ TEST_P(TlsConnectGenericPre13, AuthCompleteDelayed) { EXPECT_EQ(TlsAgent::STATE_CONNECTED, client_->state()); EXPECT_EQ(TlsAgent::STATE_CONNECTED, server_->state()); - // Remove this before closing or the close_notify alert will trigger it. - client_->DeletePacketFilter(); + // Remove filter before closing or the close_notify alert will trigger it. + client_->ClearFilter(); +} + +TEST_P(TlsConnectGenericPre13, AuthCompleteFailDelayed) { + client_->SetAuthCertificateCallback(AuthCompleteBlock); + + StartConnect(); + client_->Handshake(); // Send ClientHello + server_->Handshake(); // Send ServerHello + client_->Handshake(); // Send ClientKeyExchange and Finished + server_->Handshake(); // Send Finished + // The server should now report that it is connected + EXPECT_EQ(TlsAgent::STATE_CONNECTED, server_->state()); + + // The client should send nothing from here on. + client_->SetFilter(std::make_shared<EnforceNoActivity>()); + client_->Handshake(); + EXPECT_EQ(TlsAgent::STATE_CONNECTING, client_->state()); + + // Report failure. + client_->ClearFilter(); + client_->ExpectSendAlert(kTlsAlertBadCertificate); + EXPECT_EQ(SECSuccess, SSL_AuthCertificateComplete(client_->ssl_fd(), + SSL_ERROR_BAD_CERTIFICATE)); + client_->Handshake(); // Fail + EXPECT_EQ(TlsAgent::STATE_ERROR, client_->state()); } // TLS 1.3 handles a delayed AuthComplete callback differently since the @@ -610,20 +638,19 @@ TEST_P(TlsConnectGenericPre13, AuthCompleteDelayed) { TEST_P(TlsConnectTls13, AuthCompleteDelayed) { client_->SetAuthCertificateCallback(AuthCompleteBlock); - server_->StartConnect(); - client_->StartConnect(); + StartConnect(); client_->Handshake(); // Send ClientHello server_->Handshake(); // Send ServerHello EXPECT_EQ(TlsAgent::STATE_CONNECTING, client_->state()); EXPECT_EQ(TlsAgent::STATE_CONNECTING, server_->state()); // The client will send nothing until AuthCertificateComplete is called. - client_->SetPacketFilter(std::make_shared<EnforceNoActivity>()); + client_->SetFilter(std::make_shared<EnforceNoActivity>()); client_->Handshake(); EXPECT_EQ(TlsAgent::STATE_CONNECTING, client_->state()); // This should allow the handshake to complete now. - client_->DeletePacketFilter(); + client_->ClearFilter(); EXPECT_EQ(SECSuccess, SSL_AuthCertificateComplete(client_->ssl_fd(), 0)); client_->Handshake(); // Send Finished server_->Handshake(); // Transition to connected and send NewSessionTicket @@ -631,6 +658,44 @@ TEST_P(TlsConnectTls13, AuthCompleteDelayed) { EXPECT_EQ(TlsAgent::STATE_CONNECTED, server_->state()); } +TEST_P(TlsConnectTls13, AuthCompleteFailDelayed) { + client_->SetAuthCertificateCallback(AuthCompleteBlock); + + StartConnect(); + client_->Handshake(); // Send ClientHello + server_->Handshake(); // Send ServerHello + EXPECT_EQ(TlsAgent::STATE_CONNECTING, client_->state()); + EXPECT_EQ(TlsAgent::STATE_CONNECTING, server_->state()); + + // The client will send nothing until AuthCertificateComplete is called. + client_->SetFilter(std::make_shared<EnforceNoActivity>()); + client_->Handshake(); + EXPECT_EQ(TlsAgent::STATE_CONNECTING, client_->state()); + + // Report failure. + client_->ClearFilter(); + ExpectAlert(client_, kTlsAlertBadCertificate); + EXPECT_EQ(SECSuccess, SSL_AuthCertificateComplete(client_->ssl_fd(), + SSL_ERROR_BAD_CERTIFICATE)); + client_->Handshake(); // This should now fail. + server_->Handshake(); // Get the error. + EXPECT_EQ(TlsAgent::STATE_ERROR, client_->state()); + EXPECT_EQ(TlsAgent::STATE_ERROR, server_->state()); +} + +static SECStatus AuthCompleteFail(TlsAgent*, PRBool, PRBool) { + PORT_SetError(SSL_ERROR_BAD_CERTIFICATE); + return SECFailure; +} + +TEST_P(TlsConnectGeneric, AuthFailImmediate) { + client_->SetAuthCertificateCallback(AuthCompleteFail); + + StartConnect(); + ConnectExpectAlert(client_, kTlsAlertBadCertificate); + client_->CheckErrorCode(SSL_ERROR_BAD_CERTIFICATE); +} + static const SSLExtraServerCertData ServerCertDataRsaPkcs1Decrypt = { ssl_auth_rsa_decrypt, nullptr, nullptr, nullptr}; static const SSLExtraServerCertData ServerCertDataRsaPkcs1Sign = { @@ -753,8 +818,7 @@ TEST_P(TlsSignatureSchemeConfiguration, SignatureSchemeConfigServer) { TEST_P(TlsSignatureSchemeConfiguration, SignatureSchemeConfigClient) { Reset(certificate_); auto capture = - std::make_shared<TlsExtensionCapture>(ssl_signature_algorithms_xtn); - client_->SetPacketFilter(capture); + MakeTlsFilter<TlsExtensionCapture>(client_, ssl_signature_algorithms_xtn); TestSignatureSchemeConfig(client_); const DataBuffer& ext = capture->extension(); @@ -782,8 +846,8 @@ INSTANTIATE_TEST_CASE_P( ::testing::Values(TlsAgent::kServerRsaSign), ::testing::Values(ssl_auth_rsa_sign), ::testing::Values(ssl_sig_rsa_pkcs1_sha256, ssl_sig_rsa_pkcs1_sha384, - ssl_sig_rsa_pkcs1_sha512, ssl_sig_rsa_pss_sha256, - ssl_sig_rsa_pss_sha384))); + ssl_sig_rsa_pkcs1_sha512, ssl_sig_rsa_pss_rsae_sha256, + ssl_sig_rsa_pss_rsae_sha384))); // PSS with SHA-512 needs a bigger key to work. INSTANTIATE_TEST_CASE_P( SignatureSchemeBigRsa, TlsSignatureSchemeConfiguration, @@ -791,7 +855,7 @@ INSTANTIATE_TEST_CASE_P( TlsConnectTestBase::kTlsV12Plus, ::testing::Values(TlsAgent::kRsa2048), ::testing::Values(ssl_auth_rsa_sign), - ::testing::Values(ssl_sig_rsa_pss_sha512))); + ::testing::Values(ssl_sig_rsa_pss_rsae_sha512))); INSTANTIATE_TEST_CASE_P( SignatureSchemeRsaSha1, TlsSignatureSchemeConfiguration, ::testing::Combine(TlsConnectTestBase::kTlsVariantsAll, @@ -828,4 +892,4 @@ INSTANTIATE_TEST_CASE_P( TlsAgent::kServerEcdsa384), ::testing::Values(ssl_auth_ecdsa), ::testing::Values(ssl_sig_ecdsa_sha1))); -} +} // namespace nss_test diff --git a/security/nss/gtests/ssl_gtest/ssl_cert_ext_unittest.cc b/security/nss/gtests/ssl_gtest/ssl_cert_ext_unittest.cc index 3463782e0..573c69c75 100644 --- a/security/nss/gtests/ssl_gtest/ssl_cert_ext_unittest.cc +++ b/security/nss/gtests/ssl_gtest/ssl_cert_ext_unittest.cc @@ -82,9 +82,8 @@ TEST_P(TlsConnectGenericPre13, SignedCertificateTimestampsLegacy) { ssl_kea_rsa)); EXPECT_EQ(SECSuccess, SSL_SetSignedCertTimestamps(server_->ssl_fd(), &kSctItem, ssl_kea_rsa)); - EXPECT_EQ(SECSuccess, - SSL_OptionSet(client_->ssl_fd(), SSL_ENABLE_SIGNED_CERT_TIMESTAMPS, - PR_TRUE)); + + client_->SetOption(SSL_ENABLE_SIGNED_CERT_TIMESTAMPS, PR_TRUE); SignedCertificateTimestampsExtractor timestamps_extractor(client_); Connect(); @@ -96,9 +95,7 @@ TEST_P(TlsConnectGeneric, SignedCertificateTimestampsSuccess) { EnsureTlsSetup(); EXPECT_TRUE( server_->ConfigServerCert(TlsAgent::kServerRsa, true, &kExtraSctData)); - EXPECT_EQ(SECSuccess, - SSL_OptionSet(client_->ssl_fd(), SSL_ENABLE_SIGNED_CERT_TIMESTAMPS, - PR_TRUE)); + client_->SetOption(SSL_ENABLE_SIGNED_CERT_TIMESTAMPS, PR_TRUE); SignedCertificateTimestampsExtractor timestamps_extractor(client_); Connect(); @@ -120,9 +117,7 @@ TEST_P(TlsConnectGeneric, SignedCertificateTimestampsInactiveClient) { TEST_P(TlsConnectGeneric, SignedCertificateTimestampsInactiveServer) { EnsureTlsSetup(); - EXPECT_EQ(SECSuccess, - SSL_OptionSet(client_->ssl_fd(), SSL_ENABLE_SIGNED_CERT_TIMESTAMPS, - PR_TRUE)); + client_->SetOption(SSL_ENABLE_SIGNED_CERT_TIMESTAMPS, PR_TRUE); SignedCertificateTimestampsExtractor timestamps_extractor(client_); Connect(); @@ -173,23 +168,20 @@ TEST_P(TlsConnectGeneric, OcspNotRequested) { // Even if the client asks, the server has nothing unless it is configured. TEST_P(TlsConnectGeneric, OcspNotProvided) { EnsureTlsSetup(); - EXPECT_EQ(SECSuccess, SSL_OptionSet(client_->ssl_fd(), - SSL_ENABLE_OCSP_STAPLING, PR_TRUE)); + client_->SetOption(SSL_ENABLE_OCSP_STAPLING, PR_TRUE); client_->SetAuthCertificateCallback(CheckNoOCSP); Connect(); } TEST_P(TlsConnectGenericPre13, OcspMangled) { EnsureTlsSetup(); - EXPECT_EQ(SECSuccess, SSL_OptionSet(client_->ssl_fd(), - SSL_ENABLE_OCSP_STAPLING, PR_TRUE)); + client_->SetOption(SSL_ENABLE_OCSP_STAPLING, PR_TRUE); EXPECT_TRUE( server_->ConfigServerCert(TlsAgent::kServerRsa, true, &kOcspExtraData)); static const uint8_t val[] = {1}; - auto replacer = std::make_shared<TlsExtensionReplacer>( - ssl_cert_status_xtn, DataBuffer(val, sizeof(val))); - server_->SetPacketFilter(replacer); + auto replacer = MakeTlsFilter<TlsExtensionReplacer>( + server_, ssl_cert_status_xtn, DataBuffer(val, sizeof(val))); ConnectExpectAlert(client_, kTlsAlertIllegalParameter); client_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_SERVER_HELLO); server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT); @@ -197,11 +189,9 @@ TEST_P(TlsConnectGenericPre13, OcspMangled) { TEST_P(TlsConnectGeneric, OcspSuccess) { EnsureTlsSetup(); - EXPECT_EQ(SECSuccess, SSL_OptionSet(client_->ssl_fd(), - SSL_ENABLE_OCSP_STAPLING, PR_TRUE)); + client_->SetOption(SSL_ENABLE_OCSP_STAPLING, PR_TRUE); auto capture_ocsp = - std::make_shared<TlsExtensionCapture>(ssl_cert_status_xtn); - server_->SetPacketFilter(capture_ocsp); + MakeTlsFilter<TlsExtensionCapture>(server_, ssl_cert_status_xtn); // The value should be available during the AuthCertificateCallback client_->SetAuthCertificateCallback([](TlsAgent* agent, bool checksig, @@ -225,8 +215,7 @@ TEST_P(TlsConnectGeneric, OcspSuccess) { TEST_P(TlsConnectGeneric, OcspHugeSuccess) { EnsureTlsSetup(); - EXPECT_EQ(SECSuccess, SSL_OptionSet(client_->ssl_fd(), - SSL_ENABLE_OCSP_STAPLING, PR_TRUE)); + client_->SetOption(SSL_ENABLE_OCSP_STAPLING, PR_TRUE); uint8_t hugeOcspValue[16385]; memset(hugeOcspValue, 0xa1, sizeof(hugeOcspValue)); @@ -254,4 +243,4 @@ TEST_P(TlsConnectGeneric, OcspHugeSuccess) { Connect(); } -} // namespace nspr_test +} // namespace nss_test diff --git a/security/nss/gtests/ssl_gtest/ssl_ciphersuite_unittest.cc b/security/nss/gtests/ssl_gtest/ssl_ciphersuite_unittest.cc index 85c30b2bf..fa2238be7 100644 --- a/security/nss/gtests/ssl_gtest/ssl_ciphersuite_unittest.cc +++ b/security/nss/gtests/ssl_gtest/ssl_ciphersuite_unittest.cc @@ -31,11 +31,11 @@ class TlsCipherSuiteTestBase : public TlsConnectTestBase { public: TlsCipherSuiteTestBase(SSLProtocolVariant variant, uint16_t version, uint16_t cipher_suite, SSLNamedGroup group, - SSLSignatureScheme signature_scheme) + SSLSignatureScheme sig_scheme) : TlsConnectTestBase(variant, version), cipher_suite_(cipher_suite), group_(group), - signature_scheme_(signature_scheme), + sig_scheme_(sig_scheme), csinfo_({0}) { SECStatus rv = SSL_GetCipherSuiteInfo(cipher_suite_, &csinfo_, sizeof(csinfo_)); @@ -60,26 +60,26 @@ class TlsCipherSuiteTestBase : public TlsConnectTestBase { server_->ConfigNamedGroups(groups); kea_type_ = SSLInt_GetKEAType(group_); - client_->SetSignatureSchemes(&signature_scheme_, 1); - server_->SetSignatureSchemes(&signature_scheme_, 1); + client_->SetSignatureSchemes(&sig_scheme_, 1); + server_->SetSignatureSchemes(&sig_scheme_, 1); } } virtual void SetupCertificate() { if (version_ >= SSL_LIBRARY_VERSION_TLS_1_3) { - switch (signature_scheme_) { + switch (sig_scheme_) { case ssl_sig_rsa_pkcs1_sha256: case ssl_sig_rsa_pkcs1_sha384: case ssl_sig_rsa_pkcs1_sha512: Reset(TlsAgent::kServerRsaSign); auth_type_ = ssl_auth_rsa_sign; break; - case ssl_sig_rsa_pss_sha256: - case ssl_sig_rsa_pss_sha384: + case ssl_sig_rsa_pss_rsae_sha256: + case ssl_sig_rsa_pss_rsae_sha384: Reset(TlsAgent::kServerRsaSign); auth_type_ = ssl_auth_rsa_sign; break; - case ssl_sig_rsa_pss_sha512: + case ssl_sig_rsa_pss_rsae_sha512: // You can't fit SHA-512 PSS in a 1024-bit key. Reset(TlsAgent::kRsa2048); auth_type_ = ssl_auth_rsa_sign; @@ -93,8 +93,7 @@ class TlsCipherSuiteTestBase : public TlsConnectTestBase { auth_type_ = ssl_auth_ecdsa; break; default: - ASSERT_TRUE(false) << "Unsupported signature scheme: " - << signature_scheme_; + ADD_FAILURE() << "Unsupported signature scheme: " << sig_scheme_; break; } } else { @@ -187,7 +186,7 @@ class TlsCipherSuiteTestBase : public TlsConnectTestBase { SSLAuthType auth_type_; SSLKEAType kea_type_; SSLNamedGroup group_; - SSLSignatureScheme signature_scheme_; + SSLSignatureScheme sig_scheme_; SSLCipherSuiteInfo csinfo_; }; @@ -236,27 +235,29 @@ TEST_P(TlsCipherSuiteTest, ResumeCipherSuite) { ConnectAndCheckCipherSuite(); } -// This only works for stream ciphers because we modify the sequence number - -// which is included explicitly in the DTLS record header - and that trips a -// different error code. Note that the message that the client sends would not -// decrypt (the nonce/IV wouldn't match), but the record limit is hit before -// attempting to decrypt a record. TEST_P(TlsCipherSuiteTest, ReadLimit) { SetupCertificate(); EnableSingleCipher(); ConnectAndCheckCipherSuite(); - EXPECT_EQ(SECSuccess, - SSLInt_AdvanceWriteSeqNum(client_->ssl_fd(), last_safe_write())); - EXPECT_EQ(SECSuccess, - SSLInt_AdvanceReadSeqNum(server_->ssl_fd(), last_safe_write())); + if (version_ < SSL_LIBRARY_VERSION_TLS_1_3) { + uint64_t last = last_safe_write(); + EXPECT_EQ(SECSuccess, SSLInt_AdvanceWriteSeqNum(client_->ssl_fd(), last)); + EXPECT_EQ(SECSuccess, SSLInt_AdvanceReadSeqNum(server_->ssl_fd(), last)); - client_->SendData(10, 10); - server_->ReadBytes(); // This should be OK. + client_->SendData(10, 10); + server_->ReadBytes(); // This should be OK. + } 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; + EXPECT_EQ(SECSuccess, SSLInt_AdvanceReadSeqNum(server_->ssl_fd(), last)); + } - // The payload needs to be big enough to pass for encrypted. In the extreme - // case (TLS 1.3), this means 1 for payload, 1 for content type and 16 for - // authentication tag. - static const uint8_t payload[18] = {6}; + // The payload needs to be big enough to pass for encrypted. The code checks + // the limit before it tries to decrypt. + static const uint8_t payload[32] = {6}; DataBuffer record; uint64_t epoch; if (variant_ == ssl_variant_datagram) { @@ -271,13 +272,17 @@ TEST_P(TlsCipherSuiteTest, ReadLimit) { TlsAgentTestBase::MakeRecord(variant_, kTlsApplicationDataType, version_, payload, sizeof(payload), &record, (epoch << 48) | record_limit()); - server_->adapter()->PacketReceived(record); + client_->SendDirect(record); server_->ExpectReadWriteError(); server_->ReadBytes(); EXPECT_EQ(SSL_ERROR_TOO_MANY_RECORDS, server_->error_code()); } TEST_P(TlsCipherSuiteTest, WriteLimit) { + // This asserts in TLS 1.3 because we expect an automatic update. + if (version_ >= SSL_LIBRARY_VERSION_TLS_1_3) { + return; + } SetupCertificate(); EnableSingleCipher(); ConnectAndCheckCipherSuite(); @@ -308,8 +313,8 @@ static const auto kDummySignatureSchemesParams = static SSLSignatureScheme kSignatureSchemesParamsArr[] = { ssl_sig_rsa_pkcs1_sha256, ssl_sig_rsa_pkcs1_sha384, ssl_sig_rsa_pkcs1_sha512, ssl_sig_ecdsa_secp256r1_sha256, - ssl_sig_ecdsa_secp384r1_sha384, ssl_sig_rsa_pss_sha256, - ssl_sig_rsa_pss_sha384, ssl_sig_rsa_pss_sha512, + ssl_sig_ecdsa_secp384r1_sha384, ssl_sig_rsa_pss_rsae_sha256, + ssl_sig_rsa_pss_rsae_sha384, ssl_sig_rsa_pss_rsae_sha512, }; #endif @@ -461,4 +466,4 @@ static const SecStatusParams kSecStatusTestValuesArr[] = { INSTANTIATE_TEST_CASE_P(TestSecurityStatus, SecurityStatusTest, ::testing::ValuesIn(kSecStatusTestValuesArr)); -} // namespace nspr_test +} // namespace nss_test diff --git a/security/nss/gtests/ssl_gtest/ssl_custext_unittest.cc b/security/nss/gtests/ssl_gtest/ssl_custext_unittest.cc new file mode 100644 index 000000000..c2f582a93 --- /dev/null +++ b/security/nss/gtests/ssl_gtest/ssl_custext_unittest.cc @@ -0,0 +1,498 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "ssl.h" +#include "ssl3prot.h" +#include "sslerr.h" +#include "sslproto.h" +#include "sslexp.h" + +#include <memory> + +#include "tls_connect.h" + +namespace nss_test { + +static void IncrementCounterArg(void *arg) { + if (arg) { + auto *called = reinterpret_cast<size_t *>(arg); + ++*called; + } +} + +PRBool NoopExtensionWriter(PRFileDesc *fd, SSLHandshakeType message, + PRUint8 *data, unsigned int *len, + unsigned int maxLen, void *arg) { + IncrementCounterArg(arg); + return PR_FALSE; +} + +PRBool EmptyExtensionWriter(PRFileDesc *fd, SSLHandshakeType message, + PRUint8 *data, unsigned int *len, + unsigned int maxLen, void *arg) { + IncrementCounterArg(arg); + return PR_TRUE; +} + +SECStatus NoopExtensionHandler(PRFileDesc *fd, SSLHandshakeType message, + const PRUint8 *data, unsigned int len, + SSLAlertDescription *alert, void *arg) { + return SECSuccess; +} + +// All of the (current) set of supported extensions, plus a few extra. +static const uint16_t kManyExtensions[] = { + ssl_server_name_xtn, + ssl_cert_status_xtn, + ssl_supported_groups_xtn, + ssl_ec_point_formats_xtn, + ssl_signature_algorithms_xtn, + ssl_signature_algorithms_cert_xtn, + ssl_use_srtp_xtn, + ssl_app_layer_protocol_xtn, + ssl_signed_cert_timestamp_xtn, + ssl_padding_xtn, + ssl_extended_master_secret_xtn, + ssl_session_ticket_xtn, + ssl_tls13_key_share_xtn, + ssl_tls13_pre_shared_key_xtn, + ssl_tls13_early_data_xtn, + ssl_tls13_supported_versions_xtn, + ssl_tls13_cookie_xtn, + ssl_tls13_psk_key_exchange_modes_xtn, + ssl_tls13_ticket_early_data_info_xtn, + ssl_tls13_certificate_authorities_xtn, + ssl_next_proto_nego_xtn, + ssl_renegotiation_info_xtn, + ssl_tls13_short_header_xtn, + 1, + 0xffff}; +// The list here includes all extensions we expect to use (SSL_MAX_EXTENSIONS), +// plus the deprecated values (see sslt.h), and two extra dummy values. +PR_STATIC_ASSERT((SSL_MAX_EXTENSIONS + 5) == PR_ARRAY_SIZE(kManyExtensions)); + +void InstallManyWriters(std::shared_ptr<TlsAgent> agent, + SSLExtensionWriter writer, size_t *installed = nullptr, + size_t *called = nullptr) { + for (size_t i = 0; i < PR_ARRAY_SIZE(kManyExtensions); ++i) { + SSLExtensionSupport support = ssl_ext_none; + SECStatus rv = SSL_GetExtensionSupport(kManyExtensions[i], &support); + ASSERT_EQ(SECSuccess, rv) << "SSL_GetExtensionSupport cannot fail"; + + rv = SSL_InstallExtensionHooks(agent->ssl_fd(), kManyExtensions[i], writer, + called, NoopExtensionHandler, nullptr); + if (support == ssl_ext_native_only) { + EXPECT_EQ(SECFailure, rv); + EXPECT_EQ(SEC_ERROR_INVALID_ARGS, PORT_GetError()); + } else { + if (installed) { + ++*installed; + } + EXPECT_EQ(SECSuccess, rv); + } + } +} + +TEST_F(TlsConnectStreamTls13, CustomExtensionAllNoopClient) { + EnsureTlsSetup(); + size_t installed = 0; + size_t called = 0; + InstallManyWriters(client_, NoopExtensionWriter, &installed, &called); + EXPECT_LT(0U, installed); + Connect(); + EXPECT_EQ(installed, called); +} + +TEST_F(TlsConnectStreamTls13, CustomExtensionAllNoopServer) { + EnsureTlsSetup(); + size_t installed = 0; + size_t called = 0; + InstallManyWriters(server_, NoopExtensionWriter, &installed, &called); + EXPECT_LT(0U, installed); + Connect(); + // Extension writers are all called for each of ServerHello, + // EncryptedExtensions, and Certificate. + EXPECT_EQ(installed * 3, called); +} + +TEST_F(TlsConnectStreamTls13, CustomExtensionEmptyWriterClient) { + EnsureTlsSetup(); + InstallManyWriters(client_, EmptyExtensionWriter); + InstallManyWriters(server_, EmptyExtensionWriter); + Connect(); +} + +TEST_F(TlsConnectStreamTls13, CustomExtensionEmptyWriterServer) { + EnsureTlsSetup(); + InstallManyWriters(server_, EmptyExtensionWriter); + // Sending extensions that the client doesn't expect leads to extensions + // appearing even if the client didn't send one, or in the wrong messages. + client_->ExpectSendAlert(kTlsAlertUnsupportedExtension); + server_->ExpectSendAlert(kTlsAlertBadRecordMac); + ConnectExpectFail(); +} + +// Install an writer to disable sending of a natively-supported extension. +TEST_F(TlsConnectStreamTls13, CustomExtensionWriterDisable) { + EnsureTlsSetup(); + + // This option enables sending the extension via the native support. + SECStatus rv = SSL_OptionSet(client_->ssl_fd(), + SSL_ENABLE_SIGNED_CERT_TIMESTAMPS, PR_TRUE); + EXPECT_EQ(SECSuccess, rv); + + // This installs an override that doesn't do anything. You have to specify + // something; passing all nullptr values removes an existing handler. + rv = SSL_InstallExtensionHooks( + client_->ssl_fd(), ssl_signed_cert_timestamp_xtn, NoopExtensionWriter, + nullptr, NoopExtensionHandler, nullptr); + EXPECT_EQ(SECSuccess, rv); + auto capture = MakeTlsFilter<TlsExtensionCapture>( + client_, ssl_signed_cert_timestamp_xtn); + + Connect(); + // So nothing will be sent. + EXPECT_FALSE(capture->captured()); +} + +// An extension that is unlikely to be parsed as valid. +static uint8_t kNonsenseExtension[] = {91, 82, 73, 64, 55, 46, 37, 28, 19}; + +static PRBool NonsenseExtensionWriter(PRFileDesc *fd, SSLHandshakeType message, + PRUint8 *data, unsigned int *len, + unsigned int maxLen, void *arg) { + TlsAgent *agent = reinterpret_cast<TlsAgent *>(arg); + EXPECT_NE(nullptr, agent); + EXPECT_NE(nullptr, data); + EXPECT_NE(nullptr, len); + EXPECT_EQ(0U, *len); + EXPECT_LT(0U, maxLen); + EXPECT_EQ(agent->ssl_fd(), fd); + + if (message != ssl_hs_client_hello && message != ssl_hs_server_hello && + message != ssl_hs_encrypted_extensions) { + return PR_FALSE; + } + + *len = static_cast<unsigned int>(sizeof(kNonsenseExtension)); + EXPECT_GE(maxLen, *len); + if (maxLen < *len) { + return PR_FALSE; + } + PORT_Memcpy(data, kNonsenseExtension, *len); + return PR_TRUE; +} + +// Override the extension handler for an natively-supported and produce +// nonsense, which results in a handshake failure. +TEST_F(TlsConnectStreamTls13, CustomExtensionOverride) { + EnsureTlsSetup(); + + // This option enables sending the extension via the native support. + SECStatus rv = SSL_OptionSet(client_->ssl_fd(), + SSL_ENABLE_SIGNED_CERT_TIMESTAMPS, PR_TRUE); + EXPECT_EQ(SECSuccess, rv); + + // This installs an override that sends nonsense. + rv = SSL_InstallExtensionHooks( + client_->ssl_fd(), ssl_signed_cert_timestamp_xtn, NonsenseExtensionWriter, + client_.get(), NoopExtensionHandler, nullptr); + EXPECT_EQ(SECSuccess, rv); + + // Capture it to see what we got. + auto capture = MakeTlsFilter<TlsExtensionCapture>( + client_, ssl_signed_cert_timestamp_xtn); + + ConnectExpectAlert(server_, kTlsAlertDecodeError); + + EXPECT_TRUE(capture->captured()); + EXPECT_EQ(DataBuffer(kNonsenseExtension, sizeof(kNonsenseExtension)), + capture->extension()); +} + +static SECStatus NonsenseExtensionHandler(PRFileDesc *fd, + SSLHandshakeType message, + const PRUint8 *data, unsigned int len, + SSLAlertDescription *alert, + void *arg) { + TlsAgent *agent = reinterpret_cast<TlsAgent *>(arg); + EXPECT_EQ(agent->ssl_fd(), fd); + if (agent->role() == TlsAgent::SERVER) { + EXPECT_EQ(ssl_hs_client_hello, message); + } else { + EXPECT_TRUE(message == ssl_hs_server_hello || + message == ssl_hs_encrypted_extensions); + } + EXPECT_EQ(DataBuffer(kNonsenseExtension, sizeof(kNonsenseExtension)), + DataBuffer(data, len)); + EXPECT_NE(nullptr, alert); + return SECSuccess; +} + +// Send nonsense in an extension from client to server. +TEST_F(TlsConnectStreamTls13, CustomExtensionClientToServer) { + EnsureTlsSetup(); + + // This installs an override that sends nonsense. + const uint16_t extension_code = 0xffe5; + SECStatus rv = SSL_InstallExtensionHooks( + client_->ssl_fd(), extension_code, NonsenseExtensionWriter, client_.get(), + NoopExtensionHandler, nullptr); + EXPECT_EQ(SECSuccess, rv); + + // Capture it to see what we got. + auto capture = MakeTlsFilter<TlsExtensionCapture>(client_, extension_code); + + // Handle it so that the handshake completes. + rv = SSL_InstallExtensionHooks(server_->ssl_fd(), extension_code, + NoopExtensionWriter, nullptr, + NonsenseExtensionHandler, server_.get()); + EXPECT_EQ(SECSuccess, rv); + + Connect(); + + EXPECT_TRUE(capture->captured()); + EXPECT_EQ(DataBuffer(kNonsenseExtension, sizeof(kNonsenseExtension)), + capture->extension()); +} + +static PRBool NonsenseExtensionWriterSH(PRFileDesc *fd, + SSLHandshakeType message, PRUint8 *data, + unsigned int *len, unsigned int maxLen, + void *arg) { + if (message == ssl_hs_server_hello) { + return NonsenseExtensionWriter(fd, message, data, len, maxLen, arg); + } + return PR_FALSE; +} + +// Send nonsense in an extension from server to client, in ServerHello. +TEST_F(TlsConnectStreamTls13, CustomExtensionServerToClientSH) { + EnsureTlsSetup(); + + // This installs an override that sends nothing but expects nonsense. + const uint16_t extension_code = 0xff5e; + SECStatus rv = SSL_InstallExtensionHooks( + client_->ssl_fd(), extension_code, EmptyExtensionWriter, nullptr, + NonsenseExtensionHandler, client_.get()); + EXPECT_EQ(SECSuccess, rv); + + // Have the server send nonsense. + rv = SSL_InstallExtensionHooks(server_->ssl_fd(), extension_code, + NonsenseExtensionWriterSH, server_.get(), + NoopExtensionHandler, nullptr); + EXPECT_EQ(SECSuccess, rv); + + // Capture the extension from the ServerHello only and check it. + auto capture = MakeTlsFilter<TlsExtensionCapture>(server_, extension_code); + capture->SetHandshakeTypes({kTlsHandshakeServerHello}); + + Connect(); + + EXPECT_TRUE(capture->captured()); + EXPECT_EQ(DataBuffer(kNonsenseExtension, sizeof(kNonsenseExtension)), + capture->extension()); +} + +static PRBool NonsenseExtensionWriterEE(PRFileDesc *fd, + SSLHandshakeType message, PRUint8 *data, + unsigned int *len, unsigned int maxLen, + void *arg) { + if (message == ssl_hs_encrypted_extensions) { + return NonsenseExtensionWriter(fd, message, data, len, maxLen, arg); + } + return PR_FALSE; +} + +// Send nonsense in an extension from server to client, in EncryptedExtensions. +TEST_F(TlsConnectStreamTls13, CustomExtensionServerToClientEE) { + EnsureTlsSetup(); + + // This installs an override that sends nothing but expects nonsense. + const uint16_t extension_code = 0xff5e; + SECStatus rv = SSL_InstallExtensionHooks( + client_->ssl_fd(), extension_code, EmptyExtensionWriter, nullptr, + NonsenseExtensionHandler, client_.get()); + EXPECT_EQ(SECSuccess, rv); + + // Have the server send nonsense. + rv = SSL_InstallExtensionHooks(server_->ssl_fd(), extension_code, + NonsenseExtensionWriterEE, server_.get(), + NoopExtensionHandler, nullptr); + EXPECT_EQ(SECSuccess, rv); + + // Capture the extension from the EncryptedExtensions only and check it. + auto capture = MakeTlsFilter<TlsExtensionCapture>(server_, extension_code); + capture->SetHandshakeTypes({kTlsHandshakeEncryptedExtensions}); + capture->EnableDecryption(); + + Connect(); + + EXPECT_TRUE(capture->captured()); + EXPECT_EQ(DataBuffer(kNonsenseExtension, sizeof(kNonsenseExtension)), + capture->extension()); +} + +TEST_F(TlsConnectStreamTls13, CustomExtensionUnsolicitedServer) { + EnsureTlsSetup(); + + const uint16_t extension_code = 0xff5e; + SECStatus rv = SSL_InstallExtensionHooks( + server_->ssl_fd(), extension_code, NonsenseExtensionWriter, server_.get(), + NoopExtensionHandler, nullptr); + EXPECT_EQ(SECSuccess, rv); + + // Capture it to see what we got. + auto capture = MakeTlsFilter<TlsExtensionCapture>(server_, extension_code); + + client_->ExpectSendAlert(kTlsAlertUnsupportedExtension); + server_->ExpectSendAlert(kTlsAlertBadRecordMac); + ConnectExpectFail(); + + EXPECT_TRUE(capture->captured()); + EXPECT_EQ(DataBuffer(kNonsenseExtension, sizeof(kNonsenseExtension)), + capture->extension()); +} + +SECStatus RejectExtensionHandler(PRFileDesc *fd, SSLHandshakeType message, + const PRUint8 *data, unsigned int len, + SSLAlertDescription *alert, void *arg) { + return SECFailure; +} + +TEST_F(TlsConnectStreamTls13, CustomExtensionServerReject) { + EnsureTlsSetup(); + + // This installs an override that sends nonsense. + const uint16_t extension_code = 0xffe7; + SECStatus rv = SSL_InstallExtensionHooks(client_->ssl_fd(), extension_code, + EmptyExtensionWriter, nullptr, + NoopExtensionHandler, nullptr); + EXPECT_EQ(SECSuccess, rv); + + // Reject the extension for no good reason. + rv = SSL_InstallExtensionHooks(server_->ssl_fd(), extension_code, + NoopExtensionWriter, nullptr, + RejectExtensionHandler, nullptr); + EXPECT_EQ(SECSuccess, rv); + + ConnectExpectAlert(server_, kTlsAlertHandshakeFailure); +} + +// Send nonsense in an extension from client to server. +TEST_F(TlsConnectStreamTls13, CustomExtensionClientReject) { + EnsureTlsSetup(); + + // This installs an override that sends nothing but expects nonsense. + const uint16_t extension_code = 0xff58; + SECStatus rv = SSL_InstallExtensionHooks(client_->ssl_fd(), extension_code, + EmptyExtensionWriter, nullptr, + RejectExtensionHandler, nullptr); + EXPECT_EQ(SECSuccess, rv); + + // Have the server send nonsense. + rv = SSL_InstallExtensionHooks(server_->ssl_fd(), extension_code, + EmptyExtensionWriter, nullptr, + NoopExtensionHandler, nullptr); + EXPECT_EQ(SECSuccess, rv); + + client_->ExpectSendAlert(kTlsAlertHandshakeFailure); + server_->ExpectSendAlert(kTlsAlertBadRecordMac); + ConnectExpectFail(); +} + +static const uint8_t kCustomAlert = 0xf6; + +SECStatus AlertExtensionHandler(PRFileDesc *fd, SSLHandshakeType message, + const PRUint8 *data, unsigned int len, + SSLAlertDescription *alert, void *arg) { + *alert = kCustomAlert; + return SECFailure; +} + +TEST_F(TlsConnectStreamTls13, CustomExtensionServerRejectAlert) { + EnsureTlsSetup(); + + // This installs an override that sends nonsense. + const uint16_t extension_code = 0xffea; + SECStatus rv = SSL_InstallExtensionHooks(client_->ssl_fd(), extension_code, + EmptyExtensionWriter, nullptr, + NoopExtensionHandler, nullptr); + EXPECT_EQ(SECSuccess, rv); + + // Reject the extension for no good reason. + rv = SSL_InstallExtensionHooks(server_->ssl_fd(), extension_code, + NoopExtensionWriter, nullptr, + AlertExtensionHandler, nullptr); + EXPECT_EQ(SECSuccess, rv); + + ConnectExpectAlert(server_, kCustomAlert); +} + +// Send nonsense in an extension from client to server. +TEST_F(TlsConnectStreamTls13, CustomExtensionClientRejectAlert) { + EnsureTlsSetup(); + + // This installs an override that sends nothing but expects nonsense. + const uint16_t extension_code = 0xff5a; + SECStatus rv = SSL_InstallExtensionHooks(client_->ssl_fd(), extension_code, + EmptyExtensionWriter, nullptr, + AlertExtensionHandler, nullptr); + EXPECT_EQ(SECSuccess, rv); + + // Have the server send nonsense. + rv = SSL_InstallExtensionHooks(server_->ssl_fd(), extension_code, + EmptyExtensionWriter, nullptr, + NoopExtensionHandler, nullptr); + EXPECT_EQ(SECSuccess, rv); + + client_->ExpectSendAlert(kCustomAlert); + server_->ExpectSendAlert(kTlsAlertBadRecordMac); + ConnectExpectFail(); +} + +// Configure a custom extension hook badly. +TEST_F(TlsConnectStreamTls13, CustomExtensionOnlyWriter) { + EnsureTlsSetup(); + + // This installs an override that sends nothing but expects nonsense. + SECStatus rv = + SSL_InstallExtensionHooks(client_->ssl_fd(), 0xff6c, EmptyExtensionWriter, + nullptr, nullptr, nullptr); + EXPECT_EQ(SECFailure, rv); + EXPECT_EQ(SEC_ERROR_INVALID_ARGS, PORT_GetError()); +} + +TEST_F(TlsConnectStreamTls13, CustomExtensionOnlyHandler) { + EnsureTlsSetup(); + + // This installs an override that sends nothing but expects nonsense. + SECStatus rv = + SSL_InstallExtensionHooks(client_->ssl_fd(), 0xff6d, nullptr, nullptr, + NoopExtensionHandler, nullptr); + EXPECT_EQ(SECFailure, rv); + EXPECT_EQ(SEC_ERROR_INVALID_ARGS, PORT_GetError()); +} + +TEST_F(TlsConnectStreamTls13, CustomExtensionOverrunBuffer) { + EnsureTlsSetup(); + // This doesn't actually overrun the buffer, but it says that it does. + auto overrun_writer = [](PRFileDesc *fd, SSLHandshakeType message, + PRUint8 *data, unsigned int *len, + unsigned int maxLen, void *arg) -> PRBool { + *len = maxLen + 1; + return PR_TRUE; + }; + SECStatus rv = + SSL_InstallExtensionHooks(client_->ssl_fd(), 0xff71, overrun_writer, + nullptr, NoopExtensionHandler, nullptr); + EXPECT_EQ(SECSuccess, rv); + client_->StartConnect(); + client_->Handshake(); + client_->CheckErrorCode(SEC_ERROR_APPLICATION_CALLBACK_ERROR); +} + +} // namespace nss_test diff --git a/security/nss/gtests/ssl_gtest/ssl_damage_unittest.cc b/security/nss/gtests/ssl_gtest/ssl_damage_unittest.cc index 69fd00331..b8836d7fc 100644 --- a/security/nss/gtests/ssl_gtest/ssl_damage_unittest.cc +++ b/security/nss/gtests/ssl_gtest/ssl_damage_unittest.cc @@ -29,8 +29,7 @@ TEST_F(TlsConnectTest, DamageSecretHandleClientFinished) { SSL_LIBRARY_VERSION_TLS_1_3); server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1, SSL_LIBRARY_VERSION_TLS_1_3); - server_->StartConnect(); - client_->StartConnect(); + StartConnect(); client_->Handshake(); server_->Handshake(); std::cerr << "Damaging HS secret" << std::endl; @@ -51,23 +50,19 @@ TEST_F(TlsConnectTest, DamageSecretHandleServerFinished) { SSL_LIBRARY_VERSION_TLS_1_3); server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1, SSL_LIBRARY_VERSION_TLS_1_3); - client_->ExpectSendAlert(kTlsAlertDecryptError); - // The server can't read the client's alert, so it also sends an alert. - server_->ExpectSendAlert(kTlsAlertBadRecordMac); - server_->SetPacketFilter(std::make_shared<AfterRecordN>( + MakeTlsFilter<AfterRecordN>( server_, client_, 0, // ServerHello. - [this]() { SSLInt_DamageServerHsTrafficSecret(client_->ssl_fd()); })); - ConnectExpectFail(); + [this]() { SSLInt_DamageServerHsTrafficSecret(client_->ssl_fd()); }); + ConnectExpectAlert(client_, kTlsAlertDecryptError); client_->CheckErrorCode(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE); - server_->CheckErrorCode(SSL_ERROR_BAD_MAC_READ); } TEST_P(TlsConnectGenericPre13, DamageServerSignature) { EnsureTlsSetup(); - auto filter = - std::make_shared<TlsLastByteDamager>(kTlsHandshakeServerKeyExchange); - server_->SetTlsRecordFilter(filter); + auto filter = MakeTlsFilter<TlsLastByteDamager>( + server_, kTlsHandshakeServerKeyExchange); + filter->EnableDecryption(); ExpectAlert(client_, kTlsAlertDecryptError); ConnectExpectFail(); client_->CheckErrorCode(SEC_ERROR_BAD_SIGNATURE); @@ -76,19 +71,10 @@ TEST_P(TlsConnectGenericPre13, DamageServerSignature) { TEST_P(TlsConnectTls13, DamageServerSignature) { EnsureTlsSetup(); - auto filter = - std::make_shared<TlsLastByteDamager>(kTlsHandshakeCertificateVerify); - server_->SetTlsRecordFilter(filter); + auto filter = MakeTlsFilter<TlsLastByteDamager>( + server_, kTlsHandshakeCertificateVerify); filter->EnableDecryption(); - client_->ExpectSendAlert(kTlsAlertDecryptError); - // The server can't read the client's alert, so it also sends an alert. - if (variant_ == ssl_variant_stream) { - server_->ExpectSendAlert(kTlsAlertBadRecordMac); - ConnectExpectFail(); - server_->CheckErrorCode(SSL_ERROR_BAD_MAC_READ); - } else { - ConnectExpectFailOneSide(TlsAgent::CLIENT); - } + ConnectExpectAlert(client_, kTlsAlertDecryptError); client_->CheckErrorCode(SEC_ERROR_BAD_SIGNATURE); } @@ -96,15 +82,13 @@ TEST_P(TlsConnectGeneric, DamageClientSignature) { EnsureTlsSetup(); client_->SetupClientAuth(); server_->RequestClientAuth(true); - auto filter = - std::make_shared<TlsLastByteDamager>(kTlsHandshakeCertificateVerify); - client_->SetTlsRecordFilter(filter); - server_->ExpectSendAlert(kTlsAlertDecryptError); + auto filter = MakeTlsFilter<TlsLastByteDamager>( + client_, kTlsHandshakeCertificateVerify); filter->EnableDecryption(); + server_->ExpectSendAlert(kTlsAlertDecryptError); // Do these handshakes by hand to avoid race condition on // the client processing the server's alert. - client_->StartConnect(); - server_->StartConnect(); + StartConnect(); client_->Handshake(); server_->Handshake(); client_->Handshake(); @@ -116,4 +100,4 @@ TEST_P(TlsConnectGeneric, DamageClientSignature) { server_->CheckErrorCode(SEC_ERROR_BAD_SIGNATURE); } -} // namespace nspr_test +} // namespace nss_test diff --git a/security/nss/gtests/ssl_gtest/ssl_dhe_unittest.cc b/security/nss/gtests/ssl_gtest/ssl_dhe_unittest.cc index 97943303a..cdafa7a84 100644 --- a/security/nss/gtests/ssl_gtest/ssl_dhe_unittest.cc +++ b/security/nss/gtests/ssl_gtest/ssl_dhe_unittest.cc @@ -24,7 +24,7 @@ TEST_P(TlsConnectGeneric, ConnectDhe) { EnableOnlyDheCiphers(); Connect(); CheckKeys(ssl_kea_dh, ssl_grp_ffdhe_2048, ssl_auth_rsa_sign, - ssl_sig_rsa_pss_sha256); + ssl_sig_rsa_pss_rsae_sha256); } TEST_P(TlsConnectTls13, SharesForBothEcdheAndDhe) { @@ -32,12 +32,12 @@ TEST_P(TlsConnectTls13, SharesForBothEcdheAndDhe) { client_->ConfigNamedGroups(kAllDHEGroups); auto groups_capture = - std::make_shared<TlsExtensionCapture>(ssl_supported_groups_xtn); + std::make_shared<TlsExtensionCapture>(client_, ssl_supported_groups_xtn); auto shares_capture = - std::make_shared<TlsExtensionCapture>(ssl_tls13_key_share_xtn); + std::make_shared<TlsExtensionCapture>(client_, ssl_tls13_key_share_xtn); std::vector<std::shared_ptr<PacketFilter>> captures = {groups_capture, shares_capture}; - client_->SetPacketFilter(std::make_shared<ChainedPacketFilter>(captures)); + client_->SetFilter(std::make_shared<ChainedPacketFilter>(captures)); Connect(); @@ -59,15 +59,14 @@ TEST_P(TlsConnectTls13, SharesForBothEcdheAndDhe) { TEST_P(TlsConnectGeneric, ConnectFfdheClient) { EnableOnlyDheCiphers(); - EXPECT_EQ(SECSuccess, SSL_OptionSet(client_->ssl_fd(), - SSL_REQUIRE_DH_NAMED_GROUPS, PR_TRUE)); + client_->SetOption(SSL_REQUIRE_DH_NAMED_GROUPS, PR_TRUE); auto groups_capture = - std::make_shared<TlsExtensionCapture>(ssl_supported_groups_xtn); + std::make_shared<TlsExtensionCapture>(client_, ssl_supported_groups_xtn); auto shares_capture = - std::make_shared<TlsExtensionCapture>(ssl_tls13_key_share_xtn); + std::make_shared<TlsExtensionCapture>(client_, ssl_tls13_key_share_xtn); std::vector<std::shared_ptr<PacketFilter>> captures = {groups_capture, shares_capture}; - client_->SetPacketFilter(std::make_shared<ChainedPacketFilter>(captures)); + client_->SetFilter(std::make_shared<ChainedPacketFilter>(captures)); Connect(); @@ -90,8 +89,7 @@ TEST_P(TlsConnectGeneric, ConnectFfdheClient) { // because the client automatically sends the supported groups extension. TEST_P(TlsConnectGenericPre13, ConnectFfdheServer) { EnableOnlyDheCiphers(); - EXPECT_EQ(SECSuccess, SSL_OptionSet(server_->ssl_fd(), - SSL_REQUIRE_DH_NAMED_GROUPS, PR_TRUE)); + server_->SetOption(SSL_REQUIRE_DH_NAMED_GROUPS, PR_TRUE); if (version_ >= SSL_LIBRARY_VERSION_TLS_1_3) { Connect(); @@ -105,14 +103,11 @@ TEST_P(TlsConnectGenericPre13, ConnectFfdheServer) { class TlsDheServerKeyExchangeDamager : public TlsHandshakeFilter { public: - TlsDheServerKeyExchangeDamager() {} + TlsDheServerKeyExchangeDamager(const std::shared_ptr<TlsAgent>& agent) + : TlsHandshakeFilter(agent, {kTlsHandshakeServerKeyExchange}) {} virtual PacketFilter::Action FilterHandshake( const TlsHandshakeFilter::HandshakeHeader& header, const DataBuffer& input, DataBuffer* output) { - if (header.handshake_type() != kTlsHandshakeServerKeyExchange) { - return KEEP; - } - // Damage the first octet of dh_p. Anything other than the known prime will // be rejected as "weak" when we have SSL_REQUIRE_DH_NAMED_GROUPS enabled. *output = input; @@ -126,9 +121,8 @@ class TlsDheServerKeyExchangeDamager : public TlsHandshakeFilter { // the signature until everything else has been checked. TEST_P(TlsConnectGenericPre13, DamageServerKeyShare) { EnableOnlyDheCiphers(); - EXPECT_EQ(SECSuccess, SSL_OptionSet(client_->ssl_fd(), - SSL_REQUIRE_DH_NAMED_GROUPS, PR_TRUE)); - server_->SetPacketFilter(std::make_shared<TlsDheServerKeyExchangeDamager>()); + client_->SetOption(SSL_REQUIRE_DH_NAMED_GROUPS, PR_TRUE); + MakeTlsFilter<TlsDheServerKeyExchangeDamager>(server_); ConnectExpectAlert(client_, kTlsAlertIllegalParameter); @@ -147,7 +141,9 @@ class TlsDheSkeChangeY : public TlsHandshakeFilter { kYZeroPad }; - TlsDheSkeChangeY(ChangeYTo change) : change_Y_(change) {} + TlsDheSkeChangeY(const std::shared_ptr<TlsAgent>& agent, + uint8_t handshake_type, ChangeYTo change) + : TlsHandshakeFilter(agent, {handshake_type}), change_Y_(change) {} protected: void ChangeY(const DataBuffer& input, DataBuffer* output, size_t offset, @@ -212,8 +208,11 @@ class TlsDheSkeChangeY : public TlsHandshakeFilter { class TlsDheSkeChangeYServer : public TlsDheSkeChangeY { public: - TlsDheSkeChangeYServer(ChangeYTo change, bool modify) - : TlsDheSkeChangeY(change), modify_(modify), p_() {} + TlsDheSkeChangeYServer(const std::shared_ptr<TlsAgent>& agent, + ChangeYTo change, bool modify) + : TlsDheSkeChangeY(agent, kTlsHandshakeServerKeyExchange, change), + modify_(modify), + p_() {} const DataBuffer& prime() const { return p_; } @@ -221,10 +220,6 @@ class TlsDheSkeChangeYServer : public TlsDheSkeChangeY { virtual PacketFilter::Action FilterHandshake( const TlsHandshakeFilter::HandshakeHeader& header, const DataBuffer& input, DataBuffer* output) override { - if (header.handshake_type() != kTlsHandshakeServerKeyExchange) { - return KEEP; - } - size_t offset = 2; // Read dh_p uint32_t dh_len = 0; @@ -252,18 +247,15 @@ class TlsDheSkeChangeYServer : public TlsDheSkeChangeY { class TlsDheSkeChangeYClient : public TlsDheSkeChangeY { public: TlsDheSkeChangeYClient( - ChangeYTo change, + const std::shared_ptr<TlsAgent>& agent, ChangeYTo change, std::shared_ptr<const TlsDheSkeChangeYServer> server_filter) - : TlsDheSkeChangeY(change), server_filter_(server_filter) {} + : TlsDheSkeChangeY(agent, kTlsHandshakeClientKeyExchange, change), + server_filter_(server_filter) {} protected: virtual PacketFilter::Action FilterHandshake( const TlsHandshakeFilter::HandshakeHeader& header, const DataBuffer& input, DataBuffer* output) override { - if (header.handshake_type() != kTlsHandshakeClientKeyExchange) { - return KEEP; - } - ChangeY(input, output, 0, server_filter_->prime()); return CHANGE; } @@ -289,12 +281,10 @@ class TlsDamageDHYTest TEST_P(TlsDamageDHYTest, DamageServerY) { EnableOnlyDheCiphers(); if (std::get<3>(GetParam())) { - EXPECT_EQ(SECSuccess, SSL_OptionSet(client_->ssl_fd(), - SSL_REQUIRE_DH_NAMED_GROUPS, PR_TRUE)); + client_->SetOption(SSL_REQUIRE_DH_NAMED_GROUPS, PR_TRUE); } TlsDheSkeChangeY::ChangeYTo change = std::get<2>(GetParam()); - server_->SetPacketFilter( - std::make_shared<TlsDheSkeChangeYServer>(change, true)); + MakeTlsFilter<TlsDheSkeChangeYServer>(server_, change, true); if (change == TlsDheSkeChangeY::kYZeroPad) { ExpectAlert(client_, kTlsAlertDecryptError); @@ -320,18 +310,15 @@ TEST_P(TlsDamageDHYTest, DamageServerY) { TEST_P(TlsDamageDHYTest, DamageClientY) { EnableOnlyDheCiphers(); if (std::get<3>(GetParam())) { - EXPECT_EQ(SECSuccess, SSL_OptionSet(client_->ssl_fd(), - SSL_REQUIRE_DH_NAMED_GROUPS, PR_TRUE)); + client_->SetOption(SSL_REQUIRE_DH_NAMED_GROUPS, PR_TRUE); } // The filter on the server is required to capture the prime. - auto server_filter = - std::make_shared<TlsDheSkeChangeYServer>(TlsDheSkeChangeY::kYZero, false); - server_->SetPacketFilter(server_filter); + auto server_filter = MakeTlsFilter<TlsDheSkeChangeYServer>( + server_, TlsDheSkeChangeY::kYZero, false); // The client filter does the damage. TlsDheSkeChangeY::ChangeYTo change = std::get<2>(GetParam()); - client_->SetPacketFilter( - std::make_shared<TlsDheSkeChangeYClient>(change, server_filter)); + MakeTlsFilter<TlsDheSkeChangeYClient>(client_, change, server_filter); if (change == TlsDheSkeChangeY::kYZeroPad) { ExpectAlert(server_, kTlsAlertDecryptError); @@ -370,13 +357,12 @@ INSTANTIATE_TEST_CASE_P( class TlsDheSkeMakePEven : public TlsHandshakeFilter { public: + TlsDheSkeMakePEven(const std::shared_ptr<TlsAgent>& agent) + : TlsHandshakeFilter(agent, {kTlsHandshakeServerKeyExchange}) {} + virtual PacketFilter::Action FilterHandshake( const TlsHandshakeFilter::HandshakeHeader& header, const DataBuffer& input, DataBuffer* output) { - if (header.handshake_type() != kTlsHandshakeServerKeyExchange) { - return KEEP; - } - // Find the end of dh_p uint32_t dh_len = 0; EXPECT_TRUE(input.Read(0, 2, &dh_len)); @@ -394,7 +380,7 @@ class TlsDheSkeMakePEven : public TlsHandshakeFilter { // Even without requiring named groups, an even value for p is bad news. TEST_P(TlsConnectGenericPre13, MakeDhePEven) { EnableOnlyDheCiphers(); - server_->SetPacketFilter(std::make_shared<TlsDheSkeMakePEven>()); + MakeTlsFilter<TlsDheSkeMakePEven>(server_); ConnectExpectAlert(client_, kTlsAlertIllegalParameter); @@ -404,13 +390,12 @@ TEST_P(TlsConnectGenericPre13, MakeDhePEven) { class TlsDheSkeZeroPadP : public TlsHandshakeFilter { public: + TlsDheSkeZeroPadP(const std::shared_ptr<TlsAgent>& agent) + : TlsHandshakeFilter(agent, {kTlsHandshakeServerKeyExchange}) {} + virtual PacketFilter::Action FilterHandshake( const TlsHandshakeFilter::HandshakeHeader& header, const DataBuffer& input, DataBuffer* output) { - if (header.handshake_type() != kTlsHandshakeServerKeyExchange) { - return KEEP; - } - *output = input; uint32_t dh_len = 0; EXPECT_TRUE(input.Read(0, 2, &dh_len)); @@ -425,7 +410,7 @@ class TlsDheSkeZeroPadP : public TlsHandshakeFilter { // Zero padding only causes signature failure. TEST_P(TlsConnectGenericPre13, PadDheP) { EnableOnlyDheCiphers(); - server_->SetPacketFilter(std::make_shared<TlsDheSkeZeroPadP>()); + MakeTlsFilter<TlsDheSkeZeroPadP>(server_); ConnectExpectAlert(client_, kTlsAlertDecryptError); @@ -445,8 +430,7 @@ TEST_P(TlsConnectGenericPre13, PadDheP) { // Note: This test case can take ages to generate the weak DH key. TEST_P(TlsConnectGenericPre13, WeakDHGroup) { EnableOnlyDheCiphers(); - EXPECT_EQ(SECSuccess, SSL_OptionSet(client_->ssl_fd(), - SSL_REQUIRE_DH_NAMED_GROUPS, PR_TRUE)); + client_->SetOption(SSL_REQUIRE_DH_NAMED_GROUPS, PR_TRUE); EXPECT_EQ(SECSuccess, SSL_EnableWeakDHEPrimeGroup(server_->ssl_fd(), PR_TRUE)); @@ -474,7 +458,7 @@ TEST_P(TlsConnectGenericPre13, NamedGroupMismatchPre13) { Connect(); CheckKeys(ssl_kea_dh, ssl_grp_ffdhe_custom, ssl_auth_rsa_sign, - ssl_sig_rsa_pss_sha256); + ssl_sig_rsa_pss_rsae_sha256); } // Same test but for TLS 1.3. This has to fail. @@ -496,8 +480,7 @@ TEST_P(TlsConnectTls13, NamedGroupMismatch13) { // custom group in contrast to the previous test. TEST_P(TlsConnectGenericPre13, RequireNamedGroupsMismatchPre13) { EnableOnlyDheCiphers(); - EXPECT_EQ(SECSuccess, SSL_OptionSet(client_->ssl_fd(), - SSL_REQUIRE_DH_NAMED_GROUPS, PR_TRUE)); + client_->SetOption(SSL_REQUIRE_DH_NAMED_GROUPS, PR_TRUE); static const std::vector<SSLNamedGroup> server_groups = {ssl_grp_ffdhe_3072}; static const std::vector<SSLNamedGroup> client_groups = {ssl_grp_ec_secp256r1, ssl_grp_ffdhe_2048}; @@ -519,14 +502,13 @@ TEST_P(TlsConnectGenericPre13, PreferredFfdhe) { Connect(); client_->CheckKEA(ssl_kea_dh, ssl_grp_ffdhe_3072, 3072); server_->CheckKEA(ssl_kea_dh, ssl_grp_ffdhe_3072, 3072); - client_->CheckAuthType(ssl_auth_rsa_sign, ssl_sig_rsa_pss_sha256); - server_->CheckAuthType(ssl_auth_rsa_sign, ssl_sig_rsa_pss_sha256); + client_->CheckAuthType(ssl_auth_rsa_sign, ssl_sig_rsa_pss_rsae_sha256); + server_->CheckAuthType(ssl_auth_rsa_sign, ssl_sig_rsa_pss_rsae_sha256); } TEST_P(TlsConnectGenericPre13, MismatchDHE) { EnableOnlyDheCiphers(); - EXPECT_EQ(SECSuccess, SSL_OptionSet(client_->ssl_fd(), - SSL_REQUIRE_DH_NAMED_GROUPS, PR_TRUE)); + client_->SetOption(SSL_REQUIRE_DH_NAMED_GROUPS, PR_TRUE); static const SSLDHEGroupType serverGroups[] = {ssl_ff_dhe_3072_group}; EXPECT_EQ(SECSuccess, SSL_DHEGroupPrefSet(server_->ssl_fd(), serverGroups, PR_ARRAY_SIZE(serverGroups))); @@ -544,37 +526,37 @@ TEST_P(TlsConnectTls13, ResumeFfdhe) { ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET); Connect(); SendReceive(); // Need to read so that we absorb the session ticket. - CheckKeys(ssl_kea_dh, ssl_auth_rsa_sign); + CheckKeys(ssl_kea_dh, ssl_grp_ffdhe_2048, ssl_auth_rsa_sign, + ssl_sig_rsa_pss_rsae_sha256); Reset(); ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET); EnableOnlyDheCiphers(); auto clientCapture = - std::make_shared<TlsExtensionCapture>(ssl_tls13_pre_shared_key_xtn); - client_->SetPacketFilter(clientCapture); + MakeTlsFilter<TlsExtensionCapture>(client_, ssl_tls13_pre_shared_key_xtn); auto serverCapture = - std::make_shared<TlsExtensionCapture>(ssl_tls13_pre_shared_key_xtn); - server_->SetPacketFilter(serverCapture); + MakeTlsFilter<TlsExtensionCapture>(server_, ssl_tls13_pre_shared_key_xtn); ExpectResumption(RESUME_TICKET); Connect(); - CheckKeys(ssl_kea_dh, ssl_grp_ffdhe_2048, ssl_auth_rsa_sign, ssl_sig_none); + CheckKeys(ssl_kea_dh, ssl_grp_ffdhe_2048, ssl_auth_rsa_sign, + ssl_sig_rsa_pss_rsae_sha256); ASSERT_LT(0UL, clientCapture->extension().len()); ASSERT_LT(0UL, serverCapture->extension().len()); } class TlsDheSkeChangeSignature : public TlsHandshakeFilter { public: - TlsDheSkeChangeSignature(uint16_t version, const uint8_t* data, size_t len) - : version_(version), data_(data), len_(len) {} + TlsDheSkeChangeSignature(const std::shared_ptr<TlsAgent>& agent, + uint16_t version, const uint8_t* data, size_t len) + : TlsHandshakeFilter(agent, {kTlsHandshakeServerKeyExchange}), + version_(version), + data_(data), + len_(len) {} protected: virtual PacketFilter::Action FilterHandshake(const HandshakeHeader& header, const DataBuffer& input, DataBuffer* output) { - if (header.handshake_type() != kTlsHandshakeServerKeyExchange) { - return KEEP; - } - TlsParser parser(input); EXPECT_TRUE(parser.SkipVariable(2)); // dh_p EXPECT_TRUE(parser.SkipVariable(2)); // dh_g @@ -615,8 +597,8 @@ TEST_P(TlsConnectGenericPre13, InvalidDERSignatureFfdhe) { const std::vector<SSLNamedGroup> client_groups = {ssl_grp_ffdhe_2048}; client_->ConfigNamedGroups(client_groups); - server_->SetPacketFilter(std::make_shared<TlsDheSkeChangeSignature>( - version_, kBogusDheSignature, sizeof(kBogusDheSignature))); + MakeTlsFilter<TlsDheSkeChangeSignature>(server_, version_, kBogusDheSignature, + sizeof(kBogusDheSignature)); ConnectExpectAlert(client_, kTlsAlertDecryptError); client_->CheckErrorCode(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE); diff --git a/security/nss/gtests/ssl_gtest/ssl_drop_unittest.cc b/security/nss/gtests/ssl_gtest/ssl_drop_unittest.cc index 3cc3b0e62..ee8906deb 100644 --- a/security/nss/gtests/ssl_gtest/ssl_drop_unittest.cc +++ b/security/nss/gtests/ssl_gtest/ssl_drop_unittest.cc @@ -6,6 +6,7 @@ #include "secerr.h" #include "ssl.h" +#include "sslexp.h" extern "C" { // This is not something that should make you happy. @@ -20,14 +21,14 @@ extern "C" { namespace nss_test { -TEST_P(TlsConnectDatagram, DropClientFirstFlightOnce) { - client_->SetPacketFilter(std::make_shared<SelectiveDropFilter>(0x1)); +TEST_P(TlsConnectDatagramPre13, DropClientFirstFlightOnce) { + client_->SetFilter(std::make_shared<SelectiveDropFilter>(0x1)); Connect(); SendReceive(); } -TEST_P(TlsConnectDatagram, DropServerFirstFlightOnce) { - server_->SetPacketFilter(std::make_shared<SelectiveDropFilter>(0x1)); +TEST_P(TlsConnectDatagramPre13, DropServerFirstFlightOnce) { + server_->SetFilter(std::make_shared<SelectiveDropFilter>(0x1)); Connect(); SendReceive(); } @@ -35,36 +36,770 @@ TEST_P(TlsConnectDatagram, DropServerFirstFlightOnce) { // This drops the first transmission from both the client and server of all // flights that they send. Note: In DTLS 1.3, the shorter handshake means that // this will also drop some application data, so we can't call SendReceive(). -TEST_P(TlsConnectDatagram, DropAllFirstTransmissions) { - client_->SetPacketFilter(std::make_shared<SelectiveDropFilter>(0x15)); - server_->SetPacketFilter(std::make_shared<SelectiveDropFilter>(0x5)); +TEST_P(TlsConnectDatagramPre13, DropAllFirstTransmissions) { + client_->SetFilter(std::make_shared<SelectiveDropFilter>(0x15)); + server_->SetFilter(std::make_shared<SelectiveDropFilter>(0x5)); Connect(); } // This drops the server's first flight three times. -TEST_P(TlsConnectDatagram, DropServerFirstFlightThrice) { - server_->SetPacketFilter(std::make_shared<SelectiveDropFilter>(0x7)); +TEST_P(TlsConnectDatagramPre13, DropServerFirstFlightThrice) { + server_->SetFilter(std::make_shared<SelectiveDropFilter>(0x7)); Connect(); } // This drops the client's second flight once -TEST_P(TlsConnectDatagram, DropClientSecondFlightOnce) { - client_->SetPacketFilter(std::make_shared<SelectiveDropFilter>(0x2)); +TEST_P(TlsConnectDatagramPre13, DropClientSecondFlightOnce) { + client_->SetFilter(std::make_shared<SelectiveDropFilter>(0x2)); Connect(); } // This drops the client's second flight three times. -TEST_P(TlsConnectDatagram, DropClientSecondFlightThrice) { - client_->SetPacketFilter(std::make_shared<SelectiveDropFilter>(0xe)); +TEST_P(TlsConnectDatagramPre13, DropClientSecondFlightThrice) { + client_->SetFilter(std::make_shared<SelectiveDropFilter>(0xe)); Connect(); } // This drops the server's second flight three times. -TEST_P(TlsConnectDatagram, DropServerSecondFlightThrice) { - server_->SetPacketFilter(std::make_shared<SelectiveDropFilter>(0xe)); +TEST_P(TlsConnectDatagramPre13, DropServerSecondFlightThrice) { + server_->SetFilter(std::make_shared<SelectiveDropFilter>(0xe)); Connect(); } +class TlsDropDatagram13 : public TlsConnectDatagram13 { + public: + TlsDropDatagram13() + : client_filters_(), + server_filters_(), + expected_client_acks_(0), + expected_server_acks_(1) {} + + void SetUp() override { + TlsConnectDatagram13::SetUp(); + ConfigureSessionCache(RESUME_NONE, RESUME_NONE); + SetFilters(); + } + + void SetFilters() { + EnsureTlsSetup(); + client_filters_.Init(client_); + server_filters_.Init(server_); + } + + void HandshakeAndAck(const std::shared_ptr<TlsAgent>& agent) { + agent->Handshake(); // Read flight. + ShiftDtlsTimers(); + agent->Handshake(); // Generate ACK. + } + + void ShrinkPostServerHelloMtu() { + // Abuse the custom extension mechanism to modify the MTU so that the + // Certificate message is split into two pieces. + ASSERT_EQ( + SECSuccess, + SSL_InstallExtensionHooks( + server_->ssl_fd(), 1, + [](PRFileDesc* fd, SSLHandshakeType message, PRUint8* data, + unsigned int* len, unsigned int maxLen, void* arg) -> PRBool { + SSLInt_SetMTU(fd, 500); // Splits the certificate. + return PR_FALSE; + }, + nullptr, + [](PRFileDesc* fd, SSLHandshakeType message, const PRUint8* data, + unsigned int len, SSLAlertDescription* alert, + void* arg) -> SECStatus { return SECSuccess; }, + nullptr)); + } + + protected: + class DropAckChain { + public: + DropAckChain() + : records_(nullptr), ack_(nullptr), drop_(nullptr), chain_(nullptr) {} + + void Init(const std::shared_ptr<TlsAgent>& agent) { + records_ = std::make_shared<TlsRecordRecorder>(agent); + ack_ = std::make_shared<TlsRecordRecorder>(agent, content_ack); + ack_->EnableDecryption(); + drop_ = std::make_shared<SelectiveRecordDropFilter>(agent, 0, false); + chain_ = std::make_shared<ChainedPacketFilter>( + ChainedPacketFilterInit({records_, ack_, drop_})); + agent->SetFilter(chain_); + } + + const TlsRecord& record(size_t i) const { return records_->record(i); } + + std::shared_ptr<TlsRecordRecorder> records_; + std::shared_ptr<TlsRecordRecorder> ack_; + std::shared_ptr<SelectiveRecordDropFilter> drop_; + std::shared_ptr<PacketFilter> chain_; + }; + + 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; + + EXPECT_EQ(acks.size() * 8, buf.len()); + if ((acks.size() * 8) != buf.len()) { + while (offset < buf.len()) { + uint64_t ack; + ASSERT_TRUE(buf.Read(offset, 8, &ack)); + offset += 8; + std::cerr << "Ack=0x" << std::hex << ack << std::dec << std::endl; + } + return; + } + + for (size_t i = 0; i < acks.size(); ++i) { + uint64_t a = acks[i]; + uint64_t ack; + ASSERT_TRUE(buf.Read(offset, 8, &ack)); + offset += 8; + if (a != ack) { + ADD_FAILURE() << "Wrong ack " << i << " expected=0x" << std::hex << a + << " got=0x" << ack << std::dec; + } + } + } + + void CheckedHandshakeSendReceive() { + Handshake(); + CheckPostHandshake(); + } + + void CheckPostHandshake() { + CheckConnected(); + SendReceive(); + EXPECT_EQ(expected_client_acks_, client_filters_.ack_->count()); + EXPECT_EQ(expected_server_acks_, server_filters_.ack_->count()); + } + + protected: + DropAckChain client_filters_; + DropAckChain server_filters_; + size_t expected_client_acks_; + size_t expected_server_acks_; +}; + +// All of these tests produce a minimum one ACK, from the server +// to the client upon receiving the client Finished. +// Dropping complete first and second flights does not produce +// ACKs +TEST_F(TlsDropDatagram13, DropClientFirstFlightOnce) { + client_filters_.drop_->Reset({0}); + StartConnect(); + client_->Handshake(); + server_->Handshake(); + CheckedHandshakeSendReceive(); + CheckAcks(server_filters_, 0, {0x0002000000000000ULL}); +} + +TEST_F(TlsDropDatagram13, DropServerFirstFlightOnce) { + server_filters_.drop_->Reset(0xff); + StartConnect(); + client_->Handshake(); + // Send the first flight, all dropped. + server_->Handshake(); + server_filters_.drop_->Disable(); + CheckedHandshakeSendReceive(); + CheckAcks(server_filters_, 0, {0x0002000000000000ULL}); +} + +// 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) { + server_filters_.drop_->Reset({0}); + StartConnect(); + client_->Handshake(); + server_->Handshake(); + Handshake(); + CheckedHandshakeSendReceive(); + CheckAcks(server_filters_, 0, {0x0002000000000000ULL}); +} + +// Dropping the second packet of the server's flight should +// produce an ACK. +TEST_F(TlsDropDatagram13, DropServerSecondRecordOnce) { + server_filters_.drop_->Reset({1}); + StartConnect(); + client_->Handshake(); + server_->Handshake(); + HandshakeAndAck(client_); + expected_client_acks_ = 1; + CheckedHandshakeSendReceive(); + CheckAcks(client_filters_, 0, {0}); // ServerHello + CheckAcks(server_filters_, 0, {0x0002000000000000ULL}); +} + +// Drop the server ACK and verify that the client retransmits +// the ClientHello. +TEST_F(TlsDropDatagram13, DropServerAckOnce) { + StartConnect(); + client_->Handshake(); + server_->Handshake(); + // At this point the server has sent it's first flight, + // so make it drop the ACK. + server_filters_.drop_->Reset({0}); + client_->Handshake(); // Send the client Finished. + server_->Handshake(); // Receive the Finished and send the ACK. + EXPECT_EQ(TlsAgent::STATE_CONNECTED, client_->state()); + EXPECT_EQ(TlsAgent::STATE_CONNECTED, server_->state()); + // Wait for the DTLS timeout to make sure we retransmit the + // Finished. + ShiftDtlsTimers(); + client_->Handshake(); // Retransmit the Finished. + server_->Handshake(); // Read the Finished and send an ACK. + uint8_t buf[1]; + PRInt32 rv = PR_Read(client_->ssl_fd(), buf, sizeof(buf)); + expected_server_acks_ = 2; + EXPECT_GT(0, rv); + EXPECT_EQ(PR_WOULD_BLOCK_ERROR, PORT_GetError()); + CheckPostHandshake(); + // There should be two copies of the finished ACK + CheckAcks(server_filters_, 0, {0x0002000000000000ULL}); + CheckAcks(server_filters_, 1, {0x0002000000000000ULL}); +} + +// Drop the client certificate verify. +TEST_F(TlsDropDatagram13, DropClientCertVerify) { + StartConnect(); + client_->SetupClientAuth(); + server_->RequestClientAuth(true); + client_->Handshake(); + server_->Handshake(); + // Have the client drop Cert Verify + client_filters_.drop_->Reset({1}); + expected_server_acks_ = 2; + CheckedHandshakeSendReceive(); + // Ack of the Cert. + CheckAcks(server_filters_, 0, {0x0002000000000000ULL}); + // Ack of the whole client handshake. + CheckAcks( + server_filters_, 1, + {0x0002000000000000ULL, // CH (we drop everything after this on client) + 0x0002000000000003ULL, // CT (2) + 0x0002000000000004ULL}); // FIN (2) +} + +// Shrink the MTU down so that certs get split and drop the first piece. +TEST_F(TlsDropDatagram13, DropFirstHalfOfServerCertificate) { + server_filters_.drop_->Reset({2}); + StartConnect(); + ShrinkPostServerHelloMtu(); + client_->Handshake(); + server_->Handshake(); + // Check that things got split. + EXPECT_EQ(6UL, + server_filters_.records_->count()); // SH, EE, CT1, CT2, CV, FIN + size_t ct1_size = server_filters_.record(2).buffer.len(); + server_filters_.records_->Clear(); + expected_client_acks_ = 1; + HandshakeAndAck(client_); + server_->Handshake(); // Retransmit + EXPECT_EQ(3UL, server_filters_.records_->count()); // CT2, CV, FIN + // Check that the first record is CT1 (which is identical to the same + // as the previous CT1). + EXPECT_EQ(ct1_size, server_filters_.record(0).buffer.len()); + CheckedHandshakeSendReceive(); + CheckAcks(client_filters_, 0, + {0, // SH + 0x0002000000000000ULL, // EE + 0x0002000000000002ULL}); // CT2 + CheckAcks(server_filters_, 0, {0x0002000000000000ULL}); +} + +// Shrink the MTU down so that certs get split and drop the second piece. +TEST_F(TlsDropDatagram13, DropSecondHalfOfServerCertificate) { + server_filters_.drop_->Reset({3}); + StartConnect(); + ShrinkPostServerHelloMtu(); + client_->Handshake(); + server_->Handshake(); + // Check that things got split. + EXPECT_EQ(6UL, + server_filters_.records_->count()); // SH, EE, CT1, CT2, CV, FIN + size_t ct1_size = server_filters_.record(3).buffer.len(); + server_filters_.records_->Clear(); + expected_client_acks_ = 1; + HandshakeAndAck(client_); + server_->Handshake(); // Retransmit + EXPECT_EQ(3UL, server_filters_.records_->count()); // CT1, CV, FIN + // Check that the first record is CT1 + EXPECT_EQ(ct1_size, server_filters_.record(0).buffer.len()); + CheckedHandshakeSendReceive(); + CheckAcks(client_filters_, 0, + { + 0, // SH + 0x0002000000000000ULL, // EE + 0x0002000000000001ULL, // CT1 + }); + CheckAcks(server_filters_, 0, {0x0002000000000000ULL}); +} + +// In this test, the Certificate message is sent four times, we drop all or part +// of the first three attempts: +// 1. Without fragmentation so that we can see how big it is - we drop that. +// 2. In two pieces - we drop half AND the resulting ACK. +// 3. In three pieces - we drop the middle piece. +// +// After that we let all the ACKs through and allow the handshake to complete +// without further interference. +// +// This allows us to test that ranges of handshake messages are sent correctly +// even when there are overlapping acknowledgments; that ACKs with duplicate or +// overlapping message ranges are handled properly; and that extra +// retransmissions are handled properly. +class TlsFragmentationAndRecoveryTest : public TlsDropDatagram13 { + public: + TlsFragmentationAndRecoveryTest() : cert_len_(0) {} + + protected: + void RunTest(size_t dropped_half) { + FirstFlightDropCertificate(); + + SecondAttemptDropHalf(dropped_half); + size_t dropped_half_size = server_record_len(dropped_half); + size_t second_flight_count = server_filters_.records_->count(); + + ThirdAttemptDropMiddle(); + size_t repaired_third_size = server_record_len((dropped_half == 0) ? 0 : 2); + size_t third_flight_count = server_filters_.records_->count(); + + AckAndCompleteRetransmission(); + size_t final_server_flight_count = server_filters_.records_->count(); + EXPECT_LE(3U, final_server_flight_count); // CT(sixth), CV, Fin + CheckSizeOfSixth(dropped_half_size, repaired_third_size); + + SendDelayedAck(); + // Same number of messages as the last flight. + EXPECT_EQ(final_server_flight_count, server_filters_.records_->count()); + // Double check that the Certificate size is still correct. + CheckSizeOfSixth(dropped_half_size, repaired_third_size); + + CompleteHandshake(final_server_flight_count); + + // This is the ACK for the first attempt to send a whole certificate. + std::vector<uint64_t> client_acks = { + 0, // SH + 0x0002000000000000ULL // EE + }; + CheckAcks(client_filters_, 0, client_acks); + // And from the second attempt for the half was kept (we delayed this ACK). + client_acks.push_back(0x0002000000000000ULL + second_flight_count + + ~dropped_half % 2); + CheckAcks(client_filters_, 1, client_acks); + // And the third attempt where the first and last thirds got through. + client_acks.push_back(0x0002000000000000ULL + second_flight_count + + third_flight_count - 1); + client_acks.push_back(0x0002000000000000ULL + second_flight_count + + third_flight_count + 1); + CheckAcks(client_filters_, 2, client_acks); + CheckAcks(server_filters_, 0, {0x0002000000000000ULL}); + } + + private: + void FirstFlightDropCertificate() { + StartConnect(); + client_->Handshake(); + + // Note: 1 << N is the Nth packet, starting from zero. + server_filters_.drop_->Reset(1 << 2); // Drop Cert0. + server_->Handshake(); + EXPECT_EQ(5U, server_filters_.records_->count()); // SH, EE, CT, CV, Fin + cert_len_ = server_filters_.records_->record(2).buffer.len(); + + HandshakeAndAck(client_); + EXPECT_EQ(2U, client_filters_.records_->count()); + } + + // Lower the MTU so that the server has to split the certificate in two + // pieces. The server resends Certificate (in two), plus CV and Fin. + void SecondAttemptDropHalf(size_t dropped_half) { + ASSERT_LE(0U, dropped_half); + ASSERT_GT(2U, dropped_half); + server_filters_.records_->Clear(); + server_filters_.drop_->Reset({dropped_half}); // Drop Cert1[half] + SplitServerMtu(2); + server_->Handshake(); + EXPECT_LE(4U, server_filters_.records_->count()); // CT x2, CV, Fin + + // Generate and capture the ACK from the client. + client_filters_.drop_->Reset({0}); + HandshakeAndAck(client_); + EXPECT_EQ(3U, client_filters_.records_->count()); + } + + // Lower the MTU again so that the server sends Certificate cut into three + // pieces. Drop the middle piece. + void ThirdAttemptDropMiddle() { + server_filters_.records_->Clear(); + server_filters_.drop_->Reset({1}); // Drop Cert2[1] (of 3) + SplitServerMtu(3); + // Because we dropped the client ACK, the server retransmits on a timer. + ShiftDtlsTimers(); + server_->Handshake(); + EXPECT_LE(5U, server_filters_.records_->count()); // CT x3, CV, Fin + } + + void AckAndCompleteRetransmission() { + // Generate ACKs. + HandshakeAndAck(client_); + // The server should send the final sixth of the certificate: the client has + // acknowledged the first half and the last third. Also send CV and Fin. + server_filters_.records_->Clear(); + server_->Handshake(); + } + + void CheckSizeOfSixth(size_t size_of_half, size_t size_of_third) { + // Work out if the final sixth is the right size. We get the records with + // overheads added, which obscures the length of the payload. We want to + // ensure that the server only sent the missing sixth of the Certificate. + // + // We captured |size_of_half + overhead| and |size_of_third + overhead| and + // want to calculate |size_of_third - size_of_third + overhead|. We can't + // calculate |overhead|, but it is is (currently) always a handshake message + // header, a content type, and an authentication tag: + static const size_t record_overhead = 12 + 1 + 16; + EXPECT_EQ(size_of_half - size_of_third + record_overhead, + server_filters_.records_->record(0).buffer.len()); + } + + void SendDelayedAck() { + // Send the ACK we held back. The reordered ACK doesn't add new + // information, + // but triggers an extra retransmission of the missing records again (even + // though the client has all that it needs). + client_->SendRecordDirect(client_filters_.records_->record(2)); + server_filters_.records_->Clear(); + server_->Handshake(); + } + + void CompleteHandshake(size_t extra_retransmissions) { + // All this messing around shouldn't cause a failure... + Handshake(); + // ...but it leaves a mess. Add an extra few calls to Handshake() for the + // client so that it absorbs the extra retransmissions. + for (size_t i = 0; i < extra_retransmissions; ++i) { + client_->Handshake(); + } + CheckConnected(); + } + + // Split the server MTU so that the Certificate is split into |count| pieces. + // The calculation doesn't need to be perfect as long as the Certificate + // message is split into the right number of pieces. + void SplitServerMtu(size_t count) { + // Set the MTU based on the formula: + // bare_size = cert_len_ - actual_overhead + // MTU = ceil(bare_size / count) + pessimistic_overhead + // + // actual_overhead is the amount of actual overhead on the record we + // captured, which is (note that our length doesn't include the header): + static const size_t actual_overhead = 12 + // handshake message header + 1 + // content type + 16; // authentication tag + size_t bare_size = cert_len_ - actual_overhead; + + // pessimistic_overhead is the amount of expansion that NSS assumes will be + // added to each handshake record. Right now, that is DTLS_MIN_FRAGMENT: + static const size_t pessimistic_overhead = + 12 + // handshake message header + 1 + // content type + 13 + // record header length + 64; // maximum record expansion: IV, MAC and block cipher expansion + + size_t mtu = (bare_size + count - 1) / count + pessimistic_overhead; + if (g_ssl_gtest_verbose) { + std::cerr << "server: set MTU to " << mtu << std::endl; + } + EXPECT_EQ(SECSuccess, SSLInt_SetMTU(server_->ssl_fd(), mtu)); + } + + size_t server_record_len(size_t index) const { + return server_filters_.records_->record(index).buffer.len(); + } + + size_t cert_len_; +}; + +TEST_F(TlsFragmentationAndRecoveryTest, DropFirstHalf) { RunTest(0); } + +TEST_F(TlsFragmentationAndRecoveryTest, DropSecondHalf) { RunTest(1); } + +TEST_F(TlsDropDatagram13, NoDropsDuringZeroRtt) { + SetupForZeroRtt(); + SetFilters(); + std::cerr << "Starting second handshake" << std::endl; + client_->Set0RttEnabled(true); + server_->Set0RttEnabled(true); + ExpectResumption(RESUME_TICKET); + ZeroRttSendReceive(true, true); + Handshake(); + ExpectEarlyDataAccepted(true); + CheckConnected(); + SendReceive(); + EXPECT_EQ(0U, client_filters_.ack_->count()); + CheckAcks(server_filters_, 0, + {0x0001000000000001ULL, // EOED + 0x0002000000000000ULL}); // Finished +} + +TEST_F(TlsDropDatagram13, DropEEDuringZeroRtt) { + SetupForZeroRtt(); + SetFilters(); + std::cerr << "Starting second handshake" << std::endl; + client_->Set0RttEnabled(true); + server_->Set0RttEnabled(true); + ExpectResumption(RESUME_TICKET); + server_filters_.drop_->Reset({1}); + ZeroRttSendReceive(true, true); + HandshakeAndAck(client_); + Handshake(); + ExpectEarlyDataAccepted(true); + CheckConnected(); + SendReceive(); + CheckAcks(client_filters_, 0, {0}); + CheckAcks(server_filters_, 0, + {0x0001000000000002ULL, // EOED + 0x0002000000000000ULL}); // Finished +} + +class TlsReorderDatagram13 : public TlsDropDatagram13 { + public: + TlsReorderDatagram13() {} + + // Send records from the records buffer in the given order. + void ReSend(TlsAgent::Role side, std::vector<size_t> indices) { + std::shared_ptr<TlsAgent> agent; + std::shared_ptr<TlsRecordRecorder> records; + + if (side == TlsAgent::CLIENT) { + agent = client_; + records = client_filters_.records_; + } else { + agent = server_; + records = server_filters_.records_; + } + + for (auto i : indices) { + agent->SendRecordDirect(records->record(i)); + } + } +}; + +// Reorder the server records so that EE comes at the end +// of the flight and will still produce an ACK. +TEST_F(TlsDropDatagram13, ReorderServerEE) { + server_filters_.drop_->Reset({1}); + StartConnect(); + client_->Handshake(); + server_->Handshake(); + // We dropped EE, now reinject. + server_->SendRecordDirect(server_filters_.record(1)); + expected_client_acks_ = 1; + HandshakeAndAck(client_); + CheckedHandshakeSendReceive(); + CheckAcks(client_filters_, 0, + { + 0, // SH + 0x0002000000000000, // EE + }); + CheckAcks(server_filters_, 0, {0x0002000000000000ULL}); +} + +// The client sends an out of order non-handshake message +// but with the handshake key. +class TlsSendCipherSpecCapturer { + public: + TlsSendCipherSpecCapturer(std::shared_ptr<TlsAgent>& agent) + : send_cipher_specs_() { + SSLInt_SetCipherSpecChangeFunc(agent->ssl_fd(), CipherSpecChanged, + (void*)this); + } + + std::shared_ptr<TlsCipherSpec> spec(size_t i) { + if (i >= send_cipher_specs_.size()) { + return nullptr; + } + return send_cipher_specs_[i]; + } + + private: + static void CipherSpecChanged(void* arg, PRBool sending, + ssl3CipherSpec* newSpec) { + if (!sending) { + return; + } + + auto self = static_cast<TlsSendCipherSpecCapturer*>(arg); + + auto spec = std::make_shared<TlsCipherSpec>(); + bool ret = spec->Init(SSLInt_CipherSpecToEpoch(newSpec), + SSLInt_CipherSpecToAlgorithm(newSpec), + SSLInt_CipherSpecToKey(newSpec), + SSLInt_CipherSpecToIv(newSpec)); + EXPECT_EQ(true, ret); + self->send_cipher_specs_.push_back(spec); + } + + std::vector<std::shared_ptr<TlsCipherSpec>> send_cipher_specs_; +}; + +TEST_F(TlsDropDatagram13, SendOutOfOrderAppWithHandshakeKey) { + StartConnect(); + TlsSendCipherSpecCapturer capturer(client_); + client_->Handshake(); + server_->Handshake(); + client_->Handshake(); + EXPECT_EQ(TlsAgent::STATE_CONNECTED, client_->state()); + server_->Handshake(); + EXPECT_EQ(TlsAgent::STATE_CONNECTED, server_->state()); + // After the client sends Finished, inject an app data record + // with the handshake key. This should produce an alert. + uint8_t buf[] = {'a', 'b', 'c'}; + 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)))); + + // Now have the server consume the bogus message. + server_->ExpectSendAlert(illegal_parameter, kTlsAlertFatal); + server_->Handshake(); + EXPECT_EQ(TlsAgent::STATE_ERROR, server_->state()); + EXPECT_EQ(SSL_ERROR_RX_UNKNOWN_RECORD_TYPE, PORT_GetError()); +} + +TEST_F(TlsDropDatagram13, SendOutOfOrderHsNonsenseWithHandshakeKey) { + StartConnect(); + TlsSendCipherSpecCapturer capturer(client_); + client_->Handshake(); + server_->Handshake(); + client_->Handshake(); + EXPECT_EQ(TlsAgent::STATE_CONNECTED, client_->state()); + server_->Handshake(); + EXPECT_EQ(TlsAgent::STATE_CONNECTED, server_->state()); + // Inject a new bogus handshake record, which the server responds + // to by just ACKing the original one (we ignore the contents). + uint8_t buf[] = {'a', 'b', 'c'}; + 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)))); + server_->Handshake(); + EXPECT_EQ(2UL, server_filters_.ack_->count()); + // The server acknowledges client Finished twice. + CheckAcks(server_filters_, 0, {0x0002000000000000ULL}); + CheckAcks(server_filters_, 1, {0x0002000000000000ULL}); +} + +// 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) { + StartConnect(); + ShrinkPostServerHelloMtu(); + client_->Handshake(); + // Drop the entire handshake flight so we can reorder. + server_filters_.drop_->Reset(0xff); + server_->Handshake(); + // Check that things got split. + EXPECT_EQ(6UL, + server_filters_.records_->count()); // CH, EE, CT1, CT2, CV, FIN + // Now re-send things in a different order. + ReSend(TlsAgent::SERVER, std::vector<size_t>{0, 1, 3, 2, 4, 5}); + // Clear. + server_filters_.drop_->Disable(); + server_filters_.records_->Clear(); + // Wait for client to send ACK. + ShiftDtlsTimers(); + CheckedHandshakeSendReceive(); + EXPECT_EQ(2UL, server_filters_.records_->count()); // ACK + Data + CheckAcks(server_filters_, 0, {0x0002000000000000ULL}); +} + +TEST_F(TlsReorderDatagram13, DataAfterEOEDDuringZeroRtt) { + SetupForZeroRtt(); + SetFilters(); + std::cerr << "Starting second handshake" << std::endl; + client_->Set0RttEnabled(true); + server_->Set0RttEnabled(true); + ExpectResumption(RESUME_TICKET); + // Send the client's first flight of zero RTT data. + ZeroRttSendReceive(true, true); + // Now send another client application data record but + // capture it. + client_filters_.records_->Clear(); + client_filters_.drop_->Reset(0xff); + const char* k0RttData = "123456"; + const PRInt32 k0RttDataLen = static_cast<PRInt32>(strlen(k0RttData)); + PRInt32 rv = + PR_Write(client_->ssl_fd(), k0RttData, k0RttDataLen); // 0-RTT write. + EXPECT_EQ(k0RttDataLen, rv); + EXPECT_EQ(1UL, client_filters_.records_->count()); // data + server_->Handshake(); + client_->Handshake(); + ExpectEarlyDataAccepted(true); + // The server still hasn't received anything at this point. + EXPECT_EQ(3UL, client_filters_.records_->count()); // data, EOED, FIN + EXPECT_EQ(TlsAgent::STATE_CONNECTED, client_->state()); + EXPECT_EQ(TlsAgent::STATE_CONNECTING, server_->state()); + // Now re-send the client's messages: EOED, data, FIN + ReSend(TlsAgent::CLIENT, std::vector<size_t>({1, 0, 2})); + server_->Handshake(); + CheckConnected(); + EXPECT_EQ(0U, client_filters_.ack_->count()); + // Acknowledgements for EOED and Finished. + CheckAcks(server_filters_, 0, {0x0001000000000002ULL, 0x0002000000000000ULL}); + uint8_t buf[8]; + rv = PR_Read(server_->ssl_fd(), buf, sizeof(buf)); + EXPECT_EQ(-1, rv); + EXPECT_EQ(PR_WOULD_BLOCK_ERROR, PORT_GetError()); +} + +TEST_F(TlsReorderDatagram13, DataAfterFinDuringZeroRtt) { + SetupForZeroRtt(); + SetFilters(); + std::cerr << "Starting second handshake" << std::endl; + client_->Set0RttEnabled(true); + server_->Set0RttEnabled(true); + ExpectResumption(RESUME_TICKET); + // Send the client's first flight of zero RTT data. + ZeroRttSendReceive(true, true); + // Now send another client application data record but + // capture it. + client_filters_.records_->Clear(); + client_filters_.drop_->Reset(0xff); + const char* k0RttData = "123456"; + const PRInt32 k0RttDataLen = static_cast<PRInt32>(strlen(k0RttData)); + PRInt32 rv = + PR_Write(client_->ssl_fd(), k0RttData, k0RttDataLen); // 0-RTT write. + EXPECT_EQ(k0RttDataLen, rv); + EXPECT_EQ(1UL, client_filters_.records_->count()); // data + server_->Handshake(); + client_->Handshake(); + ExpectEarlyDataAccepted(true); + // The server still hasn't received anything at this point. + EXPECT_EQ(3UL, client_filters_.records_->count()); // EOED, FIN, Data + EXPECT_EQ(TlsAgent::STATE_CONNECTED, client_->state()); + EXPECT_EQ(TlsAgent::STATE_CONNECTING, server_->state()); + // Now re-send the client's messages: EOED, FIN, Data + ReSend(TlsAgent::CLIENT, std::vector<size_t>({1, 2, 0})); + server_->Handshake(); + CheckConnected(); + EXPECT_EQ(0U, client_filters_.ack_->count()); + // Acknowledgements for EOED and Finished. + CheckAcks(server_filters_, 0, {0x0001000000000002ULL, 0x0002000000000000ULL}); + uint8_t buf[8]; + rv = PR_Read(server_->ssl_fd(), buf, sizeof(buf)); + EXPECT_EQ(-1, rv); + EXPECT_EQ(PR_WOULD_BLOCK_ERROR, PORT_GetError()); +} + static void GetCipherAndLimit(uint16_t version, uint16_t* cipher, uint64_t* limit = nullptr) { uint64_t l; @@ -111,7 +846,6 @@ TEST_P(TlsConnectDatagram12Plus, MissAWindow) { GetCipherAndLimit(version_, &cipher); server_->EnableSingleCipher(cipher); Connect(); - EXPECT_EQ(SECSuccess, SSLInt_AdvanceWriteSeqByAWindow(client_->ssl_fd(), 0)); SendReceive(); } @@ -129,5 +863,7 @@ TEST_P(TlsConnectDatagram12Plus, MissAWindowAndOne) { INSTANTIATE_TEST_CASE_P(Datagram12Plus, TlsConnectDatagram12Plus, TlsConnectTestBase::kTlsV12Plus); +INSTANTIATE_TEST_CASE_P(DatagramPre13, TlsConnectDatagramPre13, + TlsConnectTestBase::kTlsV11V12); } // 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 1e406b6c2..3c7cd2ecf 100644 --- a/security/nss/gtests/ssl_gtest/ssl_ecdh_unittest.cc +++ b/security/nss/gtests/ssl_gtest/ssl_ecdh_unittest.cc @@ -69,20 +69,19 @@ TEST_P(TlsConnectGeneric, ConnectEcdheP384Client) { server_->ConfigNamedGroups(groups); Connect(); CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp384r1, ssl_auth_rsa_sign, - ssl_sig_rsa_pss_sha256); + ssl_sig_rsa_pss_rsae_sha256); } // This causes a HelloRetryRequest in TLS 1.3. Earlier versions don't care. TEST_P(TlsConnectGeneric, ConnectEcdheP384Server) { EnsureTlsSetup(); - auto hrr_capture = std::make_shared<TlsInspectorRecordHandshakeMessage>( - kTlsHandshakeHelloRetryRequest); - server_->SetPacketFilter(hrr_capture); + auto hrr_capture = MakeTlsFilter<TlsHandshakeRecorder>( + server_, kTlsHandshakeHelloRetryRequest); const std::vector<SSLNamedGroup> groups = {ssl_grp_ec_secp384r1}; server_->ConfigNamedGroups(groups); Connect(); CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp384r1, ssl_auth_rsa_sign, - ssl_sig_rsa_pss_sha256); + ssl_sig_rsa_pss_rsae_sha256); EXPECT_EQ(version_ == SSL_LIBRARY_VERSION_TLS_1_3, hrr_capture->buffer().len() != 0); } @@ -112,7 +111,7 @@ TEST_P(TlsKeyExchangeTest, P384Priority) { Connect(); CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp384r1, ssl_auth_rsa_sign, - ssl_sig_rsa_pss_sha256); + ssl_sig_rsa_pss_rsae_sha256); std::vector<SSLNamedGroup> shares = {ssl_grp_ec_secp384r1}; CheckKEXDetails(groups, shares); @@ -129,7 +128,7 @@ TEST_P(TlsKeyExchangeTest, DuplicateGroupConfig) { Connect(); CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp384r1, ssl_auth_rsa_sign, - ssl_sig_rsa_pss_sha256); + ssl_sig_rsa_pss_rsae_sha256); std::vector<SSLNamedGroup> shares = {ssl_grp_ec_secp384r1}; std::vector<SSLNamedGroup> expectedGroups = {ssl_grp_ec_secp384r1, @@ -147,7 +146,7 @@ TEST_P(TlsKeyExchangeTest, P384PriorityDHEnabled) { Connect(); CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp384r1, ssl_auth_rsa_sign, - ssl_sig_rsa_pss_sha256); + ssl_sig_rsa_pss_rsae_sha256); if (version_ >= SSL_LIBRARY_VERSION_TLS_1_3) { std::vector<SSLNamedGroup> shares = {ssl_grp_ec_secp384r1}; @@ -172,7 +171,7 @@ TEST_P(TlsConnectGenericPre13, P384PriorityOnServer) { Connect(); CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp384r1, ssl_auth_rsa_sign, - ssl_sig_rsa_pss_sha256); + ssl_sig_rsa_pss_rsae_sha256); } TEST_P(TlsConnectGenericPre13, P384PriorityFromModelSocket) { @@ -188,12 +187,14 @@ TEST_P(TlsConnectGenericPre13, P384PriorityFromModelSocket) { Connect(); CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp384r1, ssl_auth_rsa_sign, - ssl_sig_rsa_pss_sha256); + ssl_sig_rsa_pss_rsae_sha256); } class TlsKeyExchangeGroupCapture : public TlsHandshakeFilter { public: - TlsKeyExchangeGroupCapture() : group_(ssl_grp_none) {} + TlsKeyExchangeGroupCapture(const std::shared_ptr<TlsAgent> &agent) + : TlsHandshakeFilter(agent, {kTlsHandshakeServerKeyExchange}), + group_(ssl_grp_none) {} SSLNamedGroup group() const { return group_; } @@ -201,10 +202,6 @@ class TlsKeyExchangeGroupCapture : public TlsHandshakeFilter { virtual PacketFilter::Action FilterHandshake(const HandshakeHeader &header, const DataBuffer &input, DataBuffer *output) { - if (header.handshake_type() != kTlsHandshakeServerKeyExchange) { - return KEEP; - } - uint32_t value = 0; EXPECT_TRUE(input.Read(0, 1, &value)); EXPECT_EQ(3U, value) << "curve type has to be 3"; @@ -223,10 +220,8 @@ class TlsKeyExchangeGroupCapture : public TlsHandshakeFilter { // P-256 is supported by the client (<= 1.2 only). TEST_P(TlsConnectGenericPre13, DropSupportedGroupExtensionP256) { EnsureTlsSetup(); - client_->SetPacketFilter( - std::make_shared<TlsExtensionDropper>(ssl_supported_groups_xtn)); - auto group_capture = std::make_shared<TlsKeyExchangeGroupCapture>(); - server_->SetPacketFilter(group_capture); + MakeTlsFilter<TlsExtensionDropper>(client_, ssl_supported_groups_xtn); + auto group_capture = MakeTlsFilter<TlsKeyExchangeGroupCapture>(server_); ConnectExpectAlert(server_, kTlsAlertDecryptError); client_->CheckErrorCode(SSL_ERROR_DECRYPT_ERROR_ALERT); @@ -238,8 +233,7 @@ TEST_P(TlsConnectGenericPre13, DropSupportedGroupExtensionP256) { // Supported groups is mandatory in TLS 1.3. TEST_P(TlsConnectTls13, DropSupportedGroupExtension) { EnsureTlsSetup(); - client_->SetPacketFilter( - std::make_shared<TlsExtensionDropper>(ssl_supported_groups_xtn)); + MakeTlsFilter<TlsExtensionDropper>(client_, ssl_supported_groups_xtn); ConnectExpectAlert(server_, kTlsAlertMissingExtension); client_->CheckErrorCode(SSL_ERROR_MISSING_EXTENSION_ALERT); server_->CheckErrorCode(SSL_ERROR_MISSING_SUPPORTED_GROUPS_EXTENSION); @@ -278,7 +272,7 @@ TEST_P(TlsConnectStreamPre13, ConfiguredGroupsRenegotiate) { Connect(); CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp256r1, ssl_auth_rsa_sign, - ssl_sig_rsa_pss_sha256); + ssl_sig_rsa_pss_rsae_sha256); CheckConnected(); // The renegotiation has to use the same preferences as the original session. @@ -286,7 +280,7 @@ TEST_P(TlsConnectStreamPre13, ConfiguredGroupsRenegotiate) { client_->StartRenegotiate(); Handshake(); CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp256r1, ssl_auth_rsa_sign, - ssl_sig_rsa_pss_sha256); + ssl_sig_rsa_pss_rsae_sha256); } TEST_P(TlsKeyExchangeTest, Curve25519) { @@ -320,7 +314,7 @@ TEST_P(TlsConnectGenericPre13, GroupPreferenceServerPriority) { Connect(); CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_rsa_sign, - ssl_sig_rsa_pss_sha256); + ssl_sig_rsa_pss_rsae_sha256); } #ifndef NSS_DISABLE_TLS_1_3 @@ -339,7 +333,7 @@ TEST_P(TlsKeyExchangeTest13, Curve25519P256EqualPriorityClient13) { Connect(); CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp256r1, ssl_auth_rsa_sign, - ssl_sig_rsa_pss_sha256); + ssl_sig_rsa_pss_rsae_sha256); const std::vector<SSLNamedGroup> shares = {ssl_grp_ec_secp256r1}; CheckKEXDetails(client_groups, shares); } @@ -359,7 +353,7 @@ TEST_P(TlsKeyExchangeTest13, Curve25519P256EqualPriorityServer13) { Connect(); CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_rsa_sign, - ssl_sig_rsa_pss_sha256); + ssl_sig_rsa_pss_rsae_sha256); const std::vector<SSLNamedGroup> shares = {ssl_grp_ec_curve25519}; CheckKEXDetails(client_groups, shares); } @@ -381,7 +375,7 @@ TEST_P(TlsKeyExchangeTest13, EqualPriorityTestRetryECServer13) { Connect(); CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp256r1, ssl_auth_rsa_sign, - ssl_sig_rsa_pss_sha256); + ssl_sig_rsa_pss_rsae_sha256); const std::vector<SSLNamedGroup> shares = {ssl_grp_ec_curve25519}; CheckKEXDetails(client_groups, shares, ssl_grp_ec_secp256r1); } @@ -403,7 +397,7 @@ TEST_P(TlsKeyExchangeTest13, NotEqualPriorityWithIntermediateGroup13) { Connect(); CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp256r1, ssl_auth_rsa_sign, - ssl_sig_rsa_pss_sha256); + ssl_sig_rsa_pss_rsae_sha256); const std::vector<SSLNamedGroup> shares = {ssl_grp_ec_curve25519}; CheckKEXDetails(client_groups, shares, ssl_grp_ec_secp256r1); } @@ -425,7 +419,7 @@ TEST_P(TlsKeyExchangeTest13, Connect(); CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp256r1, ssl_auth_rsa_sign, - ssl_sig_rsa_pss_sha256); + ssl_sig_rsa_pss_rsae_sha256); const std::vector<SSLNamedGroup> shares = {ssl_grp_ec_curve25519}; CheckKEXDetails(client_groups, shares, ssl_grp_ec_secp256r1); } @@ -447,7 +441,7 @@ TEST_P(TlsKeyExchangeTest13, Connect(); CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp256r1, ssl_auth_rsa_sign, - ssl_sig_rsa_pss_sha256); + ssl_sig_rsa_pss_rsae_sha256); const std::vector<SSLNamedGroup> shares = {ssl_grp_ec_curve25519}; CheckKEXDetails(client_groups, shares, ssl_grp_ec_secp256r1); } @@ -509,7 +503,7 @@ TEST_P(TlsKeyExchangeTest13, MultipleClientShares) { // The server would accept 25519 but its preferred group (P256) has to win. CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp256r1, ssl_auth_rsa_sign, - ssl_sig_rsa_pss_sha256); + ssl_sig_rsa_pss_rsae_sha256); const std::vector<SSLNamedGroup> shares = {ssl_grp_ec_curve25519, ssl_grp_ec_secp256r1}; CheckKEXDetails(client_groups, shares); @@ -518,16 +512,13 @@ TEST_P(TlsKeyExchangeTest13, MultipleClientShares) { // Replace the point in the client key exchange message with an empty one class ECCClientKEXFilter : public TlsHandshakeFilter { public: - ECCClientKEXFilter() {} + ECCClientKEXFilter(const std::shared_ptr<TlsAgent> &client) + : TlsHandshakeFilter(client, {kTlsHandshakeClientKeyExchange}) {} protected: virtual PacketFilter::Action FilterHandshake(const HandshakeHeader &header, const DataBuffer &input, DataBuffer *output) { - if (header.handshake_type() != kTlsHandshakeClientKeyExchange) { - return KEEP; - } - // Replace the client key exchange message with an empty point output->Allocate(1); output->Write(0, 0U, 1); // set point length 0 @@ -538,20 +529,17 @@ class ECCClientKEXFilter : public TlsHandshakeFilter { // Replace the point in the server key exchange message with an empty one class ECCServerKEXFilter : public TlsHandshakeFilter { public: - ECCServerKEXFilter() {} + ECCServerKEXFilter(const std::shared_ptr<TlsAgent> &server) + : TlsHandshakeFilter(server, {kTlsHandshakeServerKeyExchange}) {} protected: virtual PacketFilter::Action FilterHandshake(const HandshakeHeader &header, const DataBuffer &input, DataBuffer *output) { - if (header.handshake_type() != kTlsHandshakeServerKeyExchange) { - return KEEP; - } - // Replace the server key exchange message with an empty point output->Allocate(4); output->Write(0, 3U, 1); // named curve - uint32_t curve; + uint32_t curve = 0; EXPECT_TRUE(input.Read(1, 2, &curve)); // get curve id output->Write(1, curve, 2); // write curve id output->Write(3, 0U, 1); // point length 0 @@ -560,15 +548,13 @@ class ECCServerKEXFilter : public TlsHandshakeFilter { }; TEST_P(TlsConnectGenericPre13, ConnectECDHEmptyServerPoint) { - // add packet filter - server_->SetPacketFilter(std::make_shared<ECCServerKEXFilter>()); + MakeTlsFilter<ECCServerKEXFilter>(server_); ConnectExpectAlert(client_, kTlsAlertIllegalParameter); client_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_SERVER_KEY_EXCH); } TEST_P(TlsConnectGenericPre13, ConnectECDHEmptyClientPoint) { - // add packet filter - client_->SetPacketFilter(std::make_shared<ECCClientKEXFilter>()); + MakeTlsFilter<ECCClientKEXFilter>(client_); ConnectExpectAlert(server_, kTlsAlertIllegalParameter); server_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_CLIENT_KEY_EXCH); } diff --git a/security/nss/gtests/ssl_gtest/ssl_exporter_unittest.cc b/security/nss/gtests/ssl_gtest/ssl_exporter_unittest.cc index be407b42e..c42883eb7 100644 --- a/security/nss/gtests/ssl_gtest/ssl_exporter_unittest.cc +++ b/security/nss/gtests/ssl_gtest/ssl_exporter_unittest.cc @@ -118,7 +118,6 @@ int32_t RegularExporterShouldFail(TlsAgent* agent, const SECItem* srvNameArr, TEST_P(TlsConnectTls13, EarlyExporter) { SetupForZeroRtt(); - ExpectAlert(client_, kTlsAlertEndOfEarlyData); client_->Set0RttEnabled(true); server_->Set0RttEnabled(true); ExpectResumption(RESUME_TICKET); diff --git a/security/nss/gtests/ssl_gtest/ssl_extension_unittest.cc b/security/nss/gtests/ssl_gtest/ssl_extension_unittest.cc index d15139419..0453dabdb 100644 --- a/security/nss/gtests/ssl_gtest/ssl_extension_unittest.cc +++ b/security/nss/gtests/ssl_gtest/ssl_extension_unittest.cc @@ -19,8 +19,9 @@ namespace nss_test { class TlsExtensionTruncator : public TlsExtensionFilter { public: - TlsExtensionTruncator(uint16_t extension, size_t length) - : extension_(extension), length_(length) {} + TlsExtensionTruncator(const std::shared_ptr<TlsAgent>& agent, + uint16_t extension, size_t length) + : TlsExtensionFilter(agent), extension_(extension), length_(length) {} virtual PacketFilter::Action FilterExtension(uint16_t extension_type, const DataBuffer& input, DataBuffer* output) { @@ -42,8 +43,9 @@ class TlsExtensionTruncator : public TlsExtensionFilter { class TlsExtensionDamager : public TlsExtensionFilter { public: - TlsExtensionDamager(uint16_t extension, size_t index) - : extension_(extension), index_(index) {} + TlsExtensionDamager(const std::shared_ptr<TlsAgent>& agent, + uint16_t extension, size_t index) + : TlsExtensionFilter(agent), extension_(extension), index_(index) {} virtual PacketFilter::Action FilterExtension(uint16_t extension_type, const DataBuffer& input, DataBuffer* output) { @@ -61,60 +63,17 @@ class TlsExtensionDamager : public TlsExtensionFilter { size_t index_; }; -class TlsExtensionInjector : public TlsHandshakeFilter { - public: - TlsExtensionInjector(uint16_t ext, DataBuffer& data) - : extension_(ext), data_(data) {} - - virtual PacketFilter::Action FilterHandshake(const HandshakeHeader& header, - const DataBuffer& input, - DataBuffer* output) { - TlsParser parser(input); - if (!TlsExtensionFilter::FindExtensions(&parser, header)) { - return KEEP; - } - size_t offset = parser.consumed(); - - *output = input; - - // Increase the size of the extensions. - uint16_t ext_len; - memcpy(&ext_len, output->data() + offset, sizeof(ext_len)); - ext_len = htons(ntohs(ext_len) + data_.len() + 4); - memcpy(output->data() + offset, &ext_len, sizeof(ext_len)); - - // Insert the extension type and length. - DataBuffer type_length; - type_length.Allocate(4); - type_length.Write(0, extension_, 2); - type_length.Write(2, data_.len(), 2); - output->Splice(type_length, offset + 2); - - // Insert the payload. - if (data_.len() > 0) { - output->Splice(data_, offset + 6); - } - - return CHANGE; - } - - private: - const uint16_t extension_; - const DataBuffer data_; -}; - class TlsExtensionAppender : public TlsHandshakeFilter { public: - TlsExtensionAppender(uint8_t handshake_type, uint16_t ext, DataBuffer& data) - : handshake_type_(handshake_type), extension_(ext), data_(data) {} + TlsExtensionAppender(const std::shared_ptr<TlsAgent>& agent, + uint8_t handshake_type, uint16_t ext, DataBuffer& data) + : TlsHandshakeFilter(agent, {handshake_type}), + extension_(ext), + data_(data) {} virtual PacketFilter::Action FilterHandshake(const HandshakeHeader& header, const DataBuffer& input, DataBuffer* output) { - if (header.handshake_type() != handshake_type_) { - return KEEP; - } - TlsParser parser(input); if (!TlsExtensionFilter::FindExtensions(&parser, header)) { return KEEP; @@ -159,7 +118,6 @@ class TlsExtensionAppender : public TlsHandshakeFilter { return true; } - const uint8_t handshake_type_; const uint16_t extension_; const DataBuffer data_; }; @@ -171,13 +129,13 @@ class TlsExtensionTestBase : public TlsConnectTestBase { void ClientHelloErrorTest(std::shared_ptr<PacketFilter> filter, uint8_t desc = kTlsAlertDecodeError) { - client_->SetPacketFilter(filter); + client_->SetFilter(filter); ConnectExpectAlert(server_, desc); } void ServerHelloErrorTest(std::shared_ptr<PacketFilter> filter, uint8_t desc = kTlsAlertDecodeError) { - server_->SetPacketFilter(filter); + server_->SetFilter(filter); ConnectExpectAlert(client_, desc); } @@ -200,11 +158,10 @@ class TlsExtensionTestBase : public TlsConnectTestBase { client_->ConfigNamedGroups(client_groups); server_->ConfigNamedGroups(server_groups); EnsureTlsSetup(); - client_->StartConnect(); - server_->StartConnect(); + StartConnect(); client_->Handshake(); // Send ClientHello server_->Handshake(); // Send HRR. - client_->SetPacketFilter(std::make_shared<TlsExtensionDropper>(type)); + MakeTlsFilter<TlsExtensionDropper>(client_, type); Handshake(); client_->CheckErrorCode(client_error); server_->CheckErrorCode(server_error); @@ -245,8 +202,8 @@ class TlsExtensionTest13 void ConnectWithBogusVersionList(const uint8_t* buf, size_t len) { DataBuffer versions_buf(buf, len); - client_->SetPacketFilter(std::make_shared<TlsExtensionReplacer>( - ssl_tls13_supported_versions_xtn, versions_buf)); + MakeTlsFilter<TlsExtensionReplacer>( + client_, ssl_tls13_supported_versions_xtn, versions_buf); ConnectExpectAlert(server_, kTlsAlertIllegalParameter); client_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT); server_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO); @@ -257,8 +214,8 @@ class TlsExtensionTest13 size_t index = versions_buf.Write(0, 2, 1); versions_buf.Write(index, version, 2); - client_->SetPacketFilter(std::make_shared<TlsExtensionReplacer>( - ssl_tls13_supported_versions_xtn, versions_buf)); + MakeTlsFilter<TlsExtensionReplacer>( + client_, ssl_tls13_supported_versions_xtn, versions_buf); ConnectExpectFail(); } }; @@ -289,26 +246,26 @@ class TlsExtensionTestPre13 : public TlsExtensionTestBase, TEST_P(TlsExtensionTestGeneric, DamageSniLength) { ClientHelloErrorTest( - std::make_shared<TlsExtensionDamager>(ssl_server_name_xtn, 1)); + std::make_shared<TlsExtensionDamager>(client_, ssl_server_name_xtn, 1)); } TEST_P(TlsExtensionTestGeneric, DamageSniHostLength) { ClientHelloErrorTest( - std::make_shared<TlsExtensionDamager>(ssl_server_name_xtn, 4)); + std::make_shared<TlsExtensionDamager>(client_, ssl_server_name_xtn, 4)); } TEST_P(TlsExtensionTestGeneric, TruncateSni) { ClientHelloErrorTest( - std::make_shared<TlsExtensionTruncator>(ssl_server_name_xtn, 7)); + std::make_shared<TlsExtensionTruncator>(client_, ssl_server_name_xtn, 7)); } // A valid extension that appears twice will be reported as unsupported. TEST_P(TlsExtensionTestGeneric, RepeatSni) { DataBuffer extension; InitSimpleSni(&extension); - ClientHelloErrorTest( - std::make_shared<TlsExtensionInjector>(ssl_server_name_xtn, extension), - kTlsAlertIllegalParameter); + ClientHelloErrorTest(std::make_shared<TlsExtensionInjector>( + client_, ssl_server_name_xtn, extension), + kTlsAlertIllegalParameter); } // An SNI entry with zero length is considered invalid (strangely, not if it is @@ -320,23 +277,23 @@ TEST_P(TlsExtensionTestGeneric, BadSni) { extension.Allocate(simple.len() + 3); extension.Write(0, static_cast<uint32_t>(0), 3); extension.Write(3, simple); - ClientHelloErrorTest( - std::make_shared<TlsExtensionReplacer>(ssl_server_name_xtn, extension)); + ClientHelloErrorTest(std::make_shared<TlsExtensionReplacer>( + client_, ssl_server_name_xtn, extension)); } TEST_P(TlsExtensionTestGeneric, EmptySni) { DataBuffer extension; extension.Allocate(2); extension.Write(0, static_cast<uint32_t>(0), 2); - ClientHelloErrorTest( - std::make_shared<TlsExtensionReplacer>(ssl_server_name_xtn, extension)); + ClientHelloErrorTest(std::make_shared<TlsExtensionReplacer>( + client_, ssl_server_name_xtn, extension)); } TEST_P(TlsExtensionTestGeneric, EmptyAlpnExtension) { EnableAlpn(); DataBuffer extension; ClientHelloErrorTest(std::make_shared<TlsExtensionReplacer>( - ssl_app_layer_protocol_xtn, extension), + client_, ssl_app_layer_protocol_xtn, extension), kTlsAlertIllegalParameter); } @@ -347,21 +304,21 @@ TEST_P(TlsExtensionTestGeneric, EmptyAlpnList) { const uint8_t val[] = {0x00, 0x00}; DataBuffer extension(val, sizeof(val)); ClientHelloErrorTest(std::make_shared<TlsExtensionReplacer>( - ssl_app_layer_protocol_xtn, extension), + client_, ssl_app_layer_protocol_xtn, extension), kTlsAlertNoApplicationProtocol); } TEST_P(TlsExtensionTestGeneric, OneByteAlpn) { EnableAlpn(); - ClientHelloErrorTest( - std::make_shared<TlsExtensionTruncator>(ssl_app_layer_protocol_xtn, 1)); + ClientHelloErrorTest(std::make_shared<TlsExtensionTruncator>( + client_, ssl_app_layer_protocol_xtn, 1)); } TEST_P(TlsExtensionTestGeneric, AlpnMissingValue) { EnableAlpn(); // This will leave the length of the second entry, but no value. - ClientHelloErrorTest( - std::make_shared<TlsExtensionTruncator>(ssl_app_layer_protocol_xtn, 5)); + ClientHelloErrorTest(std::make_shared<TlsExtensionTruncator>( + client_, ssl_app_layer_protocol_xtn, 5)); } TEST_P(TlsExtensionTestGeneric, AlpnZeroLength) { @@ -369,7 +326,7 @@ TEST_P(TlsExtensionTestGeneric, AlpnZeroLength) { const uint8_t val[] = {0x01, 0x61, 0x00}; DataBuffer extension(val, sizeof(val)); ClientHelloErrorTest(std::make_shared<TlsExtensionReplacer>( - ssl_app_layer_protocol_xtn, extension)); + client_, ssl_app_layer_protocol_xtn, extension)); } TEST_P(TlsExtensionTestGeneric, AlpnMismatch) { @@ -388,7 +345,7 @@ TEST_P(TlsExtensionTestPre13, AlpnReturnedEmptyList) { const uint8_t val[] = {0x00, 0x00}; DataBuffer extension(val, sizeof(val)); ServerHelloErrorTest(std::make_shared<TlsExtensionReplacer>( - ssl_app_layer_protocol_xtn, extension)); + server_, ssl_app_layer_protocol_xtn, extension)); } TEST_P(TlsExtensionTestPre13, AlpnReturnedEmptyName) { @@ -396,7 +353,7 @@ TEST_P(TlsExtensionTestPre13, AlpnReturnedEmptyName) { const uint8_t val[] = {0x00, 0x01, 0x00}; DataBuffer extension(val, sizeof(val)); ServerHelloErrorTest(std::make_shared<TlsExtensionReplacer>( - ssl_app_layer_protocol_xtn, extension)); + server_, ssl_app_layer_protocol_xtn, extension)); } TEST_P(TlsExtensionTestPre13, AlpnReturnedListTrailingData) { @@ -404,7 +361,7 @@ TEST_P(TlsExtensionTestPre13, AlpnReturnedListTrailingData) { const uint8_t val[] = {0x00, 0x02, 0x01, 0x61, 0x00}; DataBuffer extension(val, sizeof(val)); ServerHelloErrorTest(std::make_shared<TlsExtensionReplacer>( - ssl_app_layer_protocol_xtn, extension)); + server_, ssl_app_layer_protocol_xtn, extension)); } TEST_P(TlsExtensionTestPre13, AlpnReturnedExtraEntry) { @@ -412,7 +369,7 @@ TEST_P(TlsExtensionTestPre13, AlpnReturnedExtraEntry) { const uint8_t val[] = {0x00, 0x04, 0x01, 0x61, 0x01, 0x62}; DataBuffer extension(val, sizeof(val)); ServerHelloErrorTest(std::make_shared<TlsExtensionReplacer>( - ssl_app_layer_protocol_xtn, extension)); + server_, ssl_app_layer_protocol_xtn, extension)); } TEST_P(TlsExtensionTestPre13, AlpnReturnedBadListLength) { @@ -420,7 +377,7 @@ TEST_P(TlsExtensionTestPre13, AlpnReturnedBadListLength) { const uint8_t val[] = {0x00, 0x99, 0x01, 0x61, 0x00}; DataBuffer extension(val, sizeof(val)); ServerHelloErrorTest(std::make_shared<TlsExtensionReplacer>( - ssl_app_layer_protocol_xtn, extension)); + server_, ssl_app_layer_protocol_xtn, extension)); } TEST_P(TlsExtensionTestPre13, AlpnReturnedBadNameLength) { @@ -428,7 +385,7 @@ TEST_P(TlsExtensionTestPre13, AlpnReturnedBadNameLength) { const uint8_t val[] = {0x00, 0x02, 0x99, 0x61}; DataBuffer extension(val, sizeof(val)); ServerHelloErrorTest(std::make_shared<TlsExtensionReplacer>( - ssl_app_layer_protocol_xtn, extension)); + server_, ssl_app_layer_protocol_xtn, extension)); } TEST_P(TlsExtensionTestPre13, AlpnReturnedUnknownName) { @@ -436,55 +393,64 @@ TEST_P(TlsExtensionTestPre13, AlpnReturnedUnknownName) { const uint8_t val[] = {0x00, 0x02, 0x01, 0x67}; DataBuffer extension(val, sizeof(val)); ServerHelloErrorTest(std::make_shared<TlsExtensionReplacer>( - ssl_app_layer_protocol_xtn, extension), + server_, ssl_app_layer_protocol_xtn, extension), kTlsAlertIllegalParameter); } TEST_P(TlsExtensionTestDtls, SrtpShort) { EnableSrtp(); ClientHelloErrorTest( - std::make_shared<TlsExtensionTruncator>(ssl_use_srtp_xtn, 3)); + std::make_shared<TlsExtensionTruncator>(client_, ssl_use_srtp_xtn, 3)); } TEST_P(TlsExtensionTestDtls, SrtpOdd) { EnableSrtp(); const uint8_t val[] = {0x00, 0x01, 0xff, 0x00}; DataBuffer extension(val, sizeof(val)); - ClientHelloErrorTest( - std::make_shared<TlsExtensionReplacer>(ssl_use_srtp_xtn, extension)); + ClientHelloErrorTest(std::make_shared<TlsExtensionReplacer>( + client_, ssl_use_srtp_xtn, extension)); } TEST_P(TlsExtensionTest12Plus, SignatureAlgorithmsBadLength) { const uint8_t val[] = {0x00}; DataBuffer extension(val, sizeof(val)); ClientHelloErrorTest(std::make_shared<TlsExtensionReplacer>( - ssl_signature_algorithms_xtn, extension)); + client_, ssl_signature_algorithms_xtn, extension)); } TEST_P(TlsExtensionTest12Plus, SignatureAlgorithmsTrailingData) { const uint8_t val[] = {0x00, 0x02, 0x04, 0x01, 0x00}; // sha-256, rsa DataBuffer extension(val, sizeof(val)); ClientHelloErrorTest(std::make_shared<TlsExtensionReplacer>( - ssl_signature_algorithms_xtn, extension)); + client_, ssl_signature_algorithms_xtn, extension)); } TEST_P(TlsExtensionTest12Plus, SignatureAlgorithmsEmpty) { const uint8_t val[] = {0x00, 0x00}; DataBuffer extension(val, sizeof(val)); ClientHelloErrorTest(std::make_shared<TlsExtensionReplacer>( - ssl_signature_algorithms_xtn, extension)); + client_, ssl_signature_algorithms_xtn, extension), + kTlsAlertHandshakeFailure); +} + +TEST_P(TlsExtensionTest12Plus, SignatureAlgorithmsNoOverlap) { + const uint8_t val[] = {0x00, 0x02, 0xff, 0xff}; + DataBuffer extension(val, sizeof(val)); + ClientHelloErrorTest(std::make_shared<TlsExtensionReplacer>( + client_, ssl_signature_algorithms_xtn, extension), + kTlsAlertHandshakeFailure); } TEST_P(TlsExtensionTest12Plus, SignatureAlgorithmsOddLength) { const uint8_t val[] = {0x00, 0x01, 0x04}; DataBuffer extension(val, sizeof(val)); ClientHelloErrorTest(std::make_shared<TlsExtensionReplacer>( - ssl_signature_algorithms_xtn, extension)); + client_, ssl_signature_algorithms_xtn, extension)); } TEST_P(TlsExtensionTestGeneric, NoSupportedGroups) { ClientHelloErrorTest( - std::make_shared<TlsExtensionDropper>(ssl_supported_groups_xtn), + std::make_shared<TlsExtensionDropper>(client_, ssl_supported_groups_xtn), version_ < SSL_LIBRARY_VERSION_TLS_1_3 ? kTlsAlertDecryptError : kTlsAlertMissingExtension); } @@ -493,75 +459,74 @@ TEST_P(TlsExtensionTestGeneric, SupportedCurvesShort) { const uint8_t val[] = {0x00, 0x01, 0x00}; DataBuffer extension(val, sizeof(val)); ClientHelloErrorTest(std::make_shared<TlsExtensionReplacer>( - ssl_elliptic_curves_xtn, extension)); + client_, ssl_elliptic_curves_xtn, extension)); } TEST_P(TlsExtensionTestGeneric, SupportedCurvesBadLength) { const uint8_t val[] = {0x09, 0x99, 0x00, 0x00}; DataBuffer extension(val, sizeof(val)); ClientHelloErrorTest(std::make_shared<TlsExtensionReplacer>( - ssl_elliptic_curves_xtn, extension)); + client_, ssl_elliptic_curves_xtn, extension)); } TEST_P(TlsExtensionTestGeneric, SupportedCurvesTrailingData) { const uint8_t val[] = {0x00, 0x02, 0x00, 0x00, 0x00}; DataBuffer extension(val, sizeof(val)); ClientHelloErrorTest(std::make_shared<TlsExtensionReplacer>( - ssl_elliptic_curves_xtn, extension)); + client_, ssl_elliptic_curves_xtn, extension)); } TEST_P(TlsExtensionTestPre13, SupportedPointsEmpty) { const uint8_t val[] = {0x00}; DataBuffer extension(val, sizeof(val)); ClientHelloErrorTest(std::make_shared<TlsExtensionReplacer>( - ssl_ec_point_formats_xtn, extension)); + client_, ssl_ec_point_formats_xtn, extension)); } TEST_P(TlsExtensionTestPre13, SupportedPointsBadLength) { const uint8_t val[] = {0x99, 0x00, 0x00}; DataBuffer extension(val, sizeof(val)); ClientHelloErrorTest(std::make_shared<TlsExtensionReplacer>( - ssl_ec_point_formats_xtn, extension)); + client_, ssl_ec_point_formats_xtn, extension)); } TEST_P(TlsExtensionTestPre13, SupportedPointsTrailingData) { const uint8_t val[] = {0x01, 0x00, 0x00}; DataBuffer extension(val, sizeof(val)); ClientHelloErrorTest(std::make_shared<TlsExtensionReplacer>( - ssl_ec_point_formats_xtn, extension)); + client_, ssl_ec_point_formats_xtn, extension)); } TEST_P(TlsExtensionTestPre13, RenegotiationInfoBadLength) { const uint8_t val[] = {0x99}; DataBuffer extension(val, sizeof(val)); ClientHelloErrorTest(std::make_shared<TlsExtensionReplacer>( - ssl_renegotiation_info_xtn, extension)); + client_, ssl_renegotiation_info_xtn, extension)); } TEST_P(TlsExtensionTestPre13, RenegotiationInfoMismatch) { const uint8_t val[] = {0x01, 0x00}; DataBuffer extension(val, sizeof(val)); ClientHelloErrorTest(std::make_shared<TlsExtensionReplacer>( - ssl_renegotiation_info_xtn, extension)); + client_, ssl_renegotiation_info_xtn, extension)); } // The extension has to contain a length. TEST_P(TlsExtensionTestPre13, RenegotiationInfoExtensionEmpty) { DataBuffer extension; ClientHelloErrorTest(std::make_shared<TlsExtensionReplacer>( - ssl_renegotiation_info_xtn, extension)); + client_, ssl_renegotiation_info_xtn, extension)); } // This only works on TLS 1.2, since it relies on static RSA; otherwise libssl // picks the wrong cipher suite. TEST_P(TlsExtensionTest12, SignatureAlgorithmConfiguration) { - const SSLSignatureScheme schemes[] = {ssl_sig_rsa_pss_sha512, - ssl_sig_rsa_pss_sha384}; + const SSLSignatureScheme schemes[] = {ssl_sig_rsa_pss_rsae_sha512, + ssl_sig_rsa_pss_rsae_sha384}; auto capture = - std::make_shared<TlsExtensionCapture>(ssl_signature_algorithms_xtn); + MakeTlsFilter<TlsExtensionCapture>(client_, ssl_signature_algorithms_xtn); client_->SetSignatureSchemes(schemes, PR_ARRAY_SIZE(schemes)); - client_->SetPacketFilter(capture); EnableOnlyStaticRsaCiphers(); Connect(); @@ -579,9 +544,9 @@ TEST_P(TlsExtensionTest12, SignatureAlgorithmConfiguration) { // Temporary test to verify that we choke on an empty ClientKeyShare. // This test will fail when we implement HelloRetryRequest. TEST_P(TlsExtensionTest13, EmptyClientKeyShare) { - ClientHelloErrorTest( - std::make_shared<TlsExtensionTruncator>(ssl_tls13_key_share_xtn, 2), - kTlsAlertHandshakeFailure); + ClientHelloErrorTest(std::make_shared<TlsExtensionTruncator>( + client_, ssl_tls13_key_share_xtn, 2), + kTlsAlertHandshakeFailure); } // These tests only work in stream mode because the client sends a @@ -590,8 +555,7 @@ TEST_P(TlsExtensionTest13, EmptyClientKeyShare) { // packet gets dropped. TEST_F(TlsExtensionTest13Stream, DropServerKeyShare) { EnsureTlsSetup(); - server_->SetPacketFilter( - std::make_shared<TlsExtensionDropper>(ssl_tls13_key_share_xtn)); + MakeTlsFilter<TlsExtensionDropper>(server_, ssl_tls13_key_share_xtn); client_->ExpectSendAlert(kTlsAlertMissingExtension); server_->ExpectSendAlert(kTlsAlertBadRecordMac); ConnectExpectFail(); @@ -611,8 +575,7 @@ TEST_F(TlsExtensionTest13Stream, WrongServerKeyShare) { 0x02}; DataBuffer buf(key_share, sizeof(key_share)); EnsureTlsSetup(); - server_->SetPacketFilter( - std::make_shared<TlsExtensionReplacer>(ssl_tls13_key_share_xtn, buf)); + MakeTlsFilter<TlsExtensionReplacer>(server_, ssl_tls13_key_share_xtn, buf); client_->ExpectSendAlert(kTlsAlertIllegalParameter); server_->ExpectSendAlert(kTlsAlertBadRecordMac); ConnectExpectFail(); @@ -633,8 +596,7 @@ TEST_F(TlsExtensionTest13Stream, UnknownServerKeyShare) { 0x02}; DataBuffer buf(key_share, sizeof(key_share)); EnsureTlsSetup(); - server_->SetPacketFilter( - std::make_shared<TlsExtensionReplacer>(ssl_tls13_key_share_xtn, buf)); + MakeTlsFilter<TlsExtensionReplacer>(server_, ssl_tls13_key_share_xtn, buf); client_->ExpectSendAlert(kTlsAlertMissingExtension); server_->ExpectSendAlert(kTlsAlertBadRecordMac); ConnectExpectFail(); @@ -645,8 +607,8 @@ TEST_F(TlsExtensionTest13Stream, UnknownServerKeyShare) { TEST_F(TlsExtensionTest13Stream, AddServerSignatureAlgorithmsOnResumption) { SetupForResume(); DataBuffer empty; - server_->SetPacketFilter(std::make_shared<TlsExtensionInjector>( - ssl_signature_algorithms_xtn, empty)); + MakeTlsFilter<TlsExtensionInjector>(server_, ssl_signature_algorithms_xtn, + empty); client_->ExpectSendAlert(kTlsAlertUnsupportedExtension); server_->ExpectSendAlert(kTlsAlertBadRecordMac); ConnectExpectFail(); @@ -666,8 +628,12 @@ typedef std::function<void(TlsPreSharedKeyReplacer*)> class TlsPreSharedKeyReplacer : public TlsExtensionFilter { public: - TlsPreSharedKeyReplacer(TlsPreSharedKeyReplacerFunc function) - : identities_(), binders_(), function_(function) {} + TlsPreSharedKeyReplacer(const std::shared_ptr<TlsAgent>& agent, + TlsPreSharedKeyReplacerFunc function) + : TlsExtensionFilter(agent), + identities_(), + binders_(), + function_(function) {} static size_t CopyAndMaybeReplace(TlsParser* parser, size_t size, const std::unique_ptr<DataBuffer>& replace, @@ -781,8 +747,10 @@ class TlsPreSharedKeyReplacer : public TlsExtensionFilter { TEST_F(TlsExtensionTest13Stream, ResumeEmptyPskLabel) { SetupForResume(); - client_->SetPacketFilter(std::make_shared<TlsPreSharedKeyReplacer>([]( - TlsPreSharedKeyReplacer* r) { r->identities_[0].identity.Truncate(0); })); + MakeTlsFilter<TlsPreSharedKeyReplacer>( + client_, [](TlsPreSharedKeyReplacer* r) { + r->identities_[0].identity.Truncate(0); + }); ConnectExpectAlert(server_, kTlsAlertIllegalParameter); client_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT); server_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO); @@ -792,10 +760,10 @@ TEST_F(TlsExtensionTest13Stream, ResumeEmptyPskLabel) { TEST_F(TlsExtensionTest13Stream, ResumeIncorrectBinderValue) { SetupForResume(); - client_->SetPacketFilter( - std::make_shared<TlsPreSharedKeyReplacer>([](TlsPreSharedKeyReplacer* r) { + MakeTlsFilter<TlsPreSharedKeyReplacer>( + client_, [](TlsPreSharedKeyReplacer* r) { r->binders_[0].Write(0, r->binders_[0].data()[0] ^ 0xff, 1); - })); + }); ConnectExpectAlert(server_, kTlsAlertDecryptError); client_->CheckErrorCode(SSL_ERROR_DECRYPT_ERROR_ALERT); server_->CheckErrorCode(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE); @@ -805,10 +773,10 @@ TEST_F(TlsExtensionTest13Stream, ResumeIncorrectBinderValue) { TEST_F(TlsExtensionTest13Stream, ResumeIncorrectBinderLength) { SetupForResume(); - client_->SetPacketFilter( - std::make_shared<TlsPreSharedKeyReplacer>([](TlsPreSharedKeyReplacer* r) { + MakeTlsFilter<TlsPreSharedKeyReplacer>( + client_, [](TlsPreSharedKeyReplacer* r) { r->binders_[0].Write(r->binders_[0].len(), 0xff, 1); - })); + }); ConnectExpectAlert(server_, kTlsAlertIllegalParameter); client_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT); server_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO); @@ -818,8 +786,8 @@ TEST_F(TlsExtensionTest13Stream, ResumeIncorrectBinderLength) { TEST_F(TlsExtensionTest13Stream, ResumeBinderTooShort) { SetupForResume(); - client_->SetPacketFilter(std::make_shared<TlsPreSharedKeyReplacer>( - [](TlsPreSharedKeyReplacer* r) { r->binders_[0].Truncate(31); })); + MakeTlsFilter<TlsPreSharedKeyReplacer>( + client_, [](TlsPreSharedKeyReplacer* r) { r->binders_[0].Truncate(31); }); ConnectExpectAlert(server_, kTlsAlertIllegalParameter); client_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT); server_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO); @@ -830,11 +798,11 @@ TEST_F(TlsExtensionTest13Stream, ResumeBinderTooShort) { TEST_F(TlsExtensionTest13Stream, ResumeTwoPsks) { SetupForResume(); - client_->SetPacketFilter( - std::make_shared<TlsPreSharedKeyReplacer>([](TlsPreSharedKeyReplacer* r) { + MakeTlsFilter<TlsPreSharedKeyReplacer>( + client_, [](TlsPreSharedKeyReplacer* r) { r->identities_.push_back(r->identities_[0]); r->binders_.push_back(r->binders_[0]); - })); + }); ConnectExpectAlert(server_, kTlsAlertDecryptError); client_->CheckErrorCode(SSL_ERROR_DECRYPT_ERROR_ALERT); server_->CheckErrorCode(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE); @@ -845,10 +813,10 @@ TEST_F(TlsExtensionTest13Stream, ResumeTwoPsks) { TEST_F(TlsExtensionTest13Stream, ResumeTwoIdentitiesOneBinder) { SetupForResume(); - client_->SetPacketFilter( - std::make_shared<TlsPreSharedKeyReplacer>([](TlsPreSharedKeyReplacer* r) { + MakeTlsFilter<TlsPreSharedKeyReplacer>( + client_, [](TlsPreSharedKeyReplacer* r) { r->identities_.push_back(r->identities_[0]); - })); + }); ConnectExpectAlert(server_, kTlsAlertIllegalParameter); client_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT); server_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO); @@ -857,8 +825,10 @@ TEST_F(TlsExtensionTest13Stream, ResumeTwoIdentitiesOneBinder) { TEST_F(TlsExtensionTest13Stream, ResumeOneIdentityTwoBinders) { SetupForResume(); - client_->SetPacketFilter(std::make_shared<TlsPreSharedKeyReplacer>([]( - TlsPreSharedKeyReplacer* r) { r->binders_.push_back(r->binders_[0]); })); + MakeTlsFilter<TlsPreSharedKeyReplacer>( + client_, [](TlsPreSharedKeyReplacer* r) { + r->binders_.push_back(r->binders_[0]); + }); ConnectExpectAlert(server_, kTlsAlertIllegalParameter); client_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT); server_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO); @@ -870,8 +840,8 @@ TEST_F(TlsExtensionTest13Stream, ResumePskExtensionNotLast) { const uint8_t empty_buf[] = {0}; DataBuffer empty(empty_buf, 0); // Inject an unused extension after the PSK extension. - client_->SetPacketFilter(std::make_shared<TlsExtensionAppender>( - kTlsHandshakeClientHello, 0xffff, empty)); + MakeTlsFilter<TlsExtensionAppender>(client_, kTlsHandshakeClientHello, 0xffff, + empty); ConnectExpectAlert(server_, kTlsAlertIllegalParameter); client_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT); server_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO); @@ -881,8 +851,8 @@ TEST_F(TlsExtensionTest13Stream, ResumeNoKeModes) { SetupForResume(); DataBuffer empty; - client_->SetPacketFilter(std::make_shared<TlsExtensionDropper>( - ssl_tls13_psk_key_exchange_modes_xtn)); + MakeTlsFilter<TlsExtensionDropper>(client_, + ssl_tls13_psk_key_exchange_modes_xtn); ConnectExpectAlert(server_, kTlsAlertMissingExtension); client_->CheckErrorCode(SSL_ERROR_MISSING_EXTENSION_ALERT); server_->CheckErrorCode(SSL_ERROR_MISSING_PSK_KEY_EXCHANGE_MODES); @@ -897,8 +867,8 @@ TEST_F(TlsExtensionTest13Stream, ResumeBogusKeModes) { kTls13PskKe}; DataBuffer modes(ke_modes, sizeof(ke_modes)); - client_->SetPacketFilter(std::make_shared<TlsExtensionReplacer>( - ssl_tls13_psk_key_exchange_modes_xtn, modes)); + MakeTlsFilter<TlsExtensionReplacer>( + client_, ssl_tls13_psk_key_exchange_modes_xtn, modes); client_->ExpectSendAlert(kTlsAlertBadRecordMac); server_->ExpectSendAlert(kTlsAlertBadRecordMac); ConnectExpectFail(); @@ -908,9 +878,8 @@ TEST_F(TlsExtensionTest13Stream, ResumeBogusKeModes) { TEST_P(TlsExtensionTest13, NoKeModesIfResumptionOff) { ConfigureSessionCache(RESUME_NONE, RESUME_NONE); - auto capture = std::make_shared<TlsExtensionCapture>( - ssl_tls13_psk_key_exchange_modes_xtn); - client_->SetPacketFilter(capture); + auto capture = MakeTlsFilter<TlsExtensionCapture>( + client_, ssl_tls13_psk_key_exchange_modes_xtn); Connect(); EXPECT_FALSE(capture->captured()); } @@ -1006,12 +975,9 @@ class TlsBogusExtensionTest : public TlsConnectTestBase, static uint8_t empty_buf[1] = {0}; DataBuffer empty(empty_buf, 0); auto filter = - std::make_shared<TlsExtensionAppender>(message, extension, empty); + MakeTlsFilter<TlsExtensionAppender>(server_, message, extension, empty); if (version_ >= SSL_LIBRARY_VERSION_TLS_1_3) { - server_->SetTlsRecordFilter(filter); filter->EnableDecryption(); - } else { - server_->SetPacketFilter(filter); } } @@ -1032,17 +998,20 @@ class TlsBogusExtensionTestPre13 : public TlsBogusExtensionTest { class TlsBogusExtensionTest13 : public TlsBogusExtensionTest { protected: void ConnectAndFail(uint8_t message) override { - if (message == kTlsHandshakeHelloRetryRequest) { + if (message != kTlsHandshakeServerHello) { ConnectExpectAlert(client_, kTlsAlertUnsupportedExtension); return; } - client_->StartConnect(); - server_->StartConnect(); + FailWithAlert(kTlsAlertUnsupportedExtension); + } + + void FailWithAlert(uint8_t alert) { + StartConnect(); client_->Handshake(); // ClientHello server_->Handshake(); // ServerHello - client_->ExpectSendAlert(kTlsAlertUnsupportedExtension); + client_->ExpectSendAlert(alert); client_->Handshake(); if (variant_ == ssl_variant_stream) { server_->ExpectSendAlert(kTlsAlertBadRecordMac); @@ -1067,9 +1036,12 @@ TEST_P(TlsBogusExtensionTest13, AddBogusExtensionCertificate) { Run(kTlsHandshakeCertificate); } +// It's perfectly valid to set unknown extensions in CertificateRequest. TEST_P(TlsBogusExtensionTest13, AddBogusExtensionCertificateRequest) { server_->RequestClientAuth(false); - Run(kTlsHandshakeCertificateRequest); + AddFilter(kTlsHandshakeCertificateRequest, 0xff); + ConnectExpectAlert(client_, kTlsAlertDecryptError); + client_->CheckErrorCode(SEC_ERROR_BAD_SIGNATURE); } TEST_P(TlsBogusExtensionTest13, AddBogusExtensionHelloRetryRequest) { @@ -1079,10 +1051,6 @@ TEST_P(TlsBogusExtensionTest13, AddBogusExtensionHelloRetryRequest) { Run(kTlsHandshakeHelloRetryRequest); } -TEST_P(TlsBogusExtensionTest13, AddVersionExtensionServerHello) { - Run(kTlsHandshakeServerHello, ssl_tls13_supported_versions_xtn); -} - TEST_P(TlsBogusExtensionTest13, AddVersionExtensionEncryptedExtensions) { Run(kTlsHandshakeEncryptedExtensions, ssl_tls13_supported_versions_xtn); } @@ -1096,13 +1064,6 @@ TEST_P(TlsBogusExtensionTest13, AddVersionExtensionCertificateRequest) { Run(kTlsHandshakeCertificateRequest, ssl_tls13_supported_versions_xtn); } -TEST_P(TlsBogusExtensionTest13, AddVersionExtensionHelloRetryRequest) { - static const std::vector<SSLNamedGroup> groups = {ssl_grp_ec_secp384r1}; - server_->ConfigNamedGroups(groups); - - Run(kTlsHandshakeHelloRetryRequest, ssl_tls13_supported_versions_xtn); -} - // NewSessionTicket allows unknown extensions AND it isn't protected by the // Finished. So adding an unknown extension doesn't cause an error. TEST_P(TlsBogusExtensionTest13, AddBogusExtensionNewSessionTicket) { @@ -1132,8 +1093,7 @@ TEST_P(TlsConnectStream, IncludePadding) { SECStatus rv = SSL_SetURL(client_->ssl_fd(), long_name); EXPECT_EQ(SECSuccess, rv); - auto capture = std::make_shared<TlsExtensionCapture>(ssl_padding_xtn); - client_->SetPacketFilter(capture); + auto capture = MakeTlsFilter<TlsExtensionCapture>(client_, ssl_padding_xtn); client_->StartConnect(); client_->Handshake(); EXPECT_TRUE(capture->captured()); diff --git a/security/nss/gtests/ssl_gtest/ssl_fragment_unittest.cc b/security/nss/gtests/ssl_gtest/ssl_fragment_unittest.cc index 44cacce46..f4940bf28 100644 --- a/security/nss/gtests/ssl_gtest/ssl_fragment_unittest.cc +++ b/security/nss/gtests/ssl_gtest/ssl_fragment_unittest.cc @@ -51,10 +51,16 @@ class RecordFragmenter : public PacketFilter { while (parser.remaining()) { TlsHandshakeFilter::HandshakeHeader handshake_header; DataBuffer handshake_body; - if (!handshake_header.Parse(&parser, record_header, &handshake_body)) { + bool complete = false; + if (!handshake_header.Parse(&parser, record_header, DataBuffer(), + &handshake_body, &complete)) { ADD_FAILURE() << "couldn't parse handshake header"; return false; } + if (!complete) { + ADD_FAILURE() << "don't want to deal with fragmented messages"; + return false; + } DataBuffer record_fragment; // We can't fragment handshake records that are too small. @@ -82,7 +88,7 @@ class RecordFragmenter : public PacketFilter { while (parser.remaining()) { TlsRecordHeader header; DataBuffer record; - if (!header.Parse(&parser, &record)) { + if (!header.Parse(0, &parser, &record)) { ADD_FAILURE() << "bad record header"; return false; } @@ -143,13 +149,13 @@ class RecordFragmenter : public PacketFilter { }; TEST_P(TlsConnectDatagram, FragmentClientPackets) { - client_->SetPacketFilter(std::make_shared<RecordFragmenter>()); + client_->SetFilter(std::make_shared<RecordFragmenter>()); Connect(); SendReceive(); } TEST_P(TlsConnectDatagram, FragmentServerPackets) { - server_->SetPacketFilter(std::make_shared<RecordFragmenter>()); + server_->SetFilter(std::make_shared<RecordFragmenter>()); 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 1587b66de..99448321c 100644 --- a/security/nss/gtests/ssl_gtest/ssl_fuzz_unittest.cc +++ b/security/nss/gtests/ssl_gtest/ssl_fuzz_unittest.cc @@ -27,7 +27,8 @@ class TlsFuzzTest : public ::testing::Test {}; // Record the application data stream. class TlsApplicationDataRecorder : public TlsRecordFilter { public: - TlsApplicationDataRecorder() : buffer_() {} + TlsApplicationDataRecorder(const std::shared_ptr<TlsAgent>& agent) + : TlsRecordFilter(agent), buffer_() {} virtual PacketFilter::Action FilterRecord(const TlsRecordHeader& header, const DataBuffer& input, @@ -47,9 +48,9 @@ class TlsApplicationDataRecorder : public TlsRecordFilter { // Ensure that ssl_Time() returns a constant value. FUZZ_F(TlsFuzzTest, SSL_Time_Constant) { - PRUint32 now = ssl_Time(); + PRUint32 now = ssl_TimeSec(); PR_Sleep(PR_SecondsToInterval(2)); - EXPECT_EQ(ssl_Time(), now); + EXPECT_EQ(ssl_TimeSec(), now); } // Check that due to the deterministic PRNG we derive @@ -106,16 +107,16 @@ FUZZ_P(TlsConnectGeneric, DeterministicTranscript) { DisableECDHEServerKeyReuse(); DataBuffer buffer; - client_->SetPacketFilter(std::make_shared<TlsConversationRecorder>(buffer)); - server_->SetPacketFilter(std::make_shared<TlsConversationRecorder>(buffer)); + MakeTlsFilter<TlsConversationRecorder>(client_, buffer); + MakeTlsFilter<TlsConversationRecorder>(server_, buffer); // Reset the RNG state. EXPECT_EQ(SECSuccess, RNG_RandomUpdate(NULL, 0)); Connect(); // Ensure the filters go away before |buffer| does. - client_->DeletePacketFilter(); - server_->DeletePacketFilter(); + client_->ClearFilter(); + server_->ClearFilter(); if (last.len() > 0) { EXPECT_EQ(last, buffer); @@ -133,10 +134,8 @@ FUZZ_P(TlsConnectGeneric, ConnectSendReceive_NullCipher) { EnsureTlsSetup(); // Set up app data filters. - auto client_recorder = std::make_shared<TlsApplicationDataRecorder>(); - client_->SetPacketFilter(client_recorder); - auto server_recorder = std::make_shared<TlsApplicationDataRecorder>(); - server_->SetPacketFilter(server_recorder); + auto client_recorder = MakeTlsFilter<TlsApplicationDataRecorder>(client_); + auto server_recorder = MakeTlsFilter<TlsApplicationDataRecorder>(server_); Connect(); @@ -161,10 +160,9 @@ FUZZ_P(TlsConnectGeneric, ConnectSendReceive_NullCipher) { FUZZ_P(TlsConnectGeneric, BogusClientFinished) { EnsureTlsSetup(); - auto i1 = std::make_shared<TlsInspectorReplaceHandshakeMessage>( - kTlsHandshakeFinished, + MakeTlsFilter<TlsInspectorReplaceHandshakeMessage>( + client_, kTlsHandshakeFinished, DataBuffer(kShortEmptyFinished, sizeof(kShortEmptyFinished))); - client_->SetPacketFilter(i1); Connect(); SendReceive(); } @@ -173,10 +171,9 @@ FUZZ_P(TlsConnectGeneric, BogusClientFinished) { FUZZ_P(TlsConnectGeneric, BogusServerFinished) { EnsureTlsSetup(); - auto i1 = std::make_shared<TlsInspectorReplaceHandshakeMessage>( - kTlsHandshakeFinished, + MakeTlsFilter<TlsInspectorReplaceHandshakeMessage>( + server_, kTlsHandshakeFinished, DataBuffer(kLongEmptyFinished, sizeof(kLongEmptyFinished))); - server_->SetPacketFilter(i1); Connect(); SendReceive(); } @@ -187,7 +184,7 @@ FUZZ_P(TlsConnectGeneric, BogusServerAuthSignature) { uint8_t msg_type = version_ == SSL_LIBRARY_VERSION_TLS_1_3 ? kTlsHandshakeCertificateVerify : kTlsHandshakeServerKeyExchange; - server_->SetPacketFilter(std::make_shared<TlsLastByteDamager>(msg_type)); + MakeTlsFilter<TlsLastByteDamager>(server_, msg_type); Connect(); SendReceive(); } @@ -197,8 +194,7 @@ FUZZ_P(TlsConnectGeneric, BogusClientAuthSignature) { EnsureTlsSetup(); client_->SetupClientAuth(); server_->RequestClientAuth(true); - client_->SetPacketFilter( - std::make_shared<TlsLastByteDamager>(kTlsHandshakeCertificateVerify)); + MakeTlsFilter<TlsLastByteDamager>(client_, kTlsHandshakeCertificateVerify); Connect(); } @@ -215,82 +211,32 @@ FUZZ_P(TlsConnectGeneric, SessionTicketResumption) { SendReceive(); } -class TlsSessionTicketMacDamager : public TlsExtensionFilter { - public: - TlsSessionTicketMacDamager() {} - virtual PacketFilter::Action FilterExtension(uint16_t extension_type, - const DataBuffer& input, - DataBuffer* output) { - if (extension_type != ssl_session_ticket_xtn && - extension_type != ssl_tls13_pre_shared_key_xtn) { - return KEEP; - } - - *output = input; - - // Handle everything before TLS 1.3. - if (extension_type == ssl_session_ticket_xtn) { - // Modify the last byte of the MAC. - output->data()[output->len() - 1] ^= 0xff; - } - - // Handle TLS 1.3. - if (extension_type == ssl_tls13_pre_shared_key_xtn) { - TlsParser parser(input); - - uint32_t ids_len; - EXPECT_TRUE(parser.Read(&ids_len, 2) && ids_len > 0); - - uint32_t ticket_len; - EXPECT_TRUE(parser.Read(&ticket_len, 2) && ticket_len > 0); - - // Modify the last byte of the MAC. - output->data()[2 + 2 + ticket_len - 1] ^= 0xff; - } - - return CHANGE; - } -}; - -// Check that session ticket resumption works with a bad MAC. -FUZZ_P(TlsConnectGeneric, SessionTicketResumptionBadMac) { - ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET); - Connect(); - SendReceive(); - - Reset(); - ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET); - ExpectResumption(RESUME_TICKET); - - client_->SetPacketFilter(std::make_shared<TlsSessionTicketMacDamager>()); - Connect(); - SendReceive(); -} - // Check that session tickets are not encrypted. FUZZ_P(TlsConnectGeneric, UnencryptedSessionTickets) { ConfigureSessionCache(RESUME_TICKET, RESUME_TICKET); - auto i1 = std::make_shared<TlsInspectorRecordHandshakeMessage>( - kTlsHandshakeNewSessionTicket); - server_->SetPacketFilter(i1); + auto filter = MakeTlsFilter<TlsHandshakeRecorder>( + server_, kTlsHandshakeNewSessionTicket); Connect(); + std::cerr << "ticket" << filter->buffer() << std::endl; size_t offset = 4; /* lifetime */ if (version_ == SSL_LIBRARY_VERSION_TLS_1_3) { - offset += 1 + 1 + /* ke_modes */ - 1 + 1; /* auth_modes */ + offset += 4; /* ticket_age_add */ + uint32_t nonce_len = 0; + EXPECT_TRUE(filter->buffer().Read(offset, 1, &nonce_len)); + offset += 1 + nonce_len; } offset += 2 + /* ticket length */ 2; /* TLS_EX_SESS_TICKET_VERSION */ // Check the protocol version number. uint32_t tls_version = 0; - EXPECT_TRUE(i1->buffer().Read(offset, sizeof(version_), &tls_version)); + EXPECT_TRUE(filter->buffer().Read(offset, sizeof(version_), &tls_version)); EXPECT_EQ(version_, static_cast<decltype(version_)>(tls_version)); // Check the cipher suite. uint32_t suite = 0; - EXPECT_TRUE(i1->buffer().Read(offset + sizeof(version_), 2, &suite)); + EXPECT_TRUE(filter->buffer().Read(offset + sizeof(version_), 2, &suite)); client_->CheckCipherSuite(static_cast<uint16_t>(suite)); } } diff --git a/security/nss/gtests/ssl_gtest/ssl_gtest.cc b/security/nss/gtests/ssl_gtest/ssl_gtest.cc index cd10076b8..2fff9d7cb 100644 --- a/security/nss/gtests/ssl_gtest/ssl_gtest.cc +++ b/security/nss/gtests/ssl_gtest/ssl_gtest.cc @@ -6,6 +6,7 @@ #include <cstdlib> #include "test_io.h" +#include "databuffer.h" #define GTEST_HAS_RTTI 0 #include "gtest/gtest.h" @@ -28,6 +29,7 @@ int main(int argc, char** argv) { ++i; } else if (!strcmp(argv[i], "-v")) { g_ssl_gtest_verbose = true; + nss_test::DataBuffer::SetLogLimit(16384); } } diff --git a/security/nss/gtests/ssl_gtest/ssl_gtest.gyp b/security/nss/gtests/ssl_gtest/ssl_gtest.gyp index 8cd7d1009..e2a8d830a 100644 --- a/security/nss/gtests/ssl_gtest/ssl_gtest.gyp +++ b/security/nss/gtests/ssl_gtest/ssl_gtest.gyp @@ -11,6 +11,7 @@ 'target_name': 'ssl_gtest', 'type': 'executable', 'sources': [ + 'bloomfilter_unittest.cc', 'libssl_internals.c', 'selfencrypt_unittest.cc', 'ssl_0rtt_unittest.cc', @@ -18,6 +19,7 @@ 'ssl_auth_unittest.cc', 'ssl_cert_ext_unittest.cc', 'ssl_ciphersuite_unittest.cc', + 'ssl_custext_unittest.cc', 'ssl_damage_unittest.cc', 'ssl_dhe_unittest.cc', 'ssl_drop_unittest.cc', @@ -30,11 +32,16 @@ 'ssl_gather_unittest.cc', 'ssl_gtest.cc', 'ssl_hrr_unittest.cc', + 'ssl_keylog_unittest.cc', + 'ssl_keyupdate_unittest.cc', 'ssl_loopback_unittest.cc', + 'ssl_misc_unittest.cc', 'ssl_record_unittest.cc', 'ssl_resumption_unittest.cc', + 'ssl_renegotiation_unittest.cc', 'ssl_skip_unittest.cc', 'ssl_staticrsa_unittest.cc', + 'ssl_tls13compat_unittest.cc', 'ssl_v2_client_hello_unittest.cc', 'ssl_version_unittest.cc', 'ssl_versionpolicy_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 39055f641..05ae87034 100644 --- a/security/nss/gtests/ssl_gtest/ssl_hrr_unittest.cc +++ b/security/nss/gtests/ssl_gtest/ssl_hrr_unittest.cc @@ -35,17 +35,15 @@ TEST_P(TlsConnectTls13, HelloRetryRequestAbortsZeroRtt) { // Send first ClientHello and send 0-RTT data auto capture_early_data = - std::make_shared<TlsExtensionCapture>(ssl_tls13_early_data_xtn); - client_->SetPacketFilter(capture_early_data); + MakeTlsFilter<TlsExtensionCapture>(client_, ssl_tls13_early_data_xtn); client_->Handshake(); EXPECT_EQ(k0RttDataLen, PR_Write(client_->ssl_fd(), k0RttData, k0RttDataLen)); // 0-RTT write. EXPECT_TRUE(capture_early_data->captured()); // Send the HelloRetryRequest - auto hrr_capture = std::make_shared<TlsInspectorRecordHandshakeMessage>( - kTlsHandshakeHelloRetryRequest); - server_->SetPacketFilter(hrr_capture); + auto hrr_capture = MakeTlsFilter<TlsHandshakeRecorder>( + server_, kTlsHandshakeHelloRetryRequest); server_->Handshake(); EXPECT_LT(0U, hrr_capture->buffer().len()); @@ -56,8 +54,7 @@ TEST_P(TlsConnectTls13, HelloRetryRequestAbortsZeroRtt) { // Make a new capture for the early data. capture_early_data = - std::make_shared<TlsExtensionCapture>(ssl_tls13_early_data_xtn); - client_->SetPacketFilter(capture_early_data); + MakeTlsFilter<TlsExtensionCapture>(client_, ssl_tls13_early_data_xtn); // Complete the handshake successfully Handshake(); @@ -71,6 +68,10 @@ TEST_P(TlsConnectTls13, HelloRetryRequestAbortsZeroRtt) { // packet. If the record is split into two packets, or there are multiple // handshake packets, this will break. class CorrectMessageSeqAfterHrrFilter : public TlsRecordFilter { + public: + CorrectMessageSeqAfterHrrFilter(const std::shared_ptr<TlsAgent>& agent) + : TlsRecordFilter(agent) {} + protected: PacketFilter::Action FilterRecord(const TlsRecordHeader& header, const DataBuffer& record, size_t* offset, @@ -131,8 +132,7 @@ TEST_P(TlsConnectTls13, SecondClientHelloRejectEarlyDataXtn) { // Correct the DTLS message sequence number after an HRR. if (variant_ == ssl_variant_datagram) { - client_->SetPacketFilter( - std::make_shared<CorrectMessageSeqAfterHrrFilter>()); + MakeTlsFilter<CorrectMessageSeqAfterHrrFilter>(client_); } server_->SetPeer(client_); @@ -151,7 +151,8 @@ TEST_P(TlsConnectTls13, SecondClientHelloRejectEarlyDataXtn) { class KeyShareReplayer : public TlsExtensionFilter { public: - KeyShareReplayer() {} + KeyShareReplayer(const std::shared_ptr<TlsAgent>& agent) + : TlsExtensionFilter(agent) {} virtual PacketFilter::Action FilterExtension(uint16_t extension_type, const DataBuffer& input, @@ -178,7 +179,22 @@ class KeyShareReplayer : public TlsExtensionFilter { // server should reject this. TEST_P(TlsConnectTls13, RetryWithSameKeyShare) { EnsureTlsSetup(); - client_->SetPacketFilter(std::make_shared<KeyShareReplayer>()); + MakeTlsFilter<KeyShareReplayer>(client_); + static const std::vector<SSLNamedGroup> groups = {ssl_grp_ec_secp384r1, + ssl_grp_ec_secp521r1}; + server_->ConfigNamedGroups(groups); + ConnectExpectAlert(server_, kTlsAlertIllegalParameter); + EXPECT_EQ(SSL_ERROR_BAD_2ND_CLIENT_HELLO, server_->error_code()); + EXPECT_EQ(SSL_ERROR_ILLEGAL_PARAMETER_ALERT, client_->error_code()); +} + +// Here we modify the second ClientHello so that the client retries with the +// same shares, even though the server wanted something else. +TEST_P(TlsConnectTls13, RetryWithTwoShares) { + EnsureTlsSetup(); + EXPECT_EQ(SECSuccess, SSL_SendAdditionalKeyShares(client_->ssl_fd(), 1)); + MakeTlsFilter<KeyShareReplayer>(client_); + static const std::vector<SSLNamedGroup> groups = {ssl_grp_ec_secp384r1, ssl_grp_ec_secp521r1}; server_->ConfigNamedGroups(groups); @@ -187,13 +203,574 @@ TEST_P(TlsConnectTls13, RetryWithSameKeyShare) { EXPECT_EQ(SSL_ERROR_ILLEGAL_PARAMETER_ALERT, client_->error_code()); } +TEST_P(TlsConnectTls13, RetryCallbackAccept) { + EnsureTlsSetup(); + + auto accept_hello = [](PRBool firstHello, const PRUint8* clientToken, + unsigned int clientTokenLen, PRUint8* appToken, + unsigned int* appTokenLen, unsigned int appTokenMax, + void* arg) { + auto* called = reinterpret_cast<bool*>(arg); + *called = true; + + EXPECT_TRUE(firstHello); + EXPECT_EQ(0U, clientTokenLen); + return ssl_hello_retry_accept; + }; + + bool cb_run = false; + EXPECT_EQ(SECSuccess, SSL_HelloRetryRequestCallback(server_->ssl_fd(), + accept_hello, &cb_run)); + Connect(); + EXPECT_TRUE(cb_run); +} + +TEST_P(TlsConnectTls13, RetryCallbackAcceptGroupMismatch) { + EnsureTlsSetup(); + + auto accept_hello_twice = [](PRBool firstHello, const PRUint8* clientToken, + unsigned int clientTokenLen, PRUint8* appToken, + unsigned int* appTokenLen, + unsigned int appTokenMax, void* arg) { + auto* called = reinterpret_cast<size_t*>(arg); + ++*called; + + EXPECT_EQ(0U, clientTokenLen); + return ssl_hello_retry_accept; + }; + + auto capture = + MakeTlsFilter<TlsExtensionCapture>(server_, ssl_tls13_cookie_xtn); + capture->SetHandshakeTypes({kTlsHandshakeHelloRetryRequest}); + + static const std::vector<SSLNamedGroup> groups = {ssl_grp_ec_secp384r1}; + server_->ConfigNamedGroups(groups); + + size_t cb_run = 0; + EXPECT_EQ(SECSuccess, SSL_HelloRetryRequestCallback( + server_->ssl_fd(), accept_hello_twice, &cb_run)); + Connect(); + EXPECT_EQ(2U, cb_run); + EXPECT_TRUE(capture->captured()) << "expected a cookie in HelloRetryRequest"; +} + +TEST_P(TlsConnectTls13, RetryCallbackFail) { + EnsureTlsSetup(); + + auto fail_hello = [](PRBool firstHello, const PRUint8* clientToken, + unsigned int clientTokenLen, PRUint8* appToken, + unsigned int* appTokenLen, unsigned int appTokenMax, + void* arg) { + auto* called = reinterpret_cast<bool*>(arg); + *called = true; + + EXPECT_TRUE(firstHello); + EXPECT_EQ(0U, clientTokenLen); + return ssl_hello_retry_fail; + }; + + bool cb_run = false; + EXPECT_EQ(SECSuccess, SSL_HelloRetryRequestCallback(server_->ssl_fd(), + fail_hello, &cb_run)); + ConnectExpectAlert(server_, kTlsAlertHandshakeFailure); + server_->CheckErrorCode(SSL_ERROR_APPLICATION_ABORT); + EXPECT_TRUE(cb_run); +} + +// Asking for retry twice isn't allowed. +TEST_P(TlsConnectTls13, RetryCallbackRequestHrrTwice) { + EnsureTlsSetup(); + + auto bad_callback = [](PRBool firstHello, const PRUint8* clientToken, + unsigned int clientTokenLen, PRUint8* appToken, + unsigned int* appTokenLen, unsigned int appTokenMax, + void* arg) -> SSLHelloRetryRequestAction { + return ssl_hello_retry_request; + }; + EXPECT_EQ(SECSuccess, SSL_HelloRetryRequestCallback(server_->ssl_fd(), + bad_callback, NULL)); + ConnectExpectAlert(server_, kTlsAlertInternalError); + server_->CheckErrorCode(SSL_ERROR_APP_CALLBACK_ERROR); +} + +// Accepting the CH and modifying the token isn't allowed. +TEST_P(TlsConnectTls13, RetryCallbackAcceptAndSetToken) { + EnsureTlsSetup(); + + auto bad_callback = [](PRBool firstHello, const PRUint8* clientToken, + unsigned int clientTokenLen, PRUint8* appToken, + unsigned int* appTokenLen, unsigned int appTokenMax, + void* arg) -> SSLHelloRetryRequestAction { + *appTokenLen = 1; + return ssl_hello_retry_accept; + }; + EXPECT_EQ(SECSuccess, SSL_HelloRetryRequestCallback(server_->ssl_fd(), + bad_callback, NULL)); + ConnectExpectAlert(server_, kTlsAlertInternalError); + server_->CheckErrorCode(SSL_ERROR_APP_CALLBACK_ERROR); +} + +// As above, but with reject. +TEST_P(TlsConnectTls13, RetryCallbackRejectAndSetToken) { + EnsureTlsSetup(); + + auto bad_callback = [](PRBool firstHello, const PRUint8* clientToken, + unsigned int clientTokenLen, PRUint8* appToken, + unsigned int* appTokenLen, unsigned int appTokenMax, + void* arg) -> SSLHelloRetryRequestAction { + *appTokenLen = 1; + return ssl_hello_retry_fail; + }; + EXPECT_EQ(SECSuccess, SSL_HelloRetryRequestCallback(server_->ssl_fd(), + bad_callback, NULL)); + ConnectExpectAlert(server_, kTlsAlertInternalError); + server_->CheckErrorCode(SSL_ERROR_APP_CALLBACK_ERROR); +} + +// This is a (pretend) buffer overflow. +TEST_P(TlsConnectTls13, RetryCallbackSetTooLargeToken) { + EnsureTlsSetup(); + + auto bad_callback = [](PRBool firstHello, const PRUint8* clientToken, + unsigned int clientTokenLen, PRUint8* appToken, + unsigned int* appTokenLen, unsigned int appTokenMax, + void* arg) -> SSLHelloRetryRequestAction { + *appTokenLen = appTokenMax + 1; + return ssl_hello_retry_accept; + }; + EXPECT_EQ(SECSuccess, SSL_HelloRetryRequestCallback(server_->ssl_fd(), + bad_callback, NULL)); + ConnectExpectAlert(server_, kTlsAlertInternalError); + server_->CheckErrorCode(SSL_ERROR_APP_CALLBACK_ERROR); +} + +SSLHelloRetryRequestAction RetryHello(PRBool firstHello, + const PRUint8* clientToken, + unsigned int clientTokenLen, + PRUint8* appToken, + unsigned int* appTokenLen, + unsigned int appTokenMax, void* arg) { + auto* called = reinterpret_cast<size_t*>(arg); + ++*called; + + EXPECT_EQ(0U, clientTokenLen); + return firstHello ? ssl_hello_retry_request : ssl_hello_retry_accept; +} + +TEST_P(TlsConnectTls13, RetryCallbackRetry) { + EnsureTlsSetup(); + + auto capture_hrr = std::make_shared<TlsHandshakeRecorder>( + server_, ssl_hs_hello_retry_request); + auto capture_key_share = + std::make_shared<TlsExtensionCapture>(server_, ssl_tls13_key_share_xtn); + capture_key_share->SetHandshakeTypes({kTlsHandshakeHelloRetryRequest}); + std::vector<std::shared_ptr<PacketFilter>> chain = {capture_hrr, + capture_key_share}; + server_->SetFilter(std::make_shared<ChainedPacketFilter>(chain)); + + size_t cb_called = 0; + EXPECT_EQ(SECSuccess, SSL_HelloRetryRequestCallback(server_->ssl_fd(), + RetryHello, &cb_called)); + + // Do the first message exchange. + StartConnect(); + client_->Handshake(); + server_->Handshake(); + + EXPECT_EQ(1U, cb_called) << "callback should be called once here"; + EXPECT_LT(0U, capture_hrr->buffer().len()) << "HelloRetryRequest expected"; + EXPECT_FALSE(capture_key_share->captured()) + << "no key_share extension expected"; + + auto capture_cookie = + MakeTlsFilter<TlsExtensionCapture>(client_, ssl_tls13_cookie_xtn); + + Handshake(); + CheckConnected(); + EXPECT_EQ(2U, cb_called); + EXPECT_TRUE(capture_cookie->captured()) << "should have a cookie"; +} + +static size_t CountShares(const DataBuffer& key_share) { + size_t count = 0; + uint32_t len = 0; + size_t offset = 2; + + EXPECT_TRUE(key_share.Read(0, 2, &len)); + EXPECT_EQ(key_share.len() - 2, len); + while (offset < key_share.len()) { + offset += 2; // Skip KeyShareEntry.group + EXPECT_TRUE(key_share.Read(offset, 2, &len)); + offset += 2 + len; // Skip KeyShareEntry.key_exchange + ++count; + } + return count; +} + +TEST_P(TlsConnectTls13, RetryCallbackRetryWithAdditionalShares) { + EnsureTlsSetup(); + EXPECT_EQ(SECSuccess, SSL_SendAdditionalKeyShares(client_->ssl_fd(), 1)); + + auto capture_server = + MakeTlsFilter<TlsExtensionCapture>(server_, ssl_tls13_key_share_xtn); + capture_server->SetHandshakeTypes({kTlsHandshakeHelloRetryRequest}); + + size_t cb_called = 0; + EXPECT_EQ(SECSuccess, SSL_HelloRetryRequestCallback(server_->ssl_fd(), + RetryHello, &cb_called)); + + // Do the first message exchange. + StartConnect(); + client_->Handshake(); + server_->Handshake(); + + EXPECT_EQ(1U, cb_called) << "callback should be called once here"; + EXPECT_FALSE(capture_server->captured()) + << "no key_share extension expected from server"; + + auto capture_client_2nd = + MakeTlsFilter<TlsExtensionCapture>(client_, ssl_tls13_key_share_xtn); + + Handshake(); + CheckConnected(); + EXPECT_EQ(2U, cb_called); + EXPECT_TRUE(capture_client_2nd->captured()) << "client should send key_share"; + EXPECT_EQ(2U, CountShares(capture_client_2nd->extension())) + << "client should still send two shares"; +} + +// The callback should be run even if we have another reason to send +// HelloRetryRequest. In this case, the server sends HRR because the server +// wants a P-384 key share and the client didn't offer one. +TEST_P(TlsConnectTls13, RetryCallbackRetryWithGroupMismatch) { + EnsureTlsSetup(); + + auto capture_cookie = + std::make_shared<TlsExtensionCapture>(server_, ssl_tls13_cookie_xtn); + capture_cookie->SetHandshakeTypes({kTlsHandshakeHelloRetryRequest}); + auto capture_key_share = + std::make_shared<TlsExtensionCapture>(server_, ssl_tls13_key_share_xtn); + capture_key_share->SetHandshakeTypes({kTlsHandshakeHelloRetryRequest}); + server_->SetFilter(std::make_shared<ChainedPacketFilter>( + ChainedPacketFilterInit{capture_cookie, capture_key_share})); + + static const std::vector<SSLNamedGroup> groups = {ssl_grp_ec_secp384r1}; + server_->ConfigNamedGroups(groups); + + size_t cb_called = 0; + EXPECT_EQ(SECSuccess, SSL_HelloRetryRequestCallback(server_->ssl_fd(), + RetryHello, &cb_called)); + Connect(); + EXPECT_EQ(2U, cb_called); + EXPECT_TRUE(capture_cookie->captured()) << "cookie expected"; + EXPECT_TRUE(capture_key_share->captured()) << "key_share expected"; +} + +static const uint8_t kApplicationToken[] = {0x92, 0x44, 0x00}; + +SSLHelloRetryRequestAction RetryHelloWithToken( + PRBool firstHello, const PRUint8* clientToken, unsigned int clientTokenLen, + PRUint8* appToken, unsigned int* appTokenLen, unsigned int appTokenMax, + void* arg) { + auto* called = reinterpret_cast<size_t*>(arg); + ++*called; + + if (firstHello) { + memcpy(appToken, kApplicationToken, sizeof(kApplicationToken)); + *appTokenLen = sizeof(kApplicationToken); + return ssl_hello_retry_request; + } + + EXPECT_EQ(DataBuffer(kApplicationToken, sizeof(kApplicationToken)), + DataBuffer(clientToken, static_cast<size_t>(clientTokenLen))); + return ssl_hello_retry_accept; +} + +TEST_P(TlsConnectTls13, RetryCallbackRetryWithToken) { + EnsureTlsSetup(); + + auto capture_key_share = + MakeTlsFilter<TlsExtensionCapture>(server_, ssl_tls13_key_share_xtn); + capture_key_share->SetHandshakeTypes({kTlsHandshakeHelloRetryRequest}); + + size_t cb_called = 0; + EXPECT_EQ(SECSuccess, + SSL_HelloRetryRequestCallback(server_->ssl_fd(), + RetryHelloWithToken, &cb_called)); + Connect(); + EXPECT_EQ(2U, cb_called); + EXPECT_FALSE(capture_key_share->captured()) << "no key share expected"; +} + +TEST_P(TlsConnectTls13, RetryCallbackRetryWithTokenAndGroupMismatch) { + EnsureTlsSetup(); + + static const std::vector<SSLNamedGroup> groups = {ssl_grp_ec_secp384r1}; + server_->ConfigNamedGroups(groups); + + auto capture_key_share = + MakeTlsFilter<TlsExtensionCapture>(server_, ssl_tls13_key_share_xtn); + capture_key_share->SetHandshakeTypes({kTlsHandshakeHelloRetryRequest}); + + size_t cb_called = 0; + EXPECT_EQ(SECSuccess, + SSL_HelloRetryRequestCallback(server_->ssl_fd(), + RetryHelloWithToken, &cb_called)); + Connect(); + EXPECT_EQ(2U, cb_called); + EXPECT_TRUE(capture_key_share->captured()) << "key share expected"; +} + +SSLHelloRetryRequestAction CheckTicketToken( + PRBool firstHello, const PRUint8* clientToken, unsigned int clientTokenLen, + PRUint8* appToken, unsigned int* appTokenLen, unsigned int appTokenMax, + void* arg) { + auto* called = reinterpret_cast<bool*>(arg); + *called = true; + + EXPECT_TRUE(firstHello); + EXPECT_EQ(DataBuffer(kApplicationToken, sizeof(kApplicationToken)), + DataBuffer(clientToken, static_cast<size_t>(clientTokenLen))); + return ssl_hello_retry_accept; +} + +// Stream because SSL_SendSessionTicket only supports that. +TEST_F(TlsConnectStreamTls13, RetryCallbackWithSessionTicketToken) { + ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET); + Connect(); + EXPECT_EQ(SECSuccess, + SSL_SendSessionTicket(server_->ssl_fd(), kApplicationToken, + sizeof(kApplicationToken))); + SendReceive(); + + Reset(); + ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET); + ExpectResumption(RESUME_TICKET); + + bool cb_run = false; + EXPECT_EQ(SECSuccess, SSL_HelloRetryRequestCallback( + server_->ssl_fd(), CheckTicketToken, &cb_run)); + Connect(); + EXPECT_TRUE(cb_run); +} + +void TriggerHelloRetryRequest(std::shared_ptr<TlsAgent>& client, + std::shared_ptr<TlsAgent>& server) { + size_t cb_called = 0; + EXPECT_EQ(SECSuccess, SSL_HelloRetryRequestCallback(server->ssl_fd(), + RetryHello, &cb_called)); + + // Start the handshake. + client->StartConnect(); + server->StartConnect(); + client->Handshake(); + server->Handshake(); + EXPECT_EQ(1U, cb_called); +} + +TEST_P(TlsConnectTls13, RetryStateless) { + ConfigureSelfEncrypt(); + EnsureTlsSetup(); + + TriggerHelloRetryRequest(client_, server_); + MakeNewServer(); + + Handshake(); + SendReceive(); +} + +TEST_P(TlsConnectTls13, RetryStatefulDropCookie) { + ConfigureSelfEncrypt(); + EnsureTlsSetup(); + + TriggerHelloRetryRequest(client_, server_); + MakeTlsFilter<TlsExtensionDropper>(client_, ssl_tls13_cookie_xtn); + + ExpectAlert(server_, kTlsAlertMissingExtension); + Handshake(); + client_->CheckErrorCode(SSL_ERROR_MISSING_EXTENSION_ALERT); + server_->CheckErrorCode(SSL_ERROR_MISSING_COOKIE_EXTENSION); +} + +// Stream only because DTLS drops bad packets. +TEST_F(TlsConnectStreamTls13, RetryStatelessDamageFirstClientHello) { + ConfigureSelfEncrypt(); + EnsureTlsSetup(); + + auto damage_ch = + MakeTlsFilter<TlsExtensionInjector>(client_, 0xfff3, DataBuffer()); + + TriggerHelloRetryRequest(client_, server_); + MakeNewServer(); + + // Key exchange fails when the handshake continues because client and server + // disagree about the transcript. + client_->ExpectSendAlert(kTlsAlertBadRecordMac); + server_->ExpectSendAlert(kTlsAlertBadRecordMac); + Handshake(); + server_->CheckErrorCode(SSL_ERROR_BAD_MAC_READ); + client_->CheckErrorCode(SSL_ERROR_BAD_MAC_READ); +} + +TEST_F(TlsConnectStreamTls13, RetryStatelessDamageSecondClientHello) { + ConfigureSelfEncrypt(); + EnsureTlsSetup(); + + TriggerHelloRetryRequest(client_, server_); + MakeNewServer(); + + auto damage_ch = + MakeTlsFilter<TlsExtensionInjector>(client_, 0xfff3, DataBuffer()); + + // Key exchange fails when the handshake continues because client and server + // disagree about the transcript. + client_->ExpectSendAlert(kTlsAlertBadRecordMac); + server_->ExpectSendAlert(kTlsAlertBadRecordMac); + Handshake(); + server_->CheckErrorCode(SSL_ERROR_BAD_MAC_READ); + client_->CheckErrorCode(SSL_ERROR_BAD_MAC_READ); +} + +// Read the cipher suite from the HRR and disable it on the identified agent. +static void DisableSuiteFromHrr( + std::shared_ptr<TlsAgent>& agent, + std::shared_ptr<TlsHandshakeRecorder>& capture_hrr) { + uint32_t tmp; + size_t offset = 2 + 32; // skip version + server_random + ASSERT_TRUE( + capture_hrr->buffer().Read(offset, 1, &tmp)); // session_id length + EXPECT_EQ(0U, tmp); + offset += 1 + tmp; + ASSERT_TRUE(capture_hrr->buffer().Read(offset, 2, &tmp)); // suite + EXPECT_EQ( + SECSuccess, + SSL_CipherPrefSet(agent->ssl_fd(), static_cast<uint16_t>(tmp), PR_FALSE)); +} + +TEST_P(TlsConnectTls13, RetryStatelessDisableSuiteClient) { + ConfigureSelfEncrypt(); + EnsureTlsSetup(); + + auto capture_hrr = + MakeTlsFilter<TlsHandshakeRecorder>(server_, ssl_hs_hello_retry_request); + + TriggerHelloRetryRequest(client_, server_); + MakeNewServer(); + + DisableSuiteFromHrr(client_, capture_hrr); + + // The client thinks that the HelloRetryRequest is bad, even though its + // because it changed its mind about the cipher suite. + ExpectAlert(client_, kTlsAlertIllegalParameter); + Handshake(); + client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP); + server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT); +} + +TEST_P(TlsConnectTls13, RetryStatelessDisableSuiteServer) { + ConfigureSelfEncrypt(); + EnsureTlsSetup(); + + auto capture_hrr = + MakeTlsFilter<TlsHandshakeRecorder>(server_, ssl_hs_hello_retry_request); + + TriggerHelloRetryRequest(client_, server_); + MakeNewServer(); + + DisableSuiteFromHrr(server_, capture_hrr); + + ExpectAlert(server_, kTlsAlertIllegalParameter); + Handshake(); + server_->CheckErrorCode(SSL_ERROR_BAD_2ND_CLIENT_HELLO); + client_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT); +} + +TEST_P(TlsConnectTls13, RetryStatelessDisableGroupClient) { + ConfigureSelfEncrypt(); + EnsureTlsSetup(); + + TriggerHelloRetryRequest(client_, server_); + MakeNewServer(); + + static const std::vector<SSLNamedGroup> groups = {ssl_grp_ec_secp384r1}; + client_->ConfigNamedGroups(groups); + + // We're into undefined behavior on the client side, but - at the point this + // test was written - the client here doesn't amend its key shares because the + // server doesn't ask it to. The server notices that the key share (x25519) + // doesn't match the negotiated group (P-384) and objects. + ExpectAlert(server_, kTlsAlertIllegalParameter); + Handshake(); + server_->CheckErrorCode(SSL_ERROR_BAD_2ND_CLIENT_HELLO); + client_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT); +} + +TEST_P(TlsConnectTls13, RetryStatelessDisableGroupServer) { + ConfigureSelfEncrypt(); + EnsureTlsSetup(); + + TriggerHelloRetryRequest(client_, server_); + MakeNewServer(); + + static const std::vector<SSLNamedGroup> groups = {ssl_grp_ec_secp384r1}; + server_->ConfigNamedGroups(groups); + + ExpectAlert(server_, kTlsAlertIllegalParameter); + Handshake(); + server_->CheckErrorCode(SSL_ERROR_BAD_2ND_CLIENT_HELLO); + client_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT); +} + +TEST_P(TlsConnectTls13, RetryStatelessBadCookie) { + ConfigureSelfEncrypt(); + EnsureTlsSetup(); + + TriggerHelloRetryRequest(client_, server_); + + // Now replace the self-encrypt MAC key with a garbage key. + static const uint8_t bad_hmac_key[32] = {0}; + SECItem key_item = {siBuffer, const_cast<uint8_t*>(bad_hmac_key), + sizeof(bad_hmac_key)}; + ScopedPK11SlotInfo slot(PK11_GetInternalSlot()); + PK11SymKey* hmac_key = + PK11_ImportSymKey(slot.get(), CKM_SHA256_HMAC, PK11_OriginUnwrap, + CKA_SIGN, &key_item, nullptr); + ASSERT_NE(nullptr, hmac_key); + SSLInt_SetSelfEncryptMacKey(hmac_key); // Passes ownership. + + MakeNewServer(); + + ExpectAlert(server_, kTlsAlertIllegalParameter); + Handshake(); + server_->CheckErrorCode(SSL_ERROR_BAD_2ND_CLIENT_HELLO); + client_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT); +} + +// Stream because the server doesn't consume the alert and terminate. +TEST_F(TlsConnectStreamTls13, RetryWithDifferentCipherSuite) { + EnsureTlsSetup(); + // Force a HelloRetryRequest. + static const std::vector<SSLNamedGroup> groups = {ssl_grp_ec_secp384r1}; + server_->ConfigNamedGroups(groups); + // Then switch out the default suite (TLS_AES_128_GCM_SHA256). + MakeTlsFilter<SelectedCipherSuiteReplacer>(server_, + TLS_CHACHA20_POLY1305_SHA256); + + client_->ExpectSendAlert(kTlsAlertIllegalParameter); + server_->ExpectSendAlert(kTlsAlertBadRecordMac); + ConnectExpectFail(); + EXPECT_EQ(SSL_ERROR_RX_MALFORMED_SERVER_HELLO, client_->error_code()); + EXPECT_EQ(SSL_ERROR_BAD_MAC_READ, server_->error_code()); +} + // This tests that the second attempt at sending a ClientHello (after receiving // a HelloRetryRequest) is correctly retransmitted. TEST_F(TlsConnectDatagram13, DropClientSecondFlightWithHelloRetry) { static const std::vector<SSLNamedGroup> groups = {ssl_grp_ec_secp384r1, ssl_grp_ec_secp521r1}; server_->ConfigNamedGroups(groups); - server_->SetPacketFilter(std::make_shared<SelectiveDropFilter>(0x2)); + server_->SetFilter(std::make_shared<SelectiveDropFilter>(0x2)); Connect(); } @@ -233,6 +810,54 @@ TEST_P(TlsKeyExchange13, ConnectEcdhePreferenceMismatchHrrExtraShares) { CheckKEXDetails(client_groups, client_groups); } +// The callback should be run even if we have another reason to send +// HelloRetryRequest. In this case, the server sends HRR because the server +// wants an X25519 key share and the client didn't offer one. +TEST_P(TlsKeyExchange13, + RetryCallbackRetryWithGroupMismatchAndAdditionalShares) { + EnsureKeyShareSetup(); + + static const std::vector<SSLNamedGroup> client_groups = { + ssl_grp_ec_secp256r1, ssl_grp_ec_secp384r1, ssl_grp_ec_curve25519}; + client_->ConfigNamedGroups(client_groups); + static const std::vector<SSLNamedGroup> server_groups = { + ssl_grp_ec_curve25519}; + server_->ConfigNamedGroups(server_groups); + EXPECT_EQ(SECSuccess, SSL_SendAdditionalKeyShares(client_->ssl_fd(), 1)); + + auto capture_server = + std::make_shared<TlsExtensionCapture>(server_, ssl_tls13_key_share_xtn); + capture_server->SetHandshakeTypes({kTlsHandshakeHelloRetryRequest}); + server_->SetFilter(std::make_shared<ChainedPacketFilter>( + ChainedPacketFilterInit{capture_hrr_, capture_server})); + + size_t cb_called = 0; + EXPECT_EQ(SECSuccess, SSL_HelloRetryRequestCallback(server_->ssl_fd(), + RetryHello, &cb_called)); + + // Do the first message exchange. + StartConnect(); + client_->Handshake(); + server_->Handshake(); + + EXPECT_EQ(1U, cb_called) << "callback should be called once here"; + EXPECT_TRUE(capture_server->captured()) << "key_share extension expected"; + + uint32_t server_group = 0; + EXPECT_TRUE(capture_server->extension().Read(0, 2, &server_group)); + EXPECT_EQ(ssl_grp_ec_curve25519, static_cast<SSLNamedGroup>(server_group)); + + Handshake(); + CheckConnected(); + EXPECT_EQ(2U, cb_called); + EXPECT_TRUE(shares_capture2_->captured()) << "client should send shares"; + + CheckKeys(); + static const std::vector<SSLNamedGroup> client_shares( + client_groups.begin(), client_groups.begin() + 2); + CheckKEXDetails(client_groups, client_shares, server_groups[0]); +} + TEST_F(TlsConnectTest, Select12AfterHelloRetryRequest) { EnsureTlsSetup(); client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2, @@ -245,8 +870,7 @@ TEST_F(TlsConnectTest, Select12AfterHelloRetryRequest) { static const std::vector<SSLNamedGroup> server_groups = { ssl_grp_ec_secp384r1, ssl_grp_ec_secp521r1}; server_->ConfigNamedGroups(server_groups); - client_->StartConnect(); - server_->StartConnect(); + StartConnect(); client_->Handshake(); server_->Handshake(); @@ -276,15 +900,30 @@ class HelloRetryRequestAgentTest : public TlsAgentTestClient { void MakeCannedHrr(const uint8_t* body, size_t len, DataBuffer* hrr_record, uint32_t seq_num = 0) const { DataBuffer hrr_data; - hrr_data.Allocate(len + 4); + const uint8_t ssl_hello_retry_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}; + + hrr_data.Allocate(len + 6); size_t i = 0; + i = hrr_data.Write(i, 0x0303, 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 + i = hrr_data.Write(i, TLS_AES_128_GCM_SHA256, 2); + i = hrr_data.Write(i, ssl_compression_null, 1); + // Add extensions. First a length, which includes the supported version. + i = hrr_data.Write(i, static_cast<uint32_t>(len) + 6, 2); + // Now the supported version. + i = hrr_data.Write(i, ssl_tls13_supported_versions_xtn, 2); + i = hrr_data.Write(i, 2, 2); i = hrr_data.Write(i, 0x7f00 | TLS_1_3_DRAFT_VERSION, 2); - i = hrr_data.Write(i, static_cast<uint32_t>(len), 2); if (len) { hrr_data.Write(i, body, len); } DataBuffer hrr; - MakeHandshakeMessage(kTlsHandshakeHelloRetryRequest, hrr_data.data(), + MakeHandshakeMessage(kTlsHandshakeServerHello, hrr_data.data(), hrr_data.len(), &hrr, seq_num); MakeRecord(kTlsHandshakeType, SSL_LIBRARY_VERSION_TLS_1_3, hrr.data(), hrr.len(), hrr_record, seq_num); @@ -334,28 +973,6 @@ TEST_P(HelloRetryRequestAgentTest, HandleNoopHelloRetryRequest) { SSL_ERROR_RX_MALFORMED_HELLO_RETRY_REQUEST); } -TEST_P(HelloRetryRequestAgentTest, HandleHelloRetryRequestCookie) { - const uint8_t canned_cookie_hrr[] = { - static_cast<uint8_t>(ssl_tls13_cookie_xtn >> 8), - static_cast<uint8_t>(ssl_tls13_cookie_xtn), - 0, - 5, // length of cookie extension - 0, - 3, // cookie value length - 0xc0, - 0x0c, - 0x13}; - DataBuffer hrr; - MakeCannedHrr(canned_cookie_hrr, sizeof(canned_cookie_hrr), &hrr); - auto capture = std::make_shared<TlsExtensionCapture>(ssl_tls13_cookie_xtn); - agent_->SetPacketFilter(capture); - ProcessMessage(hrr, TlsAgent::STATE_CONNECTING); - const size_t cookie_pos = 2 + 2; // cookie_xtn, extension len - DataBuffer cookie(canned_cookie_hrr + cookie_pos, - sizeof(canned_cookie_hrr) - cookie_pos); - EXPECT_EQ(cookie, capture->extension()); -} - INSTANTIATE_TEST_CASE_P(HelloRetryRequestAgentTests, HelloRetryRequestAgentTest, ::testing::Combine(TlsConnectTestBase::kTlsVariantsAll, TlsConnectTestBase::kTlsV13)); diff --git a/security/nss/gtests/ssl_gtest/ssl_keylog_unittest.cc b/security/nss/gtests/ssl_gtest/ssl_keylog_unittest.cc new file mode 100644 index 000000000..322b64837 --- /dev/null +++ b/security/nss/gtests/ssl_gtest/ssl_keylog_unittest.cc @@ -0,0 +1,118 @@ +/* -*- 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/. */ + +#ifdef NSS_ALLOW_SSLKEYLOGFILE + +#include <cstdlib> +#include <fstream> +#include <sstream> + +#include "gtest_utils.h" +#include "tls_connect.h" + +namespace nss_test { + +static const std::string keylog_file_path = "keylog.txt"; +static const std::string keylog_env = "SSLKEYLOGFILE=" + keylog_file_path; + +class KeyLogFileTest : public TlsConnectGeneric { + public: + void SetUp() override { + TlsConnectGeneric::SetUp(); + // Remove previous results (if any). + (void)remove(keylog_file_path.c_str()); + PR_SetEnv(keylog_env.c_str()); + } + + void CheckKeyLog() { + std::ifstream f(keylog_file_path); + std::map<std::string, size_t> labels; + std::set<std::string> client_randoms; + for (std::string line; std::getline(f, line);) { + if (line[0] == '#') { + continue; + } + + std::istringstream iss(line); + std::string label, client_random, secret; + iss >> label >> client_random >> secret; + + ASSERT_EQ(64U, client_random.size()); + client_randoms.insert(client_random); + labels[label]++; + } + + if (version_ < SSL_LIBRARY_VERSION_TLS_1_3) { + ASSERT_EQ(1U, client_randoms.size()); + } else { + /* two handshakes for 0-RTT */ + ASSERT_EQ(2U, client_randoms.size()); + } + + // Every entry occurs twice (one log from server, one from client). + if (version_ < SSL_LIBRARY_VERSION_TLS_1_3) { + ASSERT_EQ(2U, labels["CLIENT_RANDOM"]); + } else { + ASSERT_EQ(2U, labels["CLIENT_EARLY_TRAFFIC_SECRET"]); + ASSERT_EQ(2U, labels["EARLY_EXPORTER_SECRET"]); + ASSERT_EQ(4U, labels["CLIENT_HANDSHAKE_TRAFFIC_SECRET"]); + ASSERT_EQ(4U, labels["SERVER_HANDSHAKE_TRAFFIC_SECRET"]); + ASSERT_EQ(4U, labels["CLIENT_TRAFFIC_SECRET_0"]); + ASSERT_EQ(4U, labels["SERVER_TRAFFIC_SECRET_0"]); + ASSERT_EQ(4U, labels["EXPORTER_SECRET"]); + } + } + + void ConnectAndCheck() { + // This is a child process, ensure that error messages immediately + // propagate or else it will not be visible. + ::testing::GTEST_FLAG(throw_on_failure) = true; + + if (version_ == SSL_LIBRARY_VERSION_TLS_1_3) { + SetupForZeroRtt(); + client_->Set0RttEnabled(true); + server_->Set0RttEnabled(true); + ExpectResumption(RESUME_TICKET); + ZeroRttSendReceive(true, true); + Handshake(); + ExpectEarlyDataAccepted(true); + CheckConnected(); + SendReceive(); + } else { + Connect(); + } + CheckKeyLog(); + _exit(0); + } +}; + +// Tests are run in a separate process to ensure that NSS is not initialized yet +// and can process the SSLKEYLOGFILE environment variable. + +TEST_P(KeyLogFileTest, KeyLogFile) { + testing::GTEST_FLAG(death_test_style) = "threadsafe"; + + ASSERT_EXIT(ConnectAndCheck(), ::testing::ExitedWithCode(0), ""); +} + +INSTANTIATE_TEST_CASE_P( + KeyLogFileDTLS12, KeyLogFileTest, + ::testing::Combine(TlsConnectTestBase::kTlsVariantsDatagram, + TlsConnectTestBase::kTlsV11V12)); +INSTANTIATE_TEST_CASE_P( + KeyLogFileTLS12, KeyLogFileTest, + ::testing::Combine(TlsConnectTestBase::kTlsVariantsStream, + TlsConnectTestBase::kTlsV10ToV12)); +#ifndef NSS_DISABLE_TLS_1_3 +INSTANTIATE_TEST_CASE_P( + KeyLogFileTLS13, KeyLogFileTest, + ::testing::Combine(TlsConnectTestBase::kTlsVariantsStream, + TlsConnectTestBase::kTlsV13)); +#endif + +} // namespace nss_test + +#endif // NSS_ALLOW_SSLKEYLOGFILE diff --git a/security/nss/gtests/ssl_gtest/ssl_keyupdate_unittest.cc b/security/nss/gtests/ssl_gtest/ssl_keyupdate_unittest.cc new file mode 100644 index 000000000..d03775c25 --- /dev/null +++ b/security/nss/gtests/ssl_gtest/ssl_keyupdate_unittest.cc @@ -0,0 +1,178 @@ +/* -*- 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" + +extern "C" { +// This is not something that should make you happy. +#include "libssl_internals.h" +} + +#include "gtest_utils.h" +#include "scoped_ptrs.h" +#include "tls_connect.h" +#include "tls_filter.h" +#include "tls_parser.h" + +namespace nss_test { + +// All stream only tests; DTLS isn't supported yet. + +TEST_F(TlsConnectTest, KeyUpdateClient) { + ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3); + Connect(); + EXPECT_EQ(SECSuccess, SSL_KeyUpdate(client_->ssl_fd(), PR_FALSE)); + SendReceive(50); + SendReceive(60); + CheckEpochs(4, 3); +} + +TEST_F(TlsConnectTest, KeyUpdateClientRequestUpdate) { + ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3); + Connect(); + EXPECT_EQ(SECSuccess, SSL_KeyUpdate(client_->ssl_fd(), PR_TRUE)); + // SendReceive() only gives each peer one chance to read. This isn't enough + // when the read on one side generates another handshake message. A second + // read gives each peer an extra chance to consume the KeyUpdate. + SendReceive(50); + SendReceive(60); // Cumulative count. + CheckEpochs(4, 4); +} + +TEST_F(TlsConnectTest, KeyUpdateServer) { + ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3); + Connect(); + EXPECT_EQ(SECSuccess, SSL_KeyUpdate(server_->ssl_fd(), PR_FALSE)); + SendReceive(50); + SendReceive(60); + CheckEpochs(3, 4); +} + +TEST_F(TlsConnectTest, KeyUpdateServerRequestUpdate) { + ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3); + Connect(); + EXPECT_EQ(SECSuccess, SSL_KeyUpdate(server_->ssl_fd(), PR_TRUE)); + SendReceive(50); + SendReceive(60); + CheckEpochs(4, 4); +} + +TEST_F(TlsConnectTest, KeyUpdateConsecutiveRequests) { + ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3); + Connect(); + EXPECT_EQ(SECSuccess, SSL_KeyUpdate(server_->ssl_fd(), PR_TRUE)); + EXPECT_EQ(SECSuccess, SSL_KeyUpdate(server_->ssl_fd(), PR_TRUE)); + SendReceive(50); + SendReceive(60); + // The server should have updated twice, but the client should have declined + // to respond to the second request from the server, since it doesn't send + // anything in between those two requests. + CheckEpochs(4, 5); +} + +// Check that a local update can be immediately followed by a remotely triggered +// update even if there is no use of the keys. +TEST_F(TlsConnectTest, KeyUpdateLocalUpdateThenConsecutiveRequests) { + ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3); + Connect(); + // This should trigger an update on the client. + EXPECT_EQ(SECSuccess, SSL_KeyUpdate(client_->ssl_fd(), PR_FALSE)); + // The client should update for the first request. + EXPECT_EQ(SECSuccess, SSL_KeyUpdate(server_->ssl_fd(), PR_TRUE)); + // ...but not the second. + EXPECT_EQ(SECSuccess, SSL_KeyUpdate(server_->ssl_fd(), PR_TRUE)); + SendReceive(50); + SendReceive(60); + // Both should have updated twice. + CheckEpochs(5, 5); +} + +TEST_F(TlsConnectTest, KeyUpdateMultiple) { + ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3); + Connect(); + EXPECT_EQ(SECSuccess, SSL_KeyUpdate(server_->ssl_fd(), PR_FALSE)); + EXPECT_EQ(SECSuccess, SSL_KeyUpdate(server_->ssl_fd(), PR_TRUE)); + EXPECT_EQ(SECSuccess, SSL_KeyUpdate(server_->ssl_fd(), PR_FALSE)); + EXPECT_EQ(SECSuccess, SSL_KeyUpdate(client_->ssl_fd(), PR_FALSE)); + SendReceive(50); + SendReceive(60); + CheckEpochs(5, 6); +} + +// Both ask the other for an update, and both should react. +TEST_F(TlsConnectTest, KeyUpdateBothRequest) { + ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3); + Connect(); + EXPECT_EQ(SECSuccess, SSL_KeyUpdate(client_->ssl_fd(), PR_TRUE)); + EXPECT_EQ(SECSuccess, SSL_KeyUpdate(server_->ssl_fd(), PR_TRUE)); + SendReceive(50); + SendReceive(60); + CheckEpochs(5, 5); +} + +// If the sequence number exceeds the number of writes before an automatic +// update (currently 3/4 of the max records for the cipher suite), then the +// stack should send an update automatically (but not request one). +TEST_F(TlsConnectTest, KeyUpdateAutomaticOnWrite) { + ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3); + ConnectWithCipherSuite(TLS_AES_128_GCM_SHA256); + + // Set this to one below the write threshold. + uint64_t threshold = (0x5aULL << 28) * 3 / 4; + EXPECT_EQ(SECSuccess, + SSLInt_AdvanceWriteSeqNum(client_->ssl_fd(), threshold)); + EXPECT_EQ(SECSuccess, SSLInt_AdvanceReadSeqNum(server_->ssl_fd(), threshold)); + + // This should be OK. + client_->SendData(10); + server_->ReadBytes(); + + // This should cause the client to update. + client_->SendData(10); + server_->ReadBytes(); + + SendReceive(100); + CheckEpochs(4, 3); +} + +// If the sequence number exceeds a certain number of reads (currently 7/8 of +// the max records for the cipher suite), then the stack should send AND request +// an update automatically. However, the sender (client) will be above its +// automatic update threshold, so the KeyUpdate - that it sends with the old +// cipher spec - will exceed the receiver (server) automatic update threshold. +// The receiver gets a packet with a sequence number over its automatic read +// update threshold. Even though the sender has updated, the code that checks +// the sequence numbers at the receiver doesn't know this and it will request an +// update. This causes two updates: one from the sender (without requesting a +// response) and one from the receiver (which does request a response). +TEST_F(TlsConnectTest, KeyUpdateAutomaticOnRead) { + ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3); + ConnectWithCipherSuite(TLS_AES_128_GCM_SHA256); + + // Move to right at the read threshold. Unlike the write test, we can't send + // packets because that would cause the client to update, which would spoil + // the test. + uint64_t threshold = ((0x5aULL << 28) * 7 / 8) + 1; + EXPECT_EQ(SECSuccess, + SSLInt_AdvanceWriteSeqNum(client_->ssl_fd(), threshold)); + EXPECT_EQ(SECSuccess, SSLInt_AdvanceReadSeqNum(server_->ssl_fd(), threshold)); + + // This should cause the client to update, but not early enough to prevent the + // server from updating also. + client_->SendData(10); + server_->ReadBytes(); + + // Need two SendReceive() calls to ensure that the update that the server + // requested is properly generated and consumed. + SendReceive(70); + SendReceive(80); + CheckEpochs(5, 4); +} + +} // namespace nss_test diff --git a/security/nss/gtests/ssl_gtest/ssl_loopback_unittest.cc b/security/nss/gtests/ssl_gtest/ssl_loopback_unittest.cc index 77703dd8e..f1b78f52f 100644 --- a/security/nss/gtests/ssl_gtest/ssl_loopback_unittest.cc +++ b/security/nss/gtests/ssl_gtest/ssl_loopback_unittest.cc @@ -6,6 +6,7 @@ #include <functional> #include <memory> +#include <vector> #include "secerr.h" #include "ssl.h" #include "sslerr.h" @@ -55,7 +56,8 @@ TEST_P(TlsConnectGeneric, CipherSuiteMismatch) { class TlsAlertRecorder : public TlsRecordFilter { public: - TlsAlertRecorder() : level_(255), description_(255) {} + TlsAlertRecorder(const std::shared_ptr<TlsAgent>& agent) + : TlsRecordFilter(agent), level_(255), description_(255) {} PacketFilter::Action FilterRecord(const TlsRecordHeader& header, const DataBuffer& input, @@ -84,13 +86,13 @@ class TlsAlertRecorder : public TlsRecordFilter { }; class HelloTruncator : public TlsHandshakeFilter { + public: + HelloTruncator(const std::shared_ptr<TlsAgent>& agent) + : TlsHandshakeFilter( + agent, {kTlsHandshakeClientHello, kTlsHandshakeServerHello}) {} PacketFilter::Action FilterHandshake(const HandshakeHeader& header, const DataBuffer& input, DataBuffer* output) override { - if (header.handshake_type() != kTlsHandshakeClientHello && - header.handshake_type() != kTlsHandshakeServerHello) { - return KEEP; - } output->Assign(input.data(), input.len() - 1); return CHANGE; } @@ -98,19 +100,17 @@ class HelloTruncator : public TlsHandshakeFilter { // Verify that when NSS reports that an alert is sent, it is actually sent. TEST_P(TlsConnectGeneric, CaptureAlertServer) { - client_->SetPacketFilter(std::make_shared<HelloTruncator>()); - auto alert_recorder = std::make_shared<TlsAlertRecorder>(); - server_->SetPacketFilter(alert_recorder); + MakeTlsFilter<HelloTruncator>(client_); + auto alert_recorder = MakeTlsFilter<TlsAlertRecorder>(server_); - ConnectExpectAlert(server_, kTlsAlertIllegalParameter); + ConnectExpectAlert(server_, kTlsAlertDecodeError); EXPECT_EQ(kTlsAlertFatal, alert_recorder->level()); - EXPECT_EQ(kTlsAlertIllegalParameter, alert_recorder->description()); + EXPECT_EQ(kTlsAlertDecodeError, alert_recorder->description()); } TEST_P(TlsConnectGenericPre13, CaptureAlertClient) { - server_->SetPacketFilter(std::make_shared<HelloTruncator>()); - auto alert_recorder = std::make_shared<TlsAlertRecorder>(); - client_->SetPacketFilter(alert_recorder); + MakeTlsFilter<HelloTruncator>(server_); + auto alert_recorder = MakeTlsFilter<TlsAlertRecorder>(client_); ConnectExpectAlert(client_, kTlsAlertDecodeError); EXPECT_EQ(kTlsAlertFatal, alert_recorder->level()); @@ -119,12 +119,10 @@ TEST_P(TlsConnectGenericPre13, CaptureAlertClient) { // In TLS 1.3, the server can't read the client alert. TEST_P(TlsConnectTls13, CaptureAlertClient) { - server_->SetPacketFilter(std::make_shared<HelloTruncator>()); - auto alert_recorder = std::make_shared<TlsAlertRecorder>(); - client_->SetPacketFilter(alert_recorder); + MakeTlsFilter<HelloTruncator>(server_); + auto alert_recorder = MakeTlsFilter<TlsAlertRecorder>(client_); - server_->StartConnect(); - client_->StartConnect(); + StartConnect(); client_->Handshake(); client_->ExpectSendAlert(kTlsAlertDecodeError); @@ -166,26 +164,111 @@ TEST_P(TlsConnectDatagram, ConnectSrtp) { SendReceive(); } -// 1.3 is disabled in the next few tests because we don't -// presently support resumption in 1.3. -TEST_P(TlsConnectStreamPre13, ConnectAndClientRenegotiate) { +TEST_P(TlsConnectGeneric, ConnectSendReceive) { Connect(); - server_->PrepareForRenegotiate(); - client_->StartRenegotiate(); - Handshake(); - CheckConnected(); + SendReceive(); } -TEST_P(TlsConnectStreamPre13, ConnectAndServerRenegotiate) { +class SaveTlsRecord : public TlsRecordFilter { + public: + SaveTlsRecord(const std::shared_ptr<TlsAgent>& agent, size_t index) + : TlsRecordFilter(agent), index_(index), count_(0), contents_() {} + + const DataBuffer& contents() const { return contents_; } + + protected: + PacketFilter::Action FilterRecord(const TlsRecordHeader& header, + const DataBuffer& data, + DataBuffer* changed) override { + if (count_++ == index_) { + contents_ = data; + } + return KEEP; + } + + private: + const size_t index_; + size_t count_; + DataBuffer contents_; +}; + +// Check that decrypting filters work and can read any record. +// This test (currently) only works in TLS 1.3 where we can decrypt. +TEST_F(TlsConnectStreamTls13, DecryptRecordClient) { + EnsureTlsSetup(); + // 0 = ClientHello, 1 = Finished, 2 = SendReceive, 3 = SendBuffer + auto saved = MakeTlsFilter<SaveTlsRecord>(client_, 3); + saved->EnableDecryption(); Connect(); - client_->PrepareForRenegotiate(); - server_->StartRenegotiate(); - Handshake(); - CheckConnected(); + SendReceive(); + + static const uint8_t data[] = {0xde, 0xad, 0xdc}; + DataBuffer buf(data, sizeof(data)); + client_->SendBuffer(buf); + EXPECT_EQ(buf, saved->contents()); } -TEST_P(TlsConnectGeneric, ConnectSendReceive) { +TEST_F(TlsConnectStreamTls13, DecryptRecordServer) { + EnsureTlsSetup(); + // Disable tickets so that we are sure to not get NewSessionTicket. + EXPECT_EQ(SECSuccess, SSL_OptionSet(server_->ssl_fd(), + SSL_ENABLE_SESSION_TICKETS, PR_FALSE)); + // 0 = ServerHello, 1 = other handshake, 2 = SendReceive, 3 = SendBuffer + auto saved = MakeTlsFilter<SaveTlsRecord>(server_, 3); + saved->EnableDecryption(); + Connect(); + SendReceive(); + + static const uint8_t data[] = {0xde, 0xad, 0xd5}; + DataBuffer buf(data, sizeof(data)); + server_->SendBuffer(buf); + EXPECT_EQ(buf, saved->contents()); +} + +class DropTlsRecord : public TlsRecordFilter { + public: + DropTlsRecord(const std::shared_ptr<TlsAgent>& agent, size_t index) + : TlsRecordFilter(agent), index_(index), count_(0) {} + + protected: + PacketFilter::Action FilterRecord(const TlsRecordHeader& header, + const DataBuffer& data, + DataBuffer* changed) override { + if (count_++ == index_) { + return DROP; + } + return KEEP; + } + + private: + const size_t index_; + size_t count_; +}; + +// Test that decrypting filters work correctly and are able to drop records. +TEST_F(TlsConnectStreamTls13, DropRecordServer) { + EnsureTlsSetup(); + // Disable session tickets so that the server doesn't send an extra record. + EXPECT_EQ(SECSuccess, SSL_OptionSet(server_->ssl_fd(), + SSL_ENABLE_SESSION_TICKETS, PR_FALSE)); + + // 0 = ServerHello, 1 = other handshake, 2 = first write + auto filter = MakeTlsFilter<DropTlsRecord>(server_, 2); + filter->EnableDecryption(); + Connect(); + server_->SendData(23, 23); // This should be dropped, so it won't be counted. + server_->ResetSentBytes(); + SendReceive(); +} + +TEST_F(TlsConnectStreamTls13, DropRecordClient) { + EnsureTlsSetup(); + // 0 = ClientHello, 1 = Finished, 2 = first write + auto filter = MakeTlsFilter<DropTlsRecord>(client_, 2); + filter->EnableDecryption(); Connect(); + client_->SendData(26, 26); // This should be dropped, so it won't be counted. + client_->ResetSentBytes(); SendReceive(); } @@ -224,32 +307,74 @@ TEST_P(TlsConnectStream, ShortRead) { ASSERT_EQ(50U, client_->received_bytes()); } -TEST_P(TlsConnectGeneric, ConnectWithCompressionMaybe) { +// We enable compression via the API but it's disabled internally, +// so we should never get it. +TEST_P(TlsConnectGeneric, ConnectWithCompressionEnabled) { EnsureTlsSetup(); - client_->EnableCompression(); - server_->EnableCompression(); + client_->SetOption(SSL_ENABLE_DEFLATE, PR_TRUE); + server_->SetOption(SSL_ENABLE_DEFLATE, PR_TRUE); Connect(); - EXPECT_EQ(client_->version() < SSL_LIBRARY_VERSION_TLS_1_3 && - variant_ != ssl_variant_datagram, - client_->is_compressed()); + EXPECT_FALSE(client_->is_compressed()); SendReceive(); } -TEST_P(TlsConnectDatagram, TestDtlsHolddownExpiry) { +class TlsHolddownTest : public TlsConnectDatagram { + protected: + // This causes all timers to run to completion. It advances the clock and + // handshakes on both peers until both peers have no more timers pending, + // which should happen at the end of a handshake. This is necessary to ensure + // that the relatively long holddown timer expires, but that any other timers + // also expire and run correctly. + void RunAllTimersDown() { + while (true) { + PRIntervalTime time; + SECStatus rv = DTLS_GetHandshakeTimeout(client_->ssl_fd(), &time); + if (rv != SECSuccess) { + rv = DTLS_GetHandshakeTimeout(server_->ssl_fd(), &time); + if (rv != SECSuccess) { + break; // Neither peer has an outstanding timer. + } + } + + if (g_ssl_gtest_verbose) { + std::cerr << "Shifting timers" << std::endl; + } + ShiftDtlsTimers(); + Handshake(); + } + } +}; + +TEST_P(TlsHolddownTest, TestDtlsHolddownExpiry) { Connect(); - std::cerr << "Expiring holddown timer\n"; - SSLInt_ForceTimerExpiry(client_->ssl_fd()); - SSLInt_ForceTimerExpiry(server_->ssl_fd()); + std::cerr << "Expiring holddown timer" << std::endl; + RunAllTimersDown(); SendReceive(); if (version_ >= SSL_LIBRARY_VERSION_TLS_1_3) { // One for send, one for receive. - EXPECT_EQ(2, SSLInt_CountTls13CipherSpecs(client_->ssl_fd())); + EXPECT_EQ(2, SSLInt_CountCipherSpecs(client_->ssl_fd())); } } +TEST_P(TlsHolddownTest, TestDtlsHolddownExpiryResumption) { + ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET); + Connect(); + SendReceive(); + + Reset(); + ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET); + ExpectResumption(RESUME_TICKET); + Connect(); + RunAllTimersDown(); + SendReceive(); + // One for send, one for receive. + EXPECT_EQ(2, SSLInt_CountCipherSpecs(client_->ssl_fd())); +} + class TlsPreCCSHeaderInjector : public TlsRecordFilter { public: - TlsPreCCSHeaderInjector() {} + TlsPreCCSHeaderInjector(const std::shared_ptr<TlsAgent>& agent) + : TlsRecordFilter(agent) {} virtual PacketFilter::Action FilterRecord( const TlsRecordHeader& record_header, const DataBuffer& input, size_t* offset, DataBuffer* output) override { @@ -266,16 +391,15 @@ class TlsPreCCSHeaderInjector : public TlsRecordFilter { }; TEST_P(TlsConnectStreamPre13, ClientFinishedHeaderBeforeCCS) { - client_->SetPacketFilter(std::make_shared<TlsPreCCSHeaderInjector>()); + MakeTlsFilter<TlsPreCCSHeaderInjector>(client_); ConnectExpectAlert(server_, kTlsAlertUnexpectedMessage); client_->CheckErrorCode(SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT); server_->CheckErrorCode(SSL_ERROR_RX_UNEXPECTED_CHANGE_CIPHER); } TEST_P(TlsConnectStreamPre13, ServerFinishedHeaderBeforeCCS) { - server_->SetPacketFilter(std::make_shared<TlsPreCCSHeaderInjector>()); - client_->StartConnect(); - server_->StartConnect(); + MakeTlsFilter<TlsPreCCSHeaderInjector>(server_); + StartConnect(); ExpectAlert(client_, kTlsAlertUnexpectedMessage); Handshake(); EXPECT_EQ(TlsAgent::STATE_ERROR, client_->state()); @@ -306,21 +430,64 @@ TEST_P(TlsConnectTls13, AlertWrongLevel) { TEST_F(TlsConnectStreamTls13, Tls13FailedWriteSecondFlight) { EnsureTlsSetup(); - client_->StartConnect(); - server_->StartConnect(); + StartConnect(); client_->Handshake(); server_->Handshake(); // Send first flight. - client_->adapter()->CloseWrites(); + client_->adapter()->SetWriteError(PR_IO_ERROR); client_->Handshake(); // This will get an error, but shouldn't crash. client_->CheckErrorCode(SSL_ERROR_SOCKET_WRITE_FAILURE); } -TEST_F(TlsConnectStreamTls13, NegotiateShortHeaders) { - client_->SetShortHeadersEnabled(); - server_->SetShortHeadersEnabled(); - client_->ExpectShortHeaders(); - server_->ExpectShortHeaders(); +TEST_P(TlsConnectDatagram, BlockedWrite) { Connect(); + + // Mark the socket as blocked. + client_->adapter()->SetWriteError(PR_WOULD_BLOCK_ERROR); + static const uint8_t data[] = {1, 2, 3}; + int32_t rv = PR_Write(client_->ssl_fd(), data, sizeof(data)); + EXPECT_GT(0, rv); + EXPECT_EQ(PR_WOULD_BLOCK_ERROR, PORT_GetError()); + + // Remove the write error and though the previous write failed, future reads + // and writes should just work as if it never happened. + client_->adapter()->SetWriteError(0); + SendReceive(); +} + +TEST_F(TlsConnectTest, ConnectSSLv3) { + ConfigureVersion(SSL_LIBRARY_VERSION_3_0); + EnableOnlyStaticRsaCiphers(); + Connect(); + CheckKeys(ssl_kea_rsa, ssl_grp_none, ssl_auth_rsa_decrypt, ssl_sig_none); +} + +TEST_F(TlsConnectTest, ConnectSSLv3ClientAuth) { + ConfigureVersion(SSL_LIBRARY_VERSION_3_0); + EnableOnlyStaticRsaCiphers(); + client_->SetupClientAuth(); + server_->RequestClientAuth(true); + Connect(); + CheckKeys(ssl_kea_rsa, ssl_grp_none, ssl_auth_rsa_decrypt, ssl_sig_none); +} + +static size_t ExpectedCbcLen(size_t in, size_t hmac = 20, size_t block = 16) { + // MAC-then-Encrypt expansion formula: + return ((in + hmac + (block - 1)) / block) * block; +} + +TEST_F(TlsConnectTest, OneNRecordSplitting) { + ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_0); + EnsureTlsSetup(); + ConnectWithCipherSuite(TLS_RSA_WITH_AES_128_CBC_SHA); + auto records = MakeTlsFilter<TlsRecordRecorder>(server_); + // This should be split into 1, 16384 and 20. + DataBuffer big_buffer; + big_buffer.Allocate(1 + 16384 + 20); + server_->SendBuffer(big_buffer); + ASSERT_EQ(3U, records->count()); + EXPECT_EQ(ExpectedCbcLen(1), records->record(0).buffer.len()); + EXPECT_EQ(ExpectedCbcLen(16384), records->record(1).buffer.len()); + EXPECT_EQ(ExpectedCbcLen(20), records->record(2).buffer.len()); } INSTANTIATE_TEST_CASE_P( @@ -336,6 +503,8 @@ INSTANTIATE_TEST_CASE_P(StreamOnly, TlsConnectStream, TlsConnectTestBase::kTlsVAll); INSTANTIATE_TEST_CASE_P(DatagramOnly, TlsConnectDatagram, TlsConnectTestBase::kTlsV11Plus); +INSTANTIATE_TEST_CASE_P(DatagramHolddown, TlsHolddownTest, + TlsConnectTestBase::kTlsV11Plus); INSTANTIATE_TEST_CASE_P( Pre12Stream, TlsConnectPre12, @@ -368,4 +537,27 @@ INSTANTIATE_TEST_CASE_P(Version12Plus, TlsConnectTls12Plus, ::testing::Combine(TlsConnectTestBase::kTlsVariantsAll, TlsConnectTestBase::kTlsV12Plus)); -} // namespace nspr_test +INSTANTIATE_TEST_CASE_P( + GenericStream, TlsConnectGenericResumption, + ::testing::Combine(TlsConnectTestBase::kTlsVariantsStream, + TlsConnectTestBase::kTlsVAll, + ::testing::Values(true, false))); +INSTANTIATE_TEST_CASE_P( + GenericDatagram, TlsConnectGenericResumption, + ::testing::Combine(TlsConnectTestBase::kTlsVariantsDatagram, + TlsConnectTestBase::kTlsV11Plus, + ::testing::Values(true, false))); + +INSTANTIATE_TEST_CASE_P( + GenericStream, TlsConnectGenericResumptionToken, + ::testing::Combine(TlsConnectTestBase::kTlsVariantsStream, + TlsConnectTestBase::kTlsVAll)); +INSTANTIATE_TEST_CASE_P( + GenericDatagram, TlsConnectGenericResumptionToken, + ::testing::Combine(TlsConnectTestBase::kTlsVariantsDatagram, + TlsConnectTestBase::kTlsV11Plus)); + +INSTANTIATE_TEST_CASE_P(GenericDatagram, TlsConnectTls13ResumptionToken, + TlsConnectTestBase::kTlsVariantsAll); + +} // namespace nss_test diff --git a/security/nss/gtests/ssl_gtest/ssl_misc_unittest.cc b/security/nss/gtests/ssl_gtest/ssl_misc_unittest.cc new file mode 100644 index 000000000..2b1b92dcd --- /dev/null +++ b/security/nss/gtests/ssl_gtest/ssl_misc_unittest.cc @@ -0,0 +1,20 @@ +/* -*- 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 "sslexp.h" + +#include "gtest_utils.h" + +namespace nss_test { + +class MiscTest : public ::testing::Test {}; + +TEST_F(MiscTest, NonExistentExperimentalAPI) { + EXPECT_EQ(nullptr, SSL_GetExperimentalAPI("blah")); + EXPECT_EQ(SSL_ERROR_UNSUPPORTED_EXPERIMENTAL_API, PORT_GetError()); +} + +} // namespace nss_test diff --git a/security/nss/gtests/ssl_gtest/ssl_record_unittest.cc b/security/nss/gtests/ssl_gtest/ssl_record_unittest.cc index ef81b222c..3b8727850 100644 --- a/security/nss/gtests/ssl_gtest/ssl_record_unittest.cc +++ b/security/nss/gtests/ssl_gtest/ssl_record_unittest.cc @@ -10,6 +10,8 @@ #include "databuffer.h" #include "gtest_utils.h" +#include "tls_connect.h" +#include "tls_filter.h" namespace nss_test { @@ -51,8 +53,8 @@ class TlsPaddingTest << " total length=" << plaintext_.len() << std::endl; std::cerr << "Plaintext: " << plaintext_ << std::endl; sslBuffer s; - s.buf = const_cast<unsigned char *>( - static_cast<const unsigned char *>(plaintext_.data())); + s.buf = const_cast<unsigned char*>( + static_cast<const unsigned char*>(plaintext_.data())); s.len = plaintext_.len(); SECStatus rv = ssl_RemoveTLSCBCPadding(&s, kMacSize); if (expect_success) { @@ -99,6 +101,73 @@ 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) {} + + 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_); + + for (size_t i = 0; i < size_; ++i) { + changed->data()[i] = i & 0xff; + } + + enabled_ = false; + return CHANGE; + } + + void Enable() { enabled_ = true; } + + private: + bool enabled_; + size_t size_; +}; + +TEST_F(TlsConnectStreamTls13, LargeRecord) { + EnsureTlsSetup(); + + const size_t record_limit = 16384; + auto replacer = MakeTlsFilter<RecordReplacer>(client_, record_limit); + replacer->EnableDecryption(); + Connect(); + + replacer->Enable(); + client_->SendData(10); + WAIT_(server_->received_bytes() == record_limit, 2000); + ASSERT_EQ(record_limit, server_->received_bytes()); +} + +TEST_F(TlsConnectStreamTls13, TooLargeRecord) { + EnsureTlsSetup(); + + const size_t record_limit = 16384; + auto replacer = MakeTlsFilter<RecordReplacer>(client_, record_limit + 1); + replacer->EnableDecryption(); + Connect(); + + replacer->Enable(); + ExpectAlert(server_, kTlsAlertRecordOverflow); + client_->SendData(10); // This is expanded. + + uint8_t buf[record_limit + 2]; + PRInt32 rv = PR_Read(server_->ssl_fd(), buf, sizeof(buf)); + EXPECT_GT(0, rv); + EXPECT_EQ(SSL_ERROR_RX_RECORD_TOO_LONG, PORT_GetError()); + + // Read the server alert. + rv = PR_Read(client_->ssl_fd(), buf, sizeof(buf)); + EXPECT_GT(0, rv); + EXPECT_EQ(SSL_ERROR_RECORD_OVERFLOW_ALERT, PORT_GetError()); +} + const static size_t kContentSizesArr[] = { 1, kMacSize - 1, kMacSize, 30, 31, 32, 36, 256, 257, 287, 288}; @@ -108,4 +177,4 @@ auto kTrueFalse = ::testing::ValuesIn(kTrueFalseArr); INSTANTIATE_TEST_CASE_P(TlsPadding, TlsPaddingTest, ::testing::Combine(kContentSizes, kTrueFalse)); -} // namespace nspr_test +} // namespace nss_test diff --git a/security/nss/gtests/ssl_gtest/ssl_renegotiation_unittest.cc b/security/nss/gtests/ssl_gtest/ssl_renegotiation_unittest.cc new file mode 100644 index 000000000..a902a5f7f --- /dev/null +++ b/security/nss/gtests/ssl_gtest/ssl_renegotiation_unittest.cc @@ -0,0 +1,212 @@ +/* -*- 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 <functional> +#include <memory> +#include "secerr.h" +#include "ssl.h" +#include "sslerr.h" +#include "sslproto.h" + +#include "gtest_utils.h" +#include "tls_connect.h" + +namespace nss_test { + +// 1.3 is disabled in the next few tests because we don't +// presently support resumption in 1.3. +TEST_P(TlsConnectStreamPre13, RenegotiateClient) { + Connect(); + server_->PrepareForRenegotiate(); + client_->StartRenegotiate(); + Handshake(); + CheckConnected(); +} + +TEST_P(TlsConnectStreamPre13, RenegotiateServer) { + Connect(); + client_->PrepareForRenegotiate(); + server_->StartRenegotiate(); + Handshake(); + CheckConnected(); +} + +// The renegotiation options shouldn't cause an error if TLS 1.3 is chosen. +TEST_F(TlsConnectTest, RenegotiationConfigTls13) { + EnsureTlsSetup(); + ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3); + server_->SetOption(SSL_ENABLE_RENEGOTIATION, SSL_RENEGOTIATE_UNRESTRICTED); + server_->SetOption(SSL_REQUIRE_SAFE_NEGOTIATION, PR_TRUE); + Connect(); + SendReceive(); + CheckKeys(); +} + +TEST_P(TlsConnectStream, ConnectTls10AndServerRenegotiateHigher) { + if (version_ == SSL_LIBRARY_VERSION_TLS_1_0) { + return; + } + // Set the client so it will accept any version from 1.0 + // to |version_|. + client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_0, version_); + server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_0, + SSL_LIBRARY_VERSION_TLS_1_0); + // Reset version so that the checks succeed. + uint16_t test_version = version_; + version_ = SSL_LIBRARY_VERSION_TLS_1_0; + Connect(); + + // Now renegotiate, with the server being set to do + // |version_|. + client_->PrepareForRenegotiate(); + server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_0, test_version); + // Reset version and cipher suite so that the preinfo callback + // doesn't fail. + server_->ResetPreliminaryInfo(); + server_->StartRenegotiate(); + + if (test_version >= SSL_LIBRARY_VERSION_TLS_1_3) { + ExpectAlert(server_, kTlsAlertUnexpectedMessage); + } else { + ExpectAlert(server_, kTlsAlertProtocolVersion); + } + + Handshake(); + if (test_version >= SSL_LIBRARY_VERSION_TLS_1_3) { + // In TLS 1.3, the server detects this problem. + client_->CheckErrorCode(SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT); + server_->CheckErrorCode(SSL_ERROR_RENEGOTIATION_NOT_ALLOWED); + } else { + client_->CheckErrorCode(SSL_ERROR_PROTOCOL_VERSION_ALERT); + server_->CheckErrorCode(SSL_ERROR_UNSUPPORTED_VERSION); + } +} + +TEST_P(TlsConnectStream, ConnectTls10AndClientRenegotiateHigher) { + if (version_ == SSL_LIBRARY_VERSION_TLS_1_0) { + return; + } + // Set the client so it will accept any version from 1.0 + // to |version_|. + client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_0, version_); + server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_0, + SSL_LIBRARY_VERSION_TLS_1_0); + // Reset version so that the checks succeed. + uint16_t test_version = version_; + version_ = SSL_LIBRARY_VERSION_TLS_1_0; + Connect(); + + // Now renegotiate, with the server being set to do + // |version_|. + server_->PrepareForRenegotiate(); + server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_0, test_version); + // Reset version and cipher suite so that the preinfo callback + // doesn't fail. + server_->ResetPreliminaryInfo(); + client_->StartRenegotiate(); + if (test_version >= SSL_LIBRARY_VERSION_TLS_1_3) { + ExpectAlert(server_, kTlsAlertUnexpectedMessage); + } else { + ExpectAlert(server_, kTlsAlertProtocolVersion); + } + Handshake(); + if (test_version >= SSL_LIBRARY_VERSION_TLS_1_3) { + // In TLS 1.3, the server detects this problem. + client_->CheckErrorCode(SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT); + server_->CheckErrorCode(SSL_ERROR_RENEGOTIATION_NOT_ALLOWED); + } else { + client_->CheckErrorCode(SSL_ERROR_PROTOCOL_VERSION_ALERT); + server_->CheckErrorCode(SSL_ERROR_UNSUPPORTED_VERSION); + } +} + +TEST_P(TlsConnectStream, ConnectAndServerRenegotiateLower) { + if (version_ == SSL_LIBRARY_VERSION_TLS_1_0) { + return; + } + Connect(); + + // Now renegotiate with the server set to TLS 1.0. + client_->PrepareForRenegotiate(); + server_->PrepareForRenegotiate(); + client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_0, version_); + // Reset version and cipher suite so that the preinfo callback + // doesn't fail. + server_->ResetPreliminaryInfo(); + + SECStatus rv = SSL_ReHandshake(server_->ssl_fd(), PR_TRUE); + if (version_ >= SSL_LIBRARY_VERSION_TLS_1_3) { + EXPECT_EQ(SECFailure, rv); + return; + } + ASSERT_EQ(SECSuccess, rv); + + // Now, before handshaking, tweak the server configuration. + server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_0, + SSL_LIBRARY_VERSION_TLS_1_0); + + // The server should catch the own error. + ExpectAlert(server_, kTlsAlertProtocolVersion); + + Handshake(); + client_->CheckErrorCode(SSL_ERROR_PROTOCOL_VERSION_ALERT); + server_->CheckErrorCode(SSL_ERROR_UNSUPPORTED_VERSION); +} + +TEST_P(TlsConnectStream, ConnectAndServerWontRenegotiateLower) { + if (version_ == SSL_LIBRARY_VERSION_TLS_1_0) { + return; + } + Connect(); + + // Now renegotiate with the server set to TLS 1.0. + client_->PrepareForRenegotiate(); + server_->PrepareForRenegotiate(); + client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_0, version_); + server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_0, + SSL_LIBRARY_VERSION_TLS_1_0); + // Reset version and cipher suite so that the preinfo callback + // doesn't fail. + server_->ResetPreliminaryInfo(); + + EXPECT_EQ(SECFailure, SSL_ReHandshake(server_->ssl_fd(), PR_TRUE)); +} + +TEST_P(TlsConnectStream, ConnectAndClientWontRenegotiateLower) { + if (version_ == SSL_LIBRARY_VERSION_TLS_1_0) { + return; + } + Connect(); + + // Now renegotiate with the client set to TLS 1.0. + client_->PrepareForRenegotiate(); + server_->PrepareForRenegotiate(); + server_->ResetPreliminaryInfo(); + client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_0, + SSL_LIBRARY_VERSION_TLS_1_0); + // The client will refuse to renegotiate down. + EXPECT_EQ(SECFailure, SSL_ReHandshake(client_->ssl_fd(), PR_TRUE)); +} + +TEST_F(TlsConnectTest, Tls13RejectsRehandshakeClient) { + EnsureTlsSetup(); + ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3); + Connect(); + SECStatus rv = SSL_ReHandshake(client_->ssl_fd(), PR_TRUE); + EXPECT_EQ(SECFailure, rv); + EXPECT_EQ(SSL_ERROR_RENEGOTIATION_NOT_ALLOWED, PORT_GetError()); +} + +TEST_F(TlsConnectTest, Tls13RejectsRehandshakeServer) { + EnsureTlsSetup(); + ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3); + Connect(); + SECStatus rv = SSL_ReHandshake(server_->ssl_fd(), PR_TRUE); + EXPECT_EQ(SECFailure, rv); + EXPECT_EQ(SSL_ERROR_RENEGOTIATION_NOT_ALLOWED, PORT_GetError()); +} + +} // 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 ce0e3ca8d..eb78c0585 100644 --- a/security/nss/gtests/ssl_gtest/ssl_resumption_unittest.cc +++ b/security/nss/gtests/ssl_gtest/ssl_resumption_unittest.cc @@ -9,6 +9,7 @@ #include "secerr.h" #include "ssl.h" #include "sslerr.h" +#include "sslexp.h" #include "sslproto.h" extern "C" { @@ -59,7 +60,7 @@ TEST_P(TlsConnectGenericPre13, ConnectResumed) { Connect(); } -TEST_P(TlsConnectGeneric, ConnectClientCacheDisabled) { +TEST_P(TlsConnectGenericResumption, ConnectClientCacheDisabled) { ConfigureSessionCache(RESUME_NONE, RESUME_SESSIONID); Connect(); SendReceive(); @@ -70,7 +71,7 @@ TEST_P(TlsConnectGeneric, ConnectClientCacheDisabled) { SendReceive(); } -TEST_P(TlsConnectGeneric, ConnectServerCacheDisabled) { +TEST_P(TlsConnectGenericResumption, ConnectServerCacheDisabled) { ConfigureSessionCache(RESUME_SESSIONID, RESUME_NONE); Connect(); SendReceive(); @@ -81,7 +82,7 @@ TEST_P(TlsConnectGeneric, ConnectServerCacheDisabled) { SendReceive(); } -TEST_P(TlsConnectGeneric, ConnectSessionCacheDisabled) { +TEST_P(TlsConnectGenericResumption, ConnectSessionCacheDisabled) { ConfigureSessionCache(RESUME_NONE, RESUME_NONE); Connect(); SendReceive(); @@ -92,7 +93,7 @@ TEST_P(TlsConnectGeneric, ConnectSessionCacheDisabled) { SendReceive(); } -TEST_P(TlsConnectGeneric, ConnectResumeSupportBoth) { +TEST_P(TlsConnectGenericResumption, ConnectResumeSupportBoth) { // This prefers tickets. ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH); Connect(); @@ -105,7 +106,7 @@ TEST_P(TlsConnectGeneric, ConnectResumeSupportBoth) { SendReceive(); } -TEST_P(TlsConnectGeneric, ConnectResumeClientTicketServerBoth) { +TEST_P(TlsConnectGenericResumption, ConnectResumeClientTicketServerBoth) { // This causes no resumption because the client needs the // session cache to resume even with tickets. ConfigureSessionCache(RESUME_TICKET, RESUME_BOTH); @@ -119,7 +120,7 @@ TEST_P(TlsConnectGeneric, ConnectResumeClientTicketServerBoth) { SendReceive(); } -TEST_P(TlsConnectGeneric, ConnectResumeClientBothTicketServerTicket) { +TEST_P(TlsConnectGenericResumption, ConnectResumeClientBothTicketServerTicket) { // This causes a ticket resumption. ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET); Connect(); @@ -132,7 +133,7 @@ TEST_P(TlsConnectGeneric, ConnectResumeClientBothTicketServerTicket) { SendReceive(); } -TEST_P(TlsConnectGeneric, ConnectResumeClientServerTicketOnly) { +TEST_P(TlsConnectGenericResumption, ConnectResumeClientServerTicketOnly) { // This causes no resumption because the client needs the // session cache to resume even with tickets. ConfigureSessionCache(RESUME_TICKET, RESUME_TICKET); @@ -146,7 +147,7 @@ TEST_P(TlsConnectGeneric, ConnectResumeClientServerTicketOnly) { SendReceive(); } -TEST_P(TlsConnectGeneric, ConnectResumeClientBothServerNone) { +TEST_P(TlsConnectGenericResumption, ConnectResumeClientBothServerNone) { ConfigureSessionCache(RESUME_BOTH, RESUME_NONE); Connect(); SendReceive(); @@ -158,7 +159,7 @@ TEST_P(TlsConnectGeneric, ConnectResumeClientBothServerNone) { SendReceive(); } -TEST_P(TlsConnectGeneric, ConnectResumeClientNoneServerBoth) { +TEST_P(TlsConnectGenericResumption, ConnectResumeClientNoneServerBoth) { ConfigureSessionCache(RESUME_NONE, RESUME_BOTH); Connect(); SendReceive(); @@ -201,7 +202,7 @@ TEST_P(TlsConnectGeneric, ConnectResumeClientBothTicketServerTicketForget) { SendReceive(); } -TEST_P(TlsConnectGeneric, ConnectWithExpiredTicketAtClient) { +TEST_P(TlsConnectGenericResumption, ConnectWithExpiredTicketAtClient) { SSLInt_SetTicketLifetime(1); // one second // This causes a ticket resumption. ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET); @@ -218,8 +219,7 @@ TEST_P(TlsConnectGeneric, ConnectWithExpiredTicketAtClient) { SSLExtensionType xtn = (version_ >= SSL_LIBRARY_VERSION_TLS_1_3) ? ssl_tls13_pre_shared_key_xtn : ssl_session_ticket_xtn; - auto capture = std::make_shared<TlsExtensionCapture>(xtn); - client_->SetPacketFilter(capture); + auto capture = MakeTlsFilter<TlsExtensionCapture>(client_, xtn); Connect(); if (version_ >= SSL_LIBRARY_VERSION_TLS_1_3) { @@ -244,10 +244,8 @@ TEST_P(TlsConnectGeneric, ConnectWithExpiredTicketAtServer) { SSLExtensionType xtn = (version_ >= SSL_LIBRARY_VERSION_TLS_1_3) ? ssl_tls13_pre_shared_key_xtn : ssl_session_ticket_xtn; - auto capture = std::make_shared<TlsExtensionCapture>(xtn); - client_->SetPacketFilter(capture); - client_->StartConnect(); - server_->StartConnect(); + auto capture = MakeTlsFilter<TlsExtensionCapture>(client_, xtn); + StartConnect(); client_->Handshake(); EXPECT_TRUE(capture->captured()); EXPECT_LT(0U, capture->extension().len()); @@ -327,25 +325,23 @@ TEST_P(TlsConnectGeneric, ServerSNICertTypeSwitch) { // Prior to TLS 1.3, we were not fully ephemeral; though 1.3 fixes that TEST_P(TlsConnectGenericPre13, ConnectEcdheTwiceReuseKey) { - auto i1 = std::make_shared<TlsInspectorRecordHandshakeMessage>( - kTlsHandshakeServerKeyExchange); - server_->SetPacketFilter(i1); + auto filter = MakeTlsFilter<TlsHandshakeRecorder>( + server_, kTlsHandshakeServerKeyExchange); Connect(); CheckKeys(); TlsServerKeyExchangeEcdhe dhe1; - EXPECT_TRUE(dhe1.Parse(i1->buffer())); + EXPECT_TRUE(dhe1.Parse(filter->buffer())); // Restart Reset(); - auto i2 = std::make_shared<TlsInspectorRecordHandshakeMessage>( - kTlsHandshakeServerKeyExchange); - server_->SetPacketFilter(i2); + auto filter2 = MakeTlsFilter<TlsHandshakeRecorder>( + server_, kTlsHandshakeServerKeyExchange); ConfigureSessionCache(RESUME_NONE, RESUME_NONE); Connect(); CheckKeys(); TlsServerKeyExchangeEcdhe dhe2; - EXPECT_TRUE(dhe2.Parse(i2->buffer())); + EXPECT_TRUE(dhe2.Parse(filter2->buffer())); // Make sure they are the same. EXPECT_EQ(dhe1.public_key_.len(), dhe2.public_key_.len()); @@ -355,32 +351,25 @@ TEST_P(TlsConnectGenericPre13, ConnectEcdheTwiceReuseKey) { // This test parses the ServerKeyExchange, which isn't in 1.3 TEST_P(TlsConnectGenericPre13, ConnectEcdheTwiceNewKey) { - server_->EnsureTlsSetup(); - SECStatus rv = - SSL_OptionSet(server_->ssl_fd(), SSL_REUSE_SERVER_ECDHE_KEY, PR_FALSE); - EXPECT_EQ(SECSuccess, rv); - auto i1 = std::make_shared<TlsInspectorRecordHandshakeMessage>( - kTlsHandshakeServerKeyExchange); - server_->SetPacketFilter(i1); + server_->SetOption(SSL_REUSE_SERVER_ECDHE_KEY, PR_FALSE); + auto filter = MakeTlsFilter<TlsHandshakeRecorder>( + server_, kTlsHandshakeServerKeyExchange); Connect(); CheckKeys(); TlsServerKeyExchangeEcdhe dhe1; - EXPECT_TRUE(dhe1.Parse(i1->buffer())); + EXPECT_TRUE(dhe1.Parse(filter->buffer())); // Restart Reset(); - server_->EnsureTlsSetup(); - rv = SSL_OptionSet(server_->ssl_fd(), SSL_REUSE_SERVER_ECDHE_KEY, PR_FALSE); - EXPECT_EQ(SECSuccess, rv); - auto i2 = std::make_shared<TlsInspectorRecordHandshakeMessage>( - kTlsHandshakeServerKeyExchange); - server_->SetPacketFilter(i2); + server_->SetOption(SSL_REUSE_SERVER_ECDHE_KEY, PR_FALSE); + auto filter2 = MakeTlsFilter<TlsHandshakeRecorder>( + server_, kTlsHandshakeServerKeyExchange); ConfigureSessionCache(RESUME_NONE, RESUME_NONE); Connect(); CheckKeys(); TlsServerKeyExchangeEcdhe dhe2; - EXPECT_TRUE(dhe2.Parse(i2->buffer())); + EXPECT_TRUE(dhe2.Parse(filter2->buffer())); // Make sure they are different. EXPECT_FALSE((dhe1.public_key_.len() == dhe2.public_key_.len()) && @@ -401,7 +390,8 @@ TEST_P(TlsConnectTls13, TestTls13ResumeDifferentGroup) { client_->ConfigNamedGroups(kFFDHEGroups); server_->ConfigNamedGroups(kFFDHEGroups); Connect(); - CheckKeys(ssl_kea_dh, ssl_grp_ffdhe_2048, ssl_auth_rsa_sign, ssl_sig_none); + CheckKeys(ssl_kea_dh, ssl_grp_ffdhe_2048, ssl_auth_rsa_sign, + ssl_sig_rsa_pss_rsae_sha256); } // We need to enable different cipher suites at different times in the following @@ -421,7 +411,7 @@ static uint16_t ChooseAnotherCipher(uint16_t version) { } // Test that we don't resume when we can't negotiate the same cipher. -TEST_P(TlsConnectGeneric, TestResumeClientDifferentCipher) { +TEST_P(TlsConnectGenericResumption, TestResumeClientDifferentCipher) { ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET); client_->EnableSingleCipher(ChooseOneCipher(version_)); Connect(); @@ -438,15 +428,15 @@ TEST_P(TlsConnectGeneric, TestResumeClientDifferentCipher) { } else { ticket_extension = ssl_session_ticket_xtn; } - auto ticket_capture = std::make_shared<TlsExtensionCapture>(ticket_extension); - client_->SetPacketFilter(ticket_capture); + auto ticket_capture = + MakeTlsFilter<TlsExtensionCapture>(client_, ticket_extension); Connect(); CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign); EXPECT_EQ(0U, ticket_capture->extension().len()); } // Test that we don't resume when we can't negotiate the same cipher. -TEST_P(TlsConnectGeneric, TestResumeServerDifferentCipher) { +TEST_P(TlsConnectGenericResumption, TestResumeServerDifferentCipher) { ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET); server_->EnableSingleCipher(ChooseOneCipher(version_)); Connect(); @@ -461,36 +451,6 @@ TEST_P(TlsConnectGeneric, TestResumeServerDifferentCipher) { CheckKeys(); } -class SelectedCipherSuiteReplacer : public TlsHandshakeFilter { - public: - SelectedCipherSuiteReplacer(uint16_t suite) : cipher_suite_(suite) {} - - protected: - PacketFilter::Action FilterHandshake(const HandshakeHeader& header, - const DataBuffer& input, - DataBuffer* output) override { - if (header.handshake_type() != kTlsHandshakeServerHello) { - return KEEP; - } - - *output = input; - uint32_t temp = 0; - EXPECT_TRUE(input.Read(0, 2, &temp)); - // Cipher suite is after version(2) and random(32). - size_t pos = 34; - if (temp < SSL_LIBRARY_VERSION_TLS_1_3) { - // In old versions, we have to skip a session_id too. - EXPECT_TRUE(input.Read(pos, 1, &temp)); - pos += 1 + temp; - } - output->Write(pos, static_cast<uint32_t>(cipher_suite_), 2); - return CHANGE; - } - - private: - uint16_t cipher_suite_; -}; - // Test that the client doesn't tolerate the server picking a different cipher // suite for resumption. TEST_P(TlsConnectStream, TestResumptionOverrideCipher) { @@ -502,8 +462,8 @@ TEST_P(TlsConnectStream, TestResumptionOverrideCipher) { Reset(); ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET); - server_->SetPacketFilter(std::make_shared<SelectedCipherSuiteReplacer>( - ChooseAnotherCipher(version_))); + MakeTlsFilter<SelectedCipherSuiteReplacer>(server_, + ChooseAnotherCipher(version_)); if (version_ >= SSL_LIBRARY_VERSION_TLS_1_3) { client_->ExpectSendAlert(kTlsAlertIllegalParameter); @@ -524,16 +484,15 @@ TEST_P(TlsConnectStream, TestResumptionOverrideCipher) { class SelectedVersionReplacer : public TlsHandshakeFilter { public: - SelectedVersionReplacer(uint16_t version) : version_(version) {} + SelectedVersionReplacer(const std::shared_ptr<TlsAgent>& agent, + uint16_t version) + : TlsHandshakeFilter(agent, {kTlsHandshakeServerHello}), + version_(version) {} protected: PacketFilter::Action FilterHandshake(const HandshakeHeader& header, const DataBuffer& input, DataBuffer* output) override { - if (header.handshake_type() != kTlsHandshakeServerHello) { - return KEEP; - } - *output = input; output->Write(0, static_cast<uint32_t>(version_), 2); return CHANGE; @@ -580,8 +539,7 @@ TEST_P(TlsConnectGenericPre13, TestResumptionOverrideVersion) { // Enable the lower version on the client. client_->SetVersionRange(version_ - 1, version_); server_->EnableSingleCipher(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA); - server_->SetPacketFilter( - std::make_shared<SelectedVersionReplacer>(override_version)); + MakeTlsFilter<SelectedVersionReplacer>(server_, override_version); ConnectExpectAlert(client_, kTlsAlertHandshakeFailure); client_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_SERVER_HELLO); @@ -604,12 +562,12 @@ TEST_F(TlsConnectTest, TestTls13ResumptionTwice) { ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET); ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3); ExpectResumption(RESUME_TICKET); - auto c1 = std::make_shared<TlsExtensionCapture>(ssl_tls13_pre_shared_key_xtn); - client_->SetPacketFilter(c1); + auto c1 = + MakeTlsFilter<TlsExtensionCapture>(client_, ssl_tls13_pre_shared_key_xtn); Connect(); SendReceive(); CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_rsa_sign, - ssl_sig_none); + ssl_sig_rsa_pss_rsae_sha256); // The filter will go away when we reset, so save the captured extension. DataBuffer initialTicket(c1->extension()); ASSERT_LT(0U, initialTicket.len()); @@ -621,13 +579,13 @@ TEST_F(TlsConnectTest, TestTls13ResumptionTwice) { ClearStats(); ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET); ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3); - auto c2 = std::make_shared<TlsExtensionCapture>(ssl_tls13_pre_shared_key_xtn); - client_->SetPacketFilter(c2); + auto c2 = + MakeTlsFilter<TlsExtensionCapture>(client_, ssl_tls13_pre_shared_key_xtn); ExpectResumption(RESUME_TICKET); Connect(); SendReceive(); CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_rsa_sign, - ssl_sig_none); + ssl_sig_rsa_pss_rsae_sha256); ASSERT_LT(0U, c2->extension().len()); ScopedCERTCertificate cert2(SSL_PeerCertificate(client_->ssl_fd())); @@ -652,7 +610,7 @@ TEST_F(TlsConnectTest, TestTls13ResumptionDuplicateNST) { // Clear the session ticket keys to invalidate the old ticket. SSLInt_ClearSelfEncryptKey(); - SSLInt_SendNewSessionTicket(server_->ssl_fd()); + SSL_SendSessionTicket(server_->ssl_fd(), NULL, 0); SendReceive(); // Need to read so that we absorb the session tickets. CheckKeys(); @@ -666,6 +624,144 @@ TEST_F(TlsConnectTest, TestTls13ResumptionDuplicateNST) { SendReceive(); } +// Check that the value captured in a NewSessionTicket message matches the value +// captured from a pre_shared_key extension. +void NstTicketMatchesPskIdentity(const DataBuffer& nst, const DataBuffer& psk) { + uint32_t len; + + size_t offset = 4 + 4; // Skip ticket_lifetime and ticket_age_add. + ASSERT_TRUE(nst.Read(offset, 1, &len)); + offset += 1 + len; // Skip ticket_nonce. + + ASSERT_TRUE(nst.Read(offset, 2, &len)); + offset += 2; // Skip the ticket length. + ASSERT_LE(offset + len, nst.len()); + DataBuffer nst_ticket(nst.data() + offset, static_cast<size_t>(len)); + + offset = 2; // Skip the identities length. + ASSERT_TRUE(psk.Read(offset, 2, &len)); + offset += 2; // Skip the identity length. + ASSERT_LE(offset + len, psk.len()); + DataBuffer psk_ticket(psk.data() + offset, static_cast<size_t>(len)); + + EXPECT_EQ(nst_ticket, psk_ticket); +} + +TEST_F(TlsConnectTest, TestTls13ResumptionDuplicateNSTWithToken) { + ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET); + ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3); + + auto nst_capture = + MakeTlsFilter<TlsHandshakeRecorder>(server_, ssl_hs_new_session_ticket); + nst_capture->EnableDecryption(); + Connect(); + + // Clear the session ticket keys to invalidate the old ticket. + SSLInt_ClearSelfEncryptKey(); + nst_capture->Reset(); + uint8_t token[] = {0x20, 0x20, 0xff, 0x00}; + EXPECT_EQ(SECSuccess, + SSL_SendSessionTicket(server_->ssl_fd(), token, sizeof(token))); + + SendReceive(); // Need to read so that we absorb the session tickets. + CheckKeys(); + EXPECT_LT(0U, nst_capture->buffer().len()); + + // Resume the connection. + Reset(); + ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET); + ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3); + ExpectResumption(RESUME_TICKET); + + auto psk_capture = + MakeTlsFilter<TlsExtensionCapture>(client_, ssl_tls13_pre_shared_key_xtn); + Connect(); + SendReceive(); + + NstTicketMatchesPskIdentity(nst_capture->buffer(), psk_capture->extension()); +} + +// Disable SSL_ENABLE_SESSION_TICKETS but ensure that tickets can still be sent +// by invoking SSL_SendSessionTicket directly (and that the ticket is usable). +TEST_F(TlsConnectTest, SendSessionTicketWithTicketsDisabled) { + ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET); + ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3); + + EXPECT_EQ(SECSuccess, SSL_OptionSet(server_->ssl_fd(), + SSL_ENABLE_SESSION_TICKETS, PR_FALSE)); + + auto nst_capture = + MakeTlsFilter<TlsHandshakeRecorder>(server_, ssl_hs_new_session_ticket); + nst_capture->EnableDecryption(); + Connect(); + + EXPECT_EQ(0U, nst_capture->buffer().len()) << "expect nothing captured yet"; + + EXPECT_EQ(SECSuccess, SSL_SendSessionTicket(server_->ssl_fd(), NULL, 0)); + EXPECT_LT(0U, nst_capture->buffer().len()) << "should capture now"; + + SendReceive(); // Ensure that the client reads the ticket. + + // Resume the connection. + Reset(); + ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET); + ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3); + ExpectResumption(RESUME_TICKET); + + auto psk_capture = + MakeTlsFilter<TlsExtensionCapture>(client_, ssl_tls13_pre_shared_key_xtn); + Connect(); + SendReceive(); + + NstTicketMatchesPskIdentity(nst_capture->buffer(), psk_capture->extension()); +} + +// Test calling SSL_SendSessionTicket in inappropriate conditions. +TEST_F(TlsConnectTest, SendSessionTicketInappropriate) { + ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET); + ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_2); + + EXPECT_EQ(SECFailure, SSL_SendSessionTicket(client_->ssl_fd(), NULL, 0)) + << "clients can't send tickets"; + EXPECT_EQ(SEC_ERROR_INVALID_ARGS, PORT_GetError()); + + StartConnect(); + + EXPECT_EQ(SECFailure, SSL_SendSessionTicket(server_->ssl_fd(), NULL, 0)) + << "no ticket before the handshake has started"; + EXPECT_EQ(SEC_ERROR_INVALID_ARGS, PORT_GetError()); + Handshake(); + EXPECT_EQ(SECFailure, SSL_SendSessionTicket(server_->ssl_fd(), NULL, 0)) + << "no special tickets in TLS 1.2"; + EXPECT_EQ(SEC_ERROR_INVALID_ARGS, PORT_GetError()); +} + +TEST_F(TlsConnectTest, SendSessionTicketMassiveToken) { + ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET); + ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3); + Connect(); + // It should be safe to set length with a NULL token because the length should + // be checked before reading token. + EXPECT_EQ(SECFailure, SSL_SendSessionTicket(server_->ssl_fd(), NULL, 0x1ffff)) + << "this is clearly too big"; + EXPECT_EQ(SEC_ERROR_INVALID_ARGS, PORT_GetError()); + + static const uint8_t big_token[0xffff] = {1}; + EXPECT_EQ(SECFailure, SSL_SendSessionTicket(server_->ssl_fd(), big_token, + sizeof(big_token))) + << "this is too big, but that's not immediately obvious"; + EXPECT_EQ(SEC_ERROR_INVALID_ARGS, PORT_GetError()); +} + +TEST_F(TlsConnectDatagram13, SendSessionTicketDtls) { + ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET); + ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3); + Connect(); + EXPECT_EQ(SECFailure, SSL_SendSessionTicket(server_->ssl_fd(), NULL, 0)) + << "no extra tickets in DTLS until we have Ack support"; + EXPECT_EQ(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_VERSION, PORT_GetError()); +} + TEST_F(TlsConnectTest, TestTls13ResumptionDowngrade) { ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET); ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3); @@ -716,16 +812,220 @@ TEST_F(TlsConnectTest, TestTls13ResumptionForcedDowngrade) { // We will eventually fail the (sid.version == SH.version) check. std::vector<std::shared_ptr<PacketFilter>> filters; filters.push_back(std::make_shared<SelectedCipherSuiteReplacer>( - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256)); + server_, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256)); + filters.push_back(std::make_shared<SelectedVersionReplacer>( + server_, SSL_LIBRARY_VERSION_TLS_1_2)); + + // Drop a bunch of extensions so that we get past the SH processing. The + // version extension says TLS 1.3, which is counter to our goal, the others + // are not permitted in TLS 1.2 handshakes. + filters.push_back(std::make_shared<TlsExtensionDropper>( + server_, ssl_tls13_supported_versions_xtn)); filters.push_back( - std::make_shared<SelectedVersionReplacer>(SSL_LIBRARY_VERSION_TLS_1_2)); - server_->SetPacketFilter(std::make_shared<ChainedPacketFilter>(filters)); - - client_->ExpectSendAlert(kTlsAlertDecodeError); + std::make_shared<TlsExtensionDropper>(server_, ssl_tls13_key_share_xtn)); + filters.push_back(std::make_shared<TlsExtensionDropper>( + server_, ssl_tls13_pre_shared_key_xtn)); + server_->SetFilter(std::make_shared<ChainedPacketFilter>(filters)); + + // The client here generates an unexpected_message alert when it receives an + // encrypted handshake message from the server (EncryptedExtension). The + // client expects to receive an unencrypted TLS 1.2 Certificate message. + // The server can't decrypt the alert. + client_->ExpectSendAlert(kTlsAlertUnexpectedMessage); server_->ExpectSendAlert(kTlsAlertBadRecordMac); // Server can't read ConnectExpectFail(); - client_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_SERVER_HELLO); + client_->CheckErrorCode(SSL_ERROR_RX_UNEXPECTED_APPLICATION_DATA); server_->CheckErrorCode(SSL_ERROR_BAD_MAC_READ); } +TEST_P(TlsConnectGenericResumption, ReConnectTicket) { + ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH); + server_->EnableSingleCipher(ChooseOneCipher(version_)); + Connect(); + SendReceive(); + CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_rsa_sign, + ssl_sig_rsa_pss_rsae_sha256); + // Resume + Reset(); + ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH); + ExpectResumption(RESUME_TICKET); + Connect(); + // Only the client knows this. + CheckKeysResumption(ssl_kea_ecdh, ssl_grp_none, ssl_grp_ec_curve25519, + ssl_auth_rsa_sign, ssl_sig_rsa_pss_rsae_sha256); +} + +TEST_P(TlsConnectGenericPre13, ReConnectCache) { + ConfigureSessionCache(RESUME_SESSIONID, RESUME_SESSIONID); + server_->EnableSingleCipher(ChooseOneCipher(version_)); + Connect(); + SendReceive(); + CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_rsa_sign, + ssl_sig_rsa_pss_rsae_sha256); + // Resume + Reset(); + ExpectResumption(RESUME_SESSIONID); + Connect(); + CheckKeysResumption(ssl_kea_ecdh, ssl_grp_none, ssl_grp_ec_curve25519, + ssl_auth_rsa_sign, ssl_sig_rsa_pss_rsae_sha256); +} + +TEST_P(TlsConnectGenericResumption, ReConnectAgainTicket) { + ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH); + server_->EnableSingleCipher(ChooseOneCipher(version_)); + Connect(); + SendReceive(); + CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_rsa_sign, + ssl_sig_rsa_pss_rsae_sha256); + // Resume + Reset(); + ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH); + ExpectResumption(RESUME_TICKET); + Connect(); + // Only the client knows this. + CheckKeysResumption(ssl_kea_ecdh, ssl_grp_none, ssl_grp_ec_curve25519, + ssl_auth_rsa_sign, ssl_sig_rsa_pss_rsae_sha256); + // Resume connection again + Reset(); + ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH); + ExpectResumption(RESUME_TICKET, 2); + Connect(); + // Only the client knows this. + CheckKeysResumption(ssl_kea_ecdh, ssl_grp_none, ssl_grp_ec_curve25519, + ssl_auth_rsa_sign, ssl_sig_rsa_pss_rsae_sha256); +} + +void CheckGetInfoResult(uint32_t alpnSize, uint32_t earlyDataSize, + ScopedCERTCertificate& cert, + ScopedSSLResumptionTokenInfo& token) { + ASSERT_TRUE(cert); + ASSERT_TRUE(token->peerCert); + + // Check that the server cert is the correct one. + ASSERT_EQ(cert->derCert.len, token->peerCert->derCert.len); + EXPECT_EQ(0, memcmp(cert->derCert.data, token->peerCert->derCert.data, + cert->derCert.len)); + + ASSERT_EQ(alpnSize, token->alpnSelectionLen); + EXPECT_EQ(0, memcmp("a", token->alpnSelection, token->alpnSelectionLen)); + + ASSERT_EQ(earlyDataSize, token->maxEarlyDataSize); +} + +TEST_P(TlsConnectGenericResumptionToken, ConnectResumeGetInfo) { + ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH); + Connect(); + SendReceive(); + + Reset(); + ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH); + ExpectResumption(RESUME_TICKET); + + StartConnect(); + ASSERT_TRUE(client_->MaybeSetResumptionToken()); + + // Get resumption token infos + SSLResumptionTokenInfo tokenInfo = {0}; + ScopedSSLResumptionTokenInfo token(&tokenInfo); + client_->GetTokenInfo(token); + ScopedCERTCertificate cert( + PK11_FindCertFromNickname(server_->name().c_str(), nullptr)); + + CheckGetInfoResult(0, 0, cert, token); + + Handshake(); + CheckConnected(); + + SendReceive(); +} + +TEST_P(TlsConnectGenericResumptionToken, ConnectResumeGetInfoAlpn) { + EnableAlpn(); + ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH); + Connect(); + CheckAlpn("a"); + SendReceive(); + + Reset(); + EnableAlpn(); + ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH); + ExpectResumption(RESUME_TICKET); + + StartConnect(); + ASSERT_TRUE(client_->MaybeSetResumptionToken()); + + // Get resumption token infos + SSLResumptionTokenInfo tokenInfo = {0}; + ScopedSSLResumptionTokenInfo token(&tokenInfo); + client_->GetTokenInfo(token); + ScopedCERTCertificate cert( + PK11_FindCertFromNickname(server_->name().c_str(), nullptr)); + + CheckGetInfoResult(1, 0, cert, token); + + Handshake(); + CheckConnected(); + CheckAlpn("a"); + + SendReceive(); +} + +TEST_P(TlsConnectTls13ResumptionToken, ConnectResumeGetInfoZeroRtt) { + EnableAlpn(); + SSLInt_RolloverAntiReplay(); + ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH); + server_->Set0RttEnabled(true); + Connect(); + CheckAlpn("a"); + SendReceive(); + + Reset(); + EnableAlpn(); + ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH); + ExpectResumption(RESUME_TICKET); + + StartConnect(); + server_->Set0RttEnabled(true); + client_->Set0RttEnabled(true); + ASSERT_TRUE(client_->MaybeSetResumptionToken()); + + // Get resumption token infos + SSLResumptionTokenInfo tokenInfo = {0}; + ScopedSSLResumptionTokenInfo token(&tokenInfo); + client_->GetTokenInfo(token); + ScopedCERTCertificate cert( + PK11_FindCertFromNickname(server_->name().c_str(), nullptr)); + + CheckGetInfoResult(1, 1024, cert, token); + + ZeroRttSendReceive(true, true); + Handshake(); + ExpectEarlyDataAccepted(true); + CheckConnected(); + CheckAlpn("a"); + + SendReceive(); +} + +// Resumption on sessions with client authentication only works with internal +// caching. +TEST_P(TlsConnectGenericResumption, ConnectResumeClientAuth) { + ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH); + client_->SetupClientAuth(); + server_->RequestClientAuth(true); + Connect(); + SendReceive(); + EXPECT_FALSE(client_->resumption_callback_called()); + + Reset(); + ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH); + if (use_external_cache()) { + ExpectResumption(RESUME_NONE); + } else { + ExpectResumption(RESUME_TICKET); + } + Connect(); + SendReceive(); +} + } // namespace nss_test diff --git a/security/nss/gtests/ssl_gtest/ssl_skip_unittest.cc b/security/nss/gtests/ssl_gtest/ssl_skip_unittest.cc index a130ef77f..e4a9e5aed 100644 --- a/security/nss/gtests/ssl_gtest/ssl_skip_unittest.cc +++ b/security/nss/gtests/ssl_gtest/ssl_skip_unittest.cc @@ -22,8 +22,11 @@ namespace nss_test { class TlsHandshakeSkipFilter : public TlsRecordFilter { public: // A TLS record filter that skips handshake messages of the identified type. - TlsHandshakeSkipFilter(uint8_t handshake_type) - : handshake_type_(handshake_type), skipped_(false) {} + TlsHandshakeSkipFilter(const std::shared_ptr<TlsAgent>& agent, + uint8_t handshake_type) + : TlsRecordFilter(agent), + handshake_type_(handshake_type), + skipped_(false) {} protected: // Takes a record; if it is a handshake record, it removes the first handshake @@ -43,7 +46,14 @@ class TlsHandshakeSkipFilter : public TlsRecordFilter { size_t start = parser.consumed(); TlsHandshakeFilter::HandshakeHeader header; DataBuffer ignored; - if (!header.Parse(&parser, record_header, &ignored)) { + bool complete = false; + if (!header.Parse(&parser, record_header, DataBuffer(), &ignored, + &complete)) { + ADD_FAILURE() << "Error parsing handshake header"; + return KEEP; + } + if (!complete) { + ADD_FAILURE() << "Don't want to deal with fragmented input"; return KEEP; } @@ -85,9 +95,14 @@ class TlsSkipTest : public TlsConnectTestBase, TlsSkipTest() : TlsConnectTestBase(std::get<0>(GetParam()), std::get<1>(GetParam())) {} + void SetUp() override { + TlsConnectTestBase::SetUp(); + EnsureTlsSetup(); + } + void ServerSkipTest(std::shared_ptr<PacketFilter> filter, uint8_t alert = kTlsAlertUnexpectedMessage) { - server_->SetPacketFilter(filter); + server_->SetFilter(filter); ConnectExpectAlert(client_, alert); } }; @@ -98,29 +113,23 @@ class Tls13SkipTest : public TlsConnectTestBase, Tls13SkipTest() : TlsConnectTestBase(GetParam(), SSL_LIBRARY_VERSION_TLS_1_3) {} - void ServerSkipTest(std::shared_ptr<TlsRecordFilter> filter, int32_t error) { + void SetUp() override { + TlsConnectTestBase::SetUp(); EnsureTlsSetup(); - server_->SetTlsRecordFilter(filter); + } + + void ServerSkipTest(std::shared_ptr<TlsRecordFilter> filter, int32_t error) { filter->EnableDecryption(); - client_->ExpectSendAlert(kTlsAlertUnexpectedMessage); - if (variant_ == ssl_variant_stream) { - server_->ExpectSendAlert(kTlsAlertBadRecordMac); - ConnectExpectFail(); - } else { - ConnectExpectFailOneSide(TlsAgent::CLIENT); - } + server_->SetFilter(filter); + ExpectAlert(client_, kTlsAlertUnexpectedMessage); + ConnectExpectFail(); client_->CheckErrorCode(error); - if (variant_ == ssl_variant_stream) { - server_->CheckErrorCode(SSL_ERROR_BAD_MAC_READ); - } else { - ASSERT_EQ(TlsAgent::STATE_CONNECTING, server_->state()); - } + server_->CheckErrorCode(SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT); } void ClientSkipTest(std::shared_ptr<TlsRecordFilter> filter, int32_t error) { - EnsureTlsSetup(); - client_->SetTlsRecordFilter(filter); filter->EnableDecryption(); + client_->SetFilter(filter); server_->ExpectSendAlert(kTlsAlertUnexpectedMessage); ConnectExpectFailOneSide(TlsAgent::SERVER); @@ -133,49 +142,49 @@ class Tls13SkipTest : public TlsConnectTestBase, TEST_P(TlsSkipTest, SkipCertificateRsa) { EnableOnlyStaticRsaCiphers(); - ServerSkipTest( - std::make_shared<TlsHandshakeSkipFilter>(kTlsHandshakeCertificate)); + ServerSkipTest(std::make_shared<TlsHandshakeSkipFilter>( + server_, kTlsHandshakeCertificate)); client_->CheckErrorCode(SSL_ERROR_RX_UNEXPECTED_HELLO_DONE); } TEST_P(TlsSkipTest, SkipCertificateDhe) { - ServerSkipTest( - std::make_shared<TlsHandshakeSkipFilter>(kTlsHandshakeCertificate)); + ServerSkipTest(std::make_shared<TlsHandshakeSkipFilter>( + server_, kTlsHandshakeCertificate)); client_->CheckErrorCode(SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH); } TEST_P(TlsSkipTest, SkipCertificateEcdhe) { - ServerSkipTest( - std::make_shared<TlsHandshakeSkipFilter>(kTlsHandshakeCertificate)); + ServerSkipTest(std::make_shared<TlsHandshakeSkipFilter>( + server_, kTlsHandshakeCertificate)); client_->CheckErrorCode(SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH); } TEST_P(TlsSkipTest, SkipCertificateEcdsa) { Reset(TlsAgent::kServerEcdsa256); - ServerSkipTest( - std::make_shared<TlsHandshakeSkipFilter>(kTlsHandshakeCertificate)); + ServerSkipTest(std::make_shared<TlsHandshakeSkipFilter>( + server_, kTlsHandshakeCertificate)); client_->CheckErrorCode(SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH); } TEST_P(TlsSkipTest, SkipServerKeyExchange) { - ServerSkipTest( - std::make_shared<TlsHandshakeSkipFilter>(kTlsHandshakeServerKeyExchange)); + ServerSkipTest(std::make_shared<TlsHandshakeSkipFilter>( + server_, kTlsHandshakeServerKeyExchange)); client_->CheckErrorCode(SSL_ERROR_RX_UNEXPECTED_HELLO_DONE); } TEST_P(TlsSkipTest, SkipServerKeyExchangeEcdsa) { Reset(TlsAgent::kServerEcdsa256); - ServerSkipTest( - std::make_shared<TlsHandshakeSkipFilter>(kTlsHandshakeServerKeyExchange)); + ServerSkipTest(std::make_shared<TlsHandshakeSkipFilter>( + server_, kTlsHandshakeServerKeyExchange)); client_->CheckErrorCode(SSL_ERROR_RX_UNEXPECTED_HELLO_DONE); } TEST_P(TlsSkipTest, SkipCertAndKeyExch) { - auto chain = std::make_shared<ChainedPacketFilter>(); - chain->Add( - std::make_shared<TlsHandshakeSkipFilter>(kTlsHandshakeCertificate)); - chain->Add( - std::make_shared<TlsHandshakeSkipFilter>(kTlsHandshakeServerKeyExchange)); + auto chain = std::make_shared<ChainedPacketFilter>( + ChainedPacketFilterInit{std::make_shared<TlsHandshakeSkipFilter>( + server_, kTlsHandshakeCertificate), + std::make_shared<TlsHandshakeSkipFilter>( + server_, kTlsHandshakeServerKeyExchange)}); ServerSkipTest(chain); client_->CheckErrorCode(SSL_ERROR_RX_UNEXPECTED_HELLO_DONE); } @@ -183,48 +192,48 @@ TEST_P(TlsSkipTest, SkipCertAndKeyExch) { TEST_P(TlsSkipTest, SkipCertAndKeyExchEcdsa) { Reset(TlsAgent::kServerEcdsa256); auto chain = std::make_shared<ChainedPacketFilter>(); - chain->Add( - std::make_shared<TlsHandshakeSkipFilter>(kTlsHandshakeCertificate)); - chain->Add( - std::make_shared<TlsHandshakeSkipFilter>(kTlsHandshakeServerKeyExchange)); + chain->Add(std::make_shared<TlsHandshakeSkipFilter>( + server_, kTlsHandshakeCertificate)); + chain->Add(std::make_shared<TlsHandshakeSkipFilter>( + server_, kTlsHandshakeServerKeyExchange)); ServerSkipTest(chain); client_->CheckErrorCode(SSL_ERROR_RX_UNEXPECTED_HELLO_DONE); } TEST_P(Tls13SkipTest, SkipEncryptedExtensions) { ServerSkipTest(std::make_shared<TlsHandshakeSkipFilter>( - kTlsHandshakeEncryptedExtensions), + server_, kTlsHandshakeEncryptedExtensions), SSL_ERROR_RX_UNEXPECTED_CERTIFICATE); } TEST_P(Tls13SkipTest, SkipServerCertificate) { - ServerSkipTest( - std::make_shared<TlsHandshakeSkipFilter>(kTlsHandshakeCertificate), - SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY); + ServerSkipTest(std::make_shared<TlsHandshakeSkipFilter>( + server_, kTlsHandshakeCertificate), + SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY); } TEST_P(Tls13SkipTest, SkipServerCertificateVerify) { - ServerSkipTest( - std::make_shared<TlsHandshakeSkipFilter>(kTlsHandshakeCertificateVerify), - SSL_ERROR_RX_UNEXPECTED_FINISHED); + ServerSkipTest(std::make_shared<TlsHandshakeSkipFilter>( + server_, kTlsHandshakeCertificateVerify), + SSL_ERROR_RX_UNEXPECTED_FINISHED); } TEST_P(Tls13SkipTest, SkipClientCertificate) { client_->SetupClientAuth(); server_->RequestClientAuth(true); client_->ExpectReceiveAlert(kTlsAlertUnexpectedMessage); - ClientSkipTest( - std::make_shared<TlsHandshakeSkipFilter>(kTlsHandshakeCertificate), - SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY); + ClientSkipTest(std::make_shared<TlsHandshakeSkipFilter>( + client_, kTlsHandshakeCertificate), + SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY); } TEST_P(Tls13SkipTest, SkipClientCertificateVerify) { client_->SetupClientAuth(); server_->RequestClientAuth(true); client_->ExpectReceiveAlert(kTlsAlertUnexpectedMessage); - ClientSkipTest( - std::make_shared<TlsHandshakeSkipFilter>(kTlsHandshakeCertificateVerify), - SSL_ERROR_RX_UNEXPECTED_FINISHED); + ClientSkipTest(std::make_shared<TlsHandshakeSkipFilter>( + client_, kTlsHandshakeCertificateVerify), + SSL_ERROR_RX_UNEXPECTED_FINISHED); } INSTANTIATE_TEST_CASE_P( diff --git a/security/nss/gtests/ssl_gtest/ssl_staticrsa_unittest.cc b/security/nss/gtests/ssl_gtest/ssl_staticrsa_unittest.cc index 8db1f30e1..e5fccc12b 100644 --- a/security/nss/gtests/ssl_gtest/ssl_staticrsa_unittest.cc +++ b/security/nss/gtests/ssl_gtest/ssl_staticrsa_unittest.cc @@ -48,10 +48,9 @@ TEST_P(TlsConnectGenericPre13, ConnectStaticRSA) { // This test is stream so we can catch the bad_record_mac alert. TEST_P(TlsConnectStreamPre13, ConnectStaticRSABogusCKE) { EnableOnlyStaticRsaCiphers(); - auto i1 = std::make_shared<TlsInspectorReplaceHandshakeMessage>( - kTlsHandshakeClientKeyExchange, + MakeTlsFilter<TlsInspectorReplaceHandshakeMessage>( + client_, kTlsHandshakeClientKeyExchange, DataBuffer(kBogusClientKeyExchange, sizeof(kBogusClientKeyExchange))); - client_->SetPacketFilter(i1); ConnectExpectAlert(server_, kTlsAlertBadRecordMac); } @@ -59,8 +58,7 @@ TEST_P(TlsConnectStreamPre13, ConnectStaticRSABogusCKE) { // This test is stream so we can catch the bad_record_mac alert. TEST_P(TlsConnectStreamPre13, ConnectStaticRSABogusPMSVersionDetect) { EnableOnlyStaticRsaCiphers(); - client_->SetPacketFilter( - std::make_shared<TlsInspectorClientHelloVersionChanger>(server_)); + MakeTlsFilter<TlsClientHelloVersionChanger>(client_, server_); ConnectExpectAlert(server_, kTlsAlertBadRecordMac); } @@ -69,9 +67,8 @@ TEST_P(TlsConnectStreamPre13, ConnectStaticRSABogusPMSVersionDetect) { // ConnectStaticRSABogusPMSVersionDetect. TEST_P(TlsConnectGenericPre13, ConnectStaticRSABogusPMSVersionIgnore) { EnableOnlyStaticRsaCiphers(); - client_->SetPacketFilter( - std::make_shared<TlsInspectorClientHelloVersionChanger>(server_)); - server_->DisableRollbackDetection(); + MakeTlsFilter<TlsClientHelloVersionChanger>(client_, server_); + server_->SetOption(SSL_ROLLBACK_DETECTION, PR_FALSE); Connect(); } @@ -79,10 +76,9 @@ TEST_P(TlsConnectGenericPre13, ConnectStaticRSABogusPMSVersionIgnore) { TEST_P(TlsConnectStreamPre13, ConnectExtendedMasterSecretStaticRSABogusCKE) { EnableOnlyStaticRsaCiphers(); EnableExtendedMasterSecret(); - auto inspect = std::make_shared<TlsInspectorReplaceHandshakeMessage>( - kTlsHandshakeClientKeyExchange, + MakeTlsFilter<TlsInspectorReplaceHandshakeMessage>( + client_, kTlsHandshakeClientKeyExchange, DataBuffer(kBogusClientKeyExchange, sizeof(kBogusClientKeyExchange))); - client_->SetPacketFilter(inspect); ConnectExpectAlert(server_, kTlsAlertBadRecordMac); } @@ -91,8 +87,7 @@ TEST_P(TlsConnectStreamPre13, ConnectExtendedMasterSecretStaticRSABogusPMSVersionDetect) { EnableOnlyStaticRsaCiphers(); EnableExtendedMasterSecret(); - client_->SetPacketFilter( - std::make_shared<TlsInspectorClientHelloVersionChanger>(server_)); + MakeTlsFilter<TlsClientHelloVersionChanger>(client_, server_); ConnectExpectAlert(server_, kTlsAlertBadRecordMac); } @@ -100,10 +95,9 @@ TEST_P(TlsConnectStreamPre13, ConnectExtendedMasterSecretStaticRSABogusPMSVersionIgnore) { EnableOnlyStaticRsaCiphers(); EnableExtendedMasterSecret(); - client_->SetPacketFilter( - std::make_shared<TlsInspectorClientHelloVersionChanger>(server_)); - server_->DisableRollbackDetection(); + MakeTlsFilter<TlsClientHelloVersionChanger>(client_, server_); + server_->SetOption(SSL_ROLLBACK_DETECTION, PR_FALSE); Connect(); } -} // namespace nspr_test +} // 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 new file mode 100644 index 000000000..f5ccf096b --- /dev/null +++ b/security/nss/gtests/ssl_gtest/ssl_tls13compat_unittest.cc @@ -0,0 +1,363 @@ +/* -*- 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 <memory> +#include <vector> +#include "ssl.h" +#include "sslerr.h" +#include "sslproto.h" + +#include "gtest_utils.h" +#include "tls_connect.h" +#include "tls_filter.h" +#include "tls_parser.h" + +namespace nss_test { + +class Tls13CompatTest : public TlsConnectStreamTls13 { + protected: + void EnableCompatMode() { + client_->SetOption(SSL_ENABLE_TLS13_COMPAT_MODE, PR_TRUE); + } + + void InstallFilters() { + EnsureTlsSetup(); + client_recorders_.Install(client_); + server_recorders_.Install(server_); + } + + void CheckRecordVersions() { + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_0, + client_recorders_.records_->record(0).header.version()); + CheckRecordsAreTls12("client", client_recorders_.records_, 1); + CheckRecordsAreTls12("server", server_recorders_.records_, 0); + } + + void CheckHelloVersions() { + uint32_t ver; + ASSERT_TRUE(server_recorders_.hello_->buffer().Read(0, 2, &ver)); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_2, static_cast<uint16_t>(ver)); + ASSERT_TRUE(client_recorders_.hello_->buffer().Read(0, 2, &ver)); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_2, static_cast<uint16_t>(ver)); + } + + void CheckForCCS(bool expected_client, bool expected_server) { + client_recorders_.CheckForCCS(expected_client); + server_recorders_.CheckForCCS(expected_server); + } + + void CheckForRegularHandshake() { + CheckRecordVersions(); + CheckHelloVersions(); + EXPECT_EQ(0U, client_recorders_.session_id_length()); + EXPECT_EQ(0U, server_recorders_.session_id_length()); + CheckForCCS(false, false); + } + + void CheckForCompatHandshake() { + CheckRecordVersions(); + CheckHelloVersions(); + EXPECT_EQ(32U, client_recorders_.session_id_length()); + EXPECT_EQ(32U, server_recorders_.session_id_length()); + CheckForCCS(true, true); + } + + private: + struct Recorders { + Recorders() : records_(nullptr), hello_(nullptr) {} + + uint8_t session_id_length() const { + // session_id is always after version (2) and random (32). + uint32_t len = 0; + EXPECT_TRUE(hello_->buffer().Read(2 + 32, 1, &len)); + return static_cast<uint8_t>(len); + } + + void CheckForCCS(bool expected) const { + EXPECT_LT(0U, records_->count()); + for (size_t i = 0; i < records_->count(); ++i) { + // Only the second record can be a CCS. + bool expected_match = expected && (i == 1); + EXPECT_EQ(expected_match, + kTlsChangeCipherSpecType == + records_->record(i).header.content_type()); + } + } + + void Install(std::shared_ptr<TlsAgent>& agent) { + if (records_ && records_->agent() == agent) { + // Avoid replacing the filters if they are already installed on this + // agent. This ensures that InstallFilters() can be used after + // MakeNewServer() without losing state on the client filters. + return; + } + records_.reset(new TlsRecordRecorder(agent)); + hello_.reset(new TlsHandshakeRecorder( + agent, std::set<uint8_t>( + {kTlsHandshakeClientHello, kTlsHandshakeServerHello}))); + agent->SetFilter(std::make_shared<ChainedPacketFilter>( + ChainedPacketFilterInit({records_, hello_}))); + } + + std::shared_ptr<TlsRecordRecorder> records_; + std::shared_ptr<TlsHandshakeRecorder> hello_; + }; + + void CheckRecordsAreTls12(const std::string& agent, + const std::shared_ptr<TlsRecordRecorder>& records, + size_t start) { + EXPECT_LE(start, records->count()); + for (size_t i = start; i < records->count(); ++i) { + EXPECT_EQ(SSL_LIBRARY_VERSION_TLS_1_2, + records->record(i).header.version()) + << agent << ": record " << i << " has wrong version"; + } + } + + Recorders client_recorders_; + Recorders server_recorders_; +}; + +TEST_F(Tls13CompatTest, Disabled) { + InstallFilters(); + Connect(); + CheckForRegularHandshake(); +} + +TEST_F(Tls13CompatTest, Enabled) { + EnableCompatMode(); + InstallFilters(); + Connect(); + CheckForCompatHandshake(); +} + +TEST_F(Tls13CompatTest, EnabledZeroRtt) { + SetupForZeroRtt(); + EnableCompatMode(); + InstallFilters(); + + client_->Set0RttEnabled(true); + server_->Set0RttEnabled(true); + ExpectResumption(RESUME_TICKET); + ZeroRttSendReceive(true, true); + CheckForCCS(true, true); + Handshake(); + ExpectEarlyDataAccepted(true); + CheckConnected(); + + CheckForCompatHandshake(); +} + +TEST_F(Tls13CompatTest, EnabledHrr) { + EnableCompatMode(); + InstallFilters(); + + // Force a HelloRetryRequest. The server sends CCS immediately. + server_->ConfigNamedGroups({ssl_grp_ec_secp384r1}); + client_->StartConnect(); + server_->StartConnect(); + client_->Handshake(); + server_->Handshake(); + CheckForCCS(false, true); + + Handshake(); + CheckConnected(); + CheckForCompatHandshake(); +} + +TEST_F(Tls13CompatTest, EnabledStatelessHrr) { + EnableCompatMode(); + InstallFilters(); + + // Force a HelloRetryRequest + server_->ConfigNamedGroups({ssl_grp_ec_secp384r1}); + client_->StartConnect(); + server_->StartConnect(); + client_->Handshake(); + server_->Handshake(); + + // The server should send CCS before HRR. + CheckForCCS(false, true); + + // A new server should complete the handshake, and not send CCS. + MakeNewServer(); + InstallFilters(); + server_->ConfigNamedGroups({ssl_grp_ec_secp384r1}); + + Handshake(); + CheckConnected(); + CheckRecordVersions(); + CheckHelloVersions(); + CheckForCCS(true, false); +} + +TEST_F(Tls13CompatTest, EnabledHrrZeroRtt) { + SetupForZeroRtt(); + EnableCompatMode(); + InstallFilters(); + server_->ConfigNamedGroups({ssl_grp_ec_secp384r1}); + + // With 0-RTT, the client sends CCS immediately. With HRR, the server sends + // CCS immediately too. + client_->Set0RttEnabled(true); + server_->Set0RttEnabled(true); + ExpectResumption(RESUME_TICKET); + ZeroRttSendReceive(true, false); + CheckForCCS(true, true); + + Handshake(); + ExpectEarlyDataAccepted(false); + CheckConnected(); + CheckForCompatHandshake(); +} + +static const uint8_t kCannedCcs[] = { + kTlsChangeCipherSpecType, + SSL_LIBRARY_VERSION_TLS_1_2 >> 8, + SSL_LIBRARY_VERSION_TLS_1_2 & 0xff, + 0, + 1, // length + 1 // change_cipher_spec_choice +}; + +// A ChangeCipherSpec is ignored by a server because we have to tolerate it for +// compatibility mode. That doesn't mean that we have to tolerate it +// unconditionally. If we negotiate 1.3, we expect to see a cookie extension. +TEST_F(TlsConnectStreamTls13, ChangeCipherSpecBeforeClientHello13) { + EnsureTlsSetup(); + server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2, + SSL_LIBRARY_VERSION_TLS_1_3); + client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2, + SSL_LIBRARY_VERSION_TLS_1_3); + // Client sends CCS before starting the handshake. + client_->SendDirect(DataBuffer(kCannedCcs, sizeof(kCannedCcs))); + ConnectExpectAlert(server_, kTlsAlertUnexpectedMessage); + server_->CheckErrorCode(SSL_ERROR_RX_UNEXPECTED_CHANGE_CIPHER); + client_->CheckErrorCode(SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT); +} + +// A ChangeCipherSpec is ignored by a server because we have to tolerate it for +// compatibility mode. That doesn't mean that we have to tolerate it +// unconditionally. If we negotiate 1.3, we expect to see a cookie extension. +TEST_F(TlsConnectStreamTls13, ChangeCipherSpecBeforeClientHelloTwice) { + EnsureTlsSetup(); + server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2, + SSL_LIBRARY_VERSION_TLS_1_3); + client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2, + SSL_LIBRARY_VERSION_TLS_1_3); + // Client sends CCS before starting the handshake. + client_->SendDirect(DataBuffer(kCannedCcs, sizeof(kCannedCcs))); + client_->SendDirect(DataBuffer(kCannedCcs, sizeof(kCannedCcs))); + ConnectExpectAlert(server_, kTlsAlertUnexpectedMessage); + server_->CheckErrorCode(SSL_ERROR_RX_UNEXPECTED_CHANGE_CIPHER); + client_->CheckErrorCode(SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT); +} + +// If we negotiate 1.2, we abort. +TEST_F(TlsConnectStreamTls13, ChangeCipherSpecBeforeClientHello12) { + EnsureTlsSetup(); + server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2, + SSL_LIBRARY_VERSION_TLS_1_3); + client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2, + SSL_LIBRARY_VERSION_TLS_1_2); + // Client sends CCS before starting the handshake. + client_->SendDirect(DataBuffer(kCannedCcs, sizeof(kCannedCcs))); + ConnectExpectAlert(server_, kTlsAlertUnexpectedMessage); + server_->CheckErrorCode(SSL_ERROR_RX_UNEXPECTED_CHANGE_CIPHER); + client_->CheckErrorCode(SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT); +} + +TEST_F(TlsConnectDatagram13, CompatModeDtlsClient) { + EnsureTlsSetup(); + client_->SetOption(SSL_ENABLE_TLS13_COMPAT_MODE, PR_TRUE); + auto client_records = MakeTlsFilter<TlsRecordRecorder>(client_); + auto server_records = MakeTlsFilter<TlsRecordRecorder>(server_); + Connect(); + + ASSERT_EQ(2U, client_records->count()); // CH, Fin + EXPECT_EQ(kTlsHandshakeType, client_records->record(0).header.content_type()); + EXPECT_EQ(kTlsApplicationDataType, + client_records->record(1).header.content_type()); + + ASSERT_EQ(6U, server_records->count()); // SH, EE, CT, CV, Fin, Ack + EXPECT_EQ(kTlsHandshakeType, server_records->record(0).header.content_type()); + for (size_t i = 1; i < server_records->count(); ++i) { + EXPECT_EQ(kTlsApplicationDataType, + server_records->record(i).header.content_type()); + } +} + +class AddSessionIdFilter : public TlsHandshakeFilter { + public: + AddSessionIdFilter(const std::shared_ptr<TlsAgent>& client) + : TlsHandshakeFilter(client, {ssl_hs_client_hello}) {} + + protected: + PacketFilter::Action FilterHandshake(const HandshakeHeader& header, + const DataBuffer& input, + DataBuffer* output) override { + uint32_t session_id_len = 0; + EXPECT_TRUE(input.Read(2 + 32, 1, &session_id_len)); + EXPECT_EQ(0U, session_id_len); + uint8_t session_id[33] = {32}; // 32 for length, the rest zero. + *output = input; + output->Splice(session_id, sizeof(session_id), 34, 1); + return CHANGE; + } +}; + +// Adding a session ID to a DTLS ClientHello should not trigger compatibility +// mode. It should be ignored instead. +TEST_F(TlsConnectDatagram13, CompatModeDtlsServer) { + EnsureTlsSetup(); + auto client_records = std::make_shared<TlsRecordRecorder>(client_); + client_->SetFilter( + std::make_shared<ChainedPacketFilter>(ChainedPacketFilterInit( + {client_records, std::make_shared<AddSessionIdFilter>(client_)}))); + auto server_hello = + std::make_shared<TlsHandshakeRecorder>(server_, kTlsHandshakeServerHello); + auto server_records = std::make_shared<TlsRecordRecorder>(server_); + server_->SetFilter(std::make_shared<ChainedPacketFilter>( + ChainedPacketFilterInit({server_records, server_hello}))); + StartConnect(); + client_->Handshake(); + server_->Handshake(); + // The client will consume the ServerHello, but discard everything else + // because it doesn't decrypt. And don't wait around for the client to ACK. + client_->Handshake(); + + ASSERT_EQ(1U, client_records->count()); + EXPECT_EQ(kTlsHandshakeType, client_records->record(0).header.content_type()); + + ASSERT_EQ(5U, server_records->count()); // SH, EE, CT, CV, Fin + EXPECT_EQ(kTlsHandshakeType, server_records->record(0).header.content_type()); + for (size_t i = 1; i < server_records->count(); ++i) { + EXPECT_EQ(kTlsApplicationDataType, + server_records->record(i).header.content_type()); + } + + uint32_t session_id_len = 0; + EXPECT_TRUE(server_hello->buffer().Read(2 + 32, 1, &session_id_len)); + EXPECT_EQ(0U, session_id_len); +} + +TEST_F(Tls13CompatTest, ConnectWith12ThenAttemptToResume13CompatMode) { + ConfigureSessionCache(RESUME_SESSIONID, RESUME_SESSIONID); + ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_2); + Connect(); + + Reset(); + ExpectResumption(RESUME_NONE); + version_ = SSL_LIBRARY_VERSION_TLS_1_3; + 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_3); + EnableCompatMode(); + Connect(); +} + +} // namespace nss_test diff --git a/security/nss/gtests/ssl_gtest/ssl_v2_client_hello_unittest.cc b/security/nss/gtests/ssl_gtest/ssl_v2_client_hello_unittest.cc index 110e3e0b6..100595732 100644 --- a/security/nss/gtests/ssl_gtest/ssl_v2_client_hello_unittest.cc +++ b/security/nss/gtests/ssl_gtest/ssl_v2_client_hello_unittest.cc @@ -23,7 +23,8 @@ namespace nss_test { // Replaces the client hello with an SSLv2 version once. class SSLv2ClientHelloFilter : public PacketFilter { public: - SSLv2ClientHelloFilter(std::shared_ptr<TlsAgent>& client, uint16_t version) + SSLv2ClientHelloFilter(const std::shared_ptr<TlsAgent>& client, + uint16_t version) : replaced_(false), client_(client), version_(version), @@ -147,17 +148,9 @@ class SSLv2ClientHelloTestF : public TlsConnectTestBase { SSLv2ClientHelloTestF(SSLProtocolVariant variant, uint16_t version) : TlsConnectTestBase(variant, version), filter_(nullptr) {} - void SetUp() { + void SetUp() override { TlsConnectTestBase::SetUp(); - filter_ = std::make_shared<SSLv2ClientHelloFilter>(client_, version_); - client_->SetPacketFilter(filter_); - } - - void RequireSafeRenegotiation() { - server_->EnsureTlsSetup(); - SECStatus rv = - SSL_OptionSet(server_->ssl_fd(), SSL_REQUIRE_SAFE_NEGOTIATION, PR_TRUE); - EXPECT_EQ(rv, SECSuccess); + filter_ = MakeTlsFilter<SSLv2ClientHelloFilter>(client_, version_); } void SetExpectedVersion(uint16_t version) { @@ -319,7 +312,7 @@ TEST_P(SSLv2ClientHelloTest, BigClientRandom) { // Connection must fail if we require safe renegotiation but the client doesn't // include TLS_EMPTY_RENEGOTIATION_INFO_SCSV in the list of cipher suites. TEST_P(SSLv2ClientHelloTest, RequireSafeRenegotiation) { - RequireSafeRenegotiation(); + server_->SetOption(SSL_REQUIRE_SAFE_NEGOTIATION, PR_TRUE); SetAvailableCipherSuite(TLS_DHE_RSA_WITH_AES_128_CBC_SHA); ConnectExpectAlert(server_, kTlsAlertHandshakeFailure); EXPECT_EQ(SSL_ERROR_UNSAFE_NEGOTIATION, server_->error_code()); @@ -328,7 +321,7 @@ TEST_P(SSLv2ClientHelloTest, RequireSafeRenegotiation) { // Connection must succeed when requiring safe renegotiation and the client // includes TLS_EMPTY_RENEGOTIATION_INFO_SCSV in the list of cipher suites. TEST_P(SSLv2ClientHelloTest, RequireSafeRenegotiationWithSCSV) { - RequireSafeRenegotiation(); + server_->SetOption(SSL_REQUIRE_SAFE_NEGOTIATION, PR_TRUE); std::vector<uint16_t> cipher_suites = {TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV}; SetAvailableCipherSuites(cipher_suites); diff --git a/security/nss/gtests/ssl_gtest/ssl_version_unittest.cc b/security/nss/gtests/ssl_gtest/ssl_version_unittest.cc index 379a67e35..4e9099561 100644 --- a/security/nss/gtests/ssl_gtest/ssl_version_unittest.cc +++ b/security/nss/gtests/ssl_gtest/ssl_version_unittest.cc @@ -56,18 +56,15 @@ TEST_P(TlsConnectGeneric, ServerNegotiateTls12) { // two validate that we can also detect fallback using the // SSL_SetDowngradeCheckVersion() API. TEST_F(TlsConnectTest, TestDowngradeDetectionToTls11) { - client_->SetPacketFilter( - std::make_shared<TlsInspectorClientHelloVersionSetter>( - SSL_LIBRARY_VERSION_TLS_1_1)); + MakeTlsFilter<TlsClientHelloVersionSetter>(client_, + SSL_LIBRARY_VERSION_TLS_1_1); ConnectExpectFail(); ASSERT_EQ(SSL_ERROR_RX_MALFORMED_SERVER_HELLO, client_->error_code()); } /* Attempt to negotiate the bogus DTLS 1.1 version. */ TEST_F(DtlsConnectTest, TestDtlsVersion11) { - client_->SetPacketFilter( - std::make_shared<TlsInspectorClientHelloVersionSetter>( - ((~0x0101) & 0xffff))); + MakeTlsFilter<TlsClientHelloVersionSetter>(client_, ((~0x0101) & 0xffff)); ConnectExpectFail(); // It's kind of surprising that SSL_ERROR_NO_CYPHER_OVERLAP is // what is returned here, but this is deliberate in ssl3_HandleAlert(). @@ -78,9 +75,8 @@ TEST_F(DtlsConnectTest, TestDtlsVersion11) { // Disabled as long as we have draft version. TEST_F(TlsConnectTest, TestDowngradeDetectionToTls12) { EnsureTlsSetup(); - client_->SetPacketFilter( - std::make_shared<TlsInspectorClientHelloVersionSetter>( - SSL_LIBRARY_VERSION_TLS_1_2)); + MakeTlsFilter<TlsClientHelloVersionSetter>(client_, + SSL_LIBRARY_VERSION_TLS_1_2); client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2, SSL_LIBRARY_VERSION_TLS_1_3); server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2, @@ -92,9 +88,8 @@ TEST_F(TlsConnectTest, TestDowngradeDetectionToTls12) { // TLS 1.1 clients do not check the random values, so we should // instead get a handshake failure alert from the server. TEST_F(TlsConnectTest, TestDowngradeDetectionToTls10) { - client_->SetPacketFilter( - std::make_shared<TlsInspectorClientHelloVersionSetter>( - SSL_LIBRARY_VERSION_TLS_1_0)); + MakeTlsFilter<TlsClientHelloVersionSetter>(client_, + SSL_LIBRARY_VERSION_TLS_1_0); client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_0, SSL_LIBRARY_VERSION_TLS_1_1); server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_0, @@ -128,12 +123,12 @@ TEST_F(TlsConnectTest, TestFallbackFromTls13) { #endif TEST_P(TlsConnectGeneric, TestFallbackSCSVVersionMatch) { - client_->SetFallbackSCSVEnabled(true); + client_->SetOption(SSL_ENABLE_FALLBACK_SCSV, PR_TRUE); Connect(); } TEST_P(TlsConnectGenericPre13, TestFallbackSCSVVersionMismatch) { - client_->SetFallbackSCSVEnabled(true); + client_->SetOption(SSL_ENABLE_FALLBACK_SCSV, PR_TRUE); server_->SetVersionRange(version_, version_ + 1); ConnectExpectAlert(server_, kTlsAlertInappropriateFallback); client_->CheckErrorCode(SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT); @@ -155,107 +150,10 @@ TEST_F(TlsConnectTest, DisallowSSLv3HelloWithTLSv13Enabled) { EXPECT_EQ(SECFailure, rv); } -TEST_P(TlsConnectStream, ConnectTls10AndServerRenegotiateHigher) { - if (version_ == SSL_LIBRARY_VERSION_TLS_1_0) { - return; - } - // Set the client so it will accept any version from 1.0 - // to |version_|. - client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_0, version_); - server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_0, - SSL_LIBRARY_VERSION_TLS_1_0); - // Reset version so that the checks succeed. - uint16_t test_version = version_; - version_ = SSL_LIBRARY_VERSION_TLS_1_0; - Connect(); - - // Now renegotiate, with the server being set to do - // |version_|. - client_->PrepareForRenegotiate(); - server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_0, test_version); - // Reset version and cipher suite so that the preinfo callback - // doesn't fail. - server_->ResetPreliminaryInfo(); - server_->StartRenegotiate(); - - if (test_version >= SSL_LIBRARY_VERSION_TLS_1_3) { - ExpectAlert(server_, kTlsAlertUnexpectedMessage); - } else { - ExpectAlert(client_, kTlsAlertIllegalParameter); - } - - Handshake(); - if (test_version >= SSL_LIBRARY_VERSION_TLS_1_3) { - // In TLS 1.3, the server detects this problem. - client_->CheckErrorCode(SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT); - server_->CheckErrorCode(SSL_ERROR_RENEGOTIATION_NOT_ALLOWED); - } else { - client_->CheckErrorCode(SSL_ERROR_UNSUPPORTED_VERSION); - server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT); - } -} - -TEST_P(TlsConnectStream, ConnectTls10AndClientRenegotiateHigher) { - if (version_ == SSL_LIBRARY_VERSION_TLS_1_0) { - return; - } - // Set the client so it will accept any version from 1.0 - // to |version_|. - client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_0, version_); - server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_0, - SSL_LIBRARY_VERSION_TLS_1_0); - // Reset version so that the checks succeed. - uint16_t test_version = version_; - version_ = SSL_LIBRARY_VERSION_TLS_1_0; - Connect(); - - // Now renegotiate, with the server being set to do - // |version_|. - server_->PrepareForRenegotiate(); - server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_0, test_version); - // Reset version and cipher suite so that the preinfo callback - // doesn't fail. - server_->ResetPreliminaryInfo(); - client_->StartRenegotiate(); - if (test_version >= SSL_LIBRARY_VERSION_TLS_1_3) { - ExpectAlert(server_, kTlsAlertUnexpectedMessage); - } else { - ExpectAlert(client_, kTlsAlertIllegalParameter); - } - Handshake(); - if (test_version >= SSL_LIBRARY_VERSION_TLS_1_3) { - // In TLS 1.3, the server detects this problem. - client_->CheckErrorCode(SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT); - server_->CheckErrorCode(SSL_ERROR_RENEGOTIATION_NOT_ALLOWED); - } else { - client_->CheckErrorCode(SSL_ERROR_UNSUPPORTED_VERSION); - server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT); - } -} - -TEST_F(TlsConnectTest, Tls13RejectsRehandshakeClient) { - EnsureTlsSetup(); - ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3); - Connect(); - SECStatus rv = SSL_ReHandshake(client_->ssl_fd(), PR_TRUE); - EXPECT_EQ(SECFailure, rv); - EXPECT_EQ(SSL_ERROR_RENEGOTIATION_NOT_ALLOWED, PORT_GetError()); -} - -TEST_F(TlsConnectTest, Tls13RejectsRehandshakeServer) { - EnsureTlsSetup(); - ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3); - Connect(); - SECStatus rv = SSL_ReHandshake(server_->ssl_fd(), PR_TRUE); - EXPECT_EQ(SECFailure, rv); - EXPECT_EQ(SSL_ERROR_RENEGOTIATION_NOT_ALLOWED, PORT_GetError()); -} - TEST_P(TlsConnectGeneric, AlertBeforeServerHello) { EnsureTlsSetup(); client_->ExpectReceiveAlert(kTlsAlertUnrecognizedName, kTlsAlertWarning); - client_->StartConnect(); - server_->StartConnect(); + StartConnect(); client_->Handshake(); // Send ClientHello. static const uint8_t kWarningAlert[] = {kTlsAlertWarning, kTlsAlertUnrecognizedName}; @@ -274,12 +172,10 @@ class Tls13NoSupportedVersions : public TlsConnectStreamTls12 { client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2, SSL_LIBRARY_VERSION_TLS_1_2); server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2, max_server_version); - client_->SetPacketFilter( - std::make_shared<TlsInspectorClientHelloVersionSetter>( - overwritten_client_version)); - auto capture = std::make_shared<TlsInspectorRecordHandshakeMessage>( - kTlsHandshakeServerHello); - server_->SetPacketFilter(capture); + MakeTlsFilter<TlsClientHelloVersionSetter>(client_, + overwritten_client_version); + auto capture = + MakeTlsFilter<TlsHandshakeRecorder>(server_, kTlsHandshakeServerHello); ConnectExpectAlert(server_, kTlsAlertDecryptError); client_->CheckErrorCode(SSL_ERROR_DECRYPT_ERROR_ALERT); server_->CheckErrorCode(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE); @@ -311,23 +207,21 @@ TEST_F(Tls13NoSupportedVersions, // Offer 1.3 but with ClientHello.legacy_version == TLS 1.4. This // causes a bad MAC error when we read EncryptedExtensions. TEST_F(TlsConnectStreamTls13, Tls14ClientHelloWithSupportedVersions) { - client_->SetPacketFilter( - std::make_shared<TlsInspectorClientHelloVersionSetter>( - SSL_LIBRARY_VERSION_TLS_1_3 + 1)); - auto capture = std::make_shared<TlsInspectorRecordHandshakeMessage>( - kTlsHandshakeServerHello); - server_->SetPacketFilter(capture); + MakeTlsFilter<TlsClientHelloVersionSetter>(client_, + SSL_LIBRARY_VERSION_TLS_1_3 + 1); + auto capture = MakeTlsFilter<TlsExtensionCapture>( + server_, ssl_tls13_supported_versions_xtn); client_->ExpectSendAlert(kTlsAlertBadRecordMac); server_->ExpectSendAlert(kTlsAlertBadRecordMac); ConnectExpectFail(); client_->CheckErrorCode(SSL_ERROR_BAD_MAC_READ); server_->CheckErrorCode(SSL_ERROR_BAD_MAC_READ); - const DataBuffer& server_hello = capture->buffer(); - ASSERT_GT(server_hello.len(), 2U); - uint32_t ver; - ASSERT_TRUE(server_hello.Read(0, 2, &ver)); + + ASSERT_EQ(2U, capture->extension().len()); + uint32_t version = 0; + ASSERT_TRUE(capture->extension().Read(0, 2, &version)); // This way we don't need to change with new draft version. - ASSERT_LT(static_cast<uint32_t>(SSL_LIBRARY_VERSION_TLS_1_2), ver); + ASSERT_LT(static_cast<uint32_t>(SSL_LIBRARY_VERSION_TLS_1_2), version); } } // namespace nss_test diff --git a/security/nss/gtests/ssl_gtest/ssl_versionpolicy_unittest.cc b/security/nss/gtests/ssl_gtest/ssl_versionpolicy_unittest.cc index eda96831c..7f3c4a896 100644 --- a/security/nss/gtests/ssl_gtest/ssl_versionpolicy_unittest.cc +++ b/security/nss/gtests/ssl_gtest/ssl_versionpolicy_unittest.cc @@ -189,12 +189,12 @@ class TestPolicyVersionRange } } - void SetUp() { - SetPolicy(policy_.range()); + void SetUp() override { TlsConnectTestBase::SetUp(); + SetPolicy(policy_.range()); } - void TearDown() { + void TearDown() override { TlsConnectTestBase::TearDown(); saved_version_policy_.RestoreOriginalPolicy(); } diff --git a/security/nss/gtests/ssl_gtest/test_io.cc b/security/nss/gtests/ssl_gtest/test_io.cc index b9f0c672e..728217851 100644 --- a/security/nss/gtests/ssl_gtest/test_io.cc +++ b/security/nss/gtests/ssl_gtest/test_io.cc @@ -25,10 +25,6 @@ namespace nss_test { if (g_ssl_gtest_verbose) LOG(a); \ } while (false) -void DummyPrSocket::SetPacketFilter(std::shared_ptr<PacketFilter> filter) { - filter_ = filter; -} - ScopedPRFileDesc DummyPrSocket::CreateFD() { static PRDescIdentity test_fd_identity = PR_GetUniqueIdentity("testtransportadapter"); @@ -98,8 +94,13 @@ int32_t DummyPrSocket::Recv(PRFileDesc *f, void *buf, int32_t buflen, } int32_t DummyPrSocket::Write(PRFileDesc *f, const void *buf, int32_t length) { + if (write_error_) { + PR_SetError(write_error_, 0); + return -1; + } + auto peer = peer_.lock(); - if (!peer || !writeable_) { + if (!peer) { PR_SetError(PR_IO_ERROR, 0); return -1; } @@ -109,7 +110,7 @@ int32_t DummyPrSocket::Write(PRFileDesc *f, const void *buf, int32_t length) { DataBuffer filtered; PacketFilter::Action action = PacketFilter::KEEP; if (filter_) { - action = filter_->Filter(packet, &filtered); + action = filter_->Process(packet, &filtered); } switch (action) { case PacketFilter::CHANGE: diff --git a/security/nss/gtests/ssl_gtest/test_io.h b/security/nss/gtests/ssl_gtest/test_io.h index ac2497222..dbeb6b9d4 100644 --- a/security/nss/gtests/ssl_gtest/test_io.h +++ b/security/nss/gtests/ssl_gtest/test_io.h @@ -33,9 +33,18 @@ class PacketFilter { CHANGE, // change the packet to a different value DROP // drop the packet }; - + PacketFilter(bool enabled = true) : enabled_(enabled) {} virtual ~PacketFilter() {} + virtual Action Process(const DataBuffer& input, DataBuffer* output) { + if (!enabled_) { + return KEEP; + } + return Filter(input, output); + } + void Enable() { enabled_ = true; } + void Disable() { enabled_ = false; } + // The packet filter takes input and has the option of mutating it. // // A filter that modifies the data places the modified data in *output and @@ -43,6 +52,9 @@ class PacketFilter { // case the value in *output is ignored. A Filter can return DROP, in which // case the packet is dropped (and *output is ignored). virtual Action Filter(const DataBuffer& input, DataBuffer* output) = 0; + + private: + bool enabled_; }; class DummyPrSocket : public DummyIOLayerMethods { @@ -53,7 +65,7 @@ class DummyPrSocket : public DummyIOLayerMethods { peer_(), input_(), filter_(nullptr), - writeable_(true) {} + write_error_(0) {} virtual ~DummyPrSocket() {} // Create a file descriptor that will reference this object. The fd must not @@ -62,7 +74,9 @@ class DummyPrSocket : public DummyIOLayerMethods { std::weak_ptr<DummyPrSocket>& peer() { return peer_; } void SetPeer(const std::shared_ptr<DummyPrSocket>& peer) { peer_ = peer; } - void SetPacketFilter(std::shared_ptr<PacketFilter> filter); + void SetPacketFilter(const std::shared_ptr<PacketFilter>& filter) { + filter_ = filter; + } // Drops peer, packet filter and any outstanding packets. void Reset(); @@ -71,7 +85,7 @@ class DummyPrSocket : public DummyIOLayerMethods { int32_t Recv(PRFileDesc* f, void* buf, int32_t buflen, int32_t flags, PRIntervalTime to) override; int32_t Write(PRFileDesc* f, const void* buf, int32_t length) override; - void CloseWrites() { writeable_ = false; } + void SetWriteError(PRErrorCode code) { write_error_ = code; } SSLProtocolVariant variant() const { return variant_; } bool readable() const { return !input_.empty(); } @@ -98,7 +112,7 @@ class DummyPrSocket : public DummyIOLayerMethods { std::weak_ptr<DummyPrSocket> peer_; std::queue<Packet> input_; std::shared_ptr<PacketFilter> filter_; - bool writeable_; + PRErrorCode write_error_; }; // Marker interface. @@ -164,6 +178,6 @@ class Poller { timers_; }; -} // end of namespace +} // namespace nss_test #endif diff --git a/security/nss/gtests/ssl_gtest/tls_agent.cc b/security/nss/gtests/ssl_gtest/tls_agent.cc index d6d91f7f7..2f71caedb 100644 --- a/security/nss/gtests/ssl_gtest/tls_agent.cc +++ b/security/nss/gtests/ssl_gtest/tls_agent.cc @@ -10,7 +10,9 @@ #include "pk11func.h" #include "ssl.h" #include "sslerr.h" +#include "sslexp.h" #include "sslproto.h" +#include "tls_filter.h" #include "tls_parser.h" extern "C" { @@ -35,7 +37,6 @@ const std::string TlsAgent::kServerRsa = "rsa"; // both sign and encrypt const std::string TlsAgent::kServerRsaSign = "rsa_sign"; const std::string TlsAgent::kServerRsaPss = "rsa_pss"; const std::string TlsAgent::kServerRsaDecrypt = "rsa_decrypt"; -const std::string TlsAgent::kServerRsaChain = "rsa_chain"; const std::string TlsAgent::kServerEcdsa256 = "ecdsa256"; const std::string TlsAgent::kServerEcdsa384 = "ecdsa384"; const std::string TlsAgent::kServerEcdsa521 = "ecdsa521"; @@ -66,6 +67,7 @@ TlsAgent::TlsAgent(const std::string& name, Role role, expected_sent_alert_(kTlsAlertCloseNotify), expected_sent_alert_level_(kTlsAlertWarning), handshake_callback_called_(false), + resumption_callback_called_(false), error_code_(0), send_ctr_(0), recv_ctr_(0), @@ -73,8 +75,8 @@ TlsAgent::TlsAgent(const std::string& name, Role role, handshake_callback_(), auth_certificate_callback_(), sni_callback_(), - expect_short_headers_(false), - skip_version_checks_(false) { + skip_version_checks_(false), + resumption_token_() { memset(&info_, 0, sizeof(info_)); memset(&csinfo_, 0, sizeof(csinfo_)); SECStatus rv = SSL_VersionRangeGetDefault(variant_, &vrange_); @@ -93,11 +95,11 @@ TlsAgent::~TlsAgent() { // Add failures manually, if any, so we don't throw in a destructor. if (expected_received_alert_ != kTlsAlertCloseNotify || expected_received_alert_level_ != kTlsAlertWarning) { - ADD_FAILURE() << "Wrong expected_received_alert status"; + ADD_FAILURE() << "Wrong expected_received_alert status: " << role_str(); } if (expected_sent_alert_ != kTlsAlertCloseNotify || expected_sent_alert_level_ != kTlsAlertWarning) { - ADD_FAILURE() << "Wrong expected_sent_alert status"; + ADD_FAILURE() << "Wrong expected_sent_alert status: " << role_str(); } } @@ -183,6 +185,10 @@ bool TlsAgent::EnsureTlsSetup(PRFileDesc* modelSocket) { 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; } else { rv = SSL_SetURL(ssl_fd(), "server"); EXPECT_EQ(SECSuccess, rv); @@ -208,6 +214,29 @@ bool TlsAgent::EnsureTlsSetup(PRFileDesc* modelSocket) { return true; } +bool TlsAgent::MaybeSetResumptionToken() { + if (!resumption_token_.empty()) { + SECStatus rv = SSL_SetResumptionToken(ssl_fd(), resumption_token_.data(), + resumption_token_.size()); + + // rv is SECFailure with error set to SSL_ERROR_BAD_RESUMPTION_TOKEN_ERROR + // if the resumption token was bad (expired/malformed/etc.). + if (expect_resumption_) { + // Only in case we expect resumption this has to be successful. We might + // not expect resumption due to some reason but the token is totally fine. + EXPECT_EQ(SECSuccess, rv); + } + if (rv != SECSuccess) { + EXPECT_EQ(SSL_ERROR_BAD_RESUMPTION_TOKEN_ERROR, PORT_GetError()); + resumption_token_.clear(); + EXPECT_FALSE(expect_resumption_); + if (expect_resumption_) return false; + } + } + + return true; +} + void TlsAgent::SetupClientAuth() { EXPECT_TRUE(EnsureTlsSetup()); ASSERT_EQ(CLIENT, role_); @@ -258,13 +287,10 @@ void TlsAgent::CheckCipherSuite(uint16_t cipher_suite) { } void TlsAgent::RequestClientAuth(bool requireAuth) { - EXPECT_TRUE(EnsureTlsSetup()); ASSERT_EQ(SERVER, role_); - EXPECT_EQ(SECSuccess, - SSL_OptionSet(ssl_fd(), SSL_REQUEST_CERTIFICATE, PR_TRUE)); - EXPECT_EQ(SECSuccess, SSL_OptionSet(ssl_fd(), SSL_REQUIRE_CERTIFICATE, - requireAuth ? PR_TRUE : PR_FALSE)); + SetOption(SSL_REQUEST_CERTIFICATE, PR_TRUE); + SetOption(SSL_REQUIRE_CERTIFICATE, requireAuth ? PR_TRUE : PR_FALSE); EXPECT_EQ(SECSuccess, SSL_AuthCertificateHook( ssl_fd(), &TlsAgent::ClientAuthenticated, this)); @@ -376,42 +402,8 @@ void TlsAgent::ConfigNamedGroups(const std::vector<SSLNamedGroup>& groups) { EXPECT_EQ(SECSuccess, rv); } -void TlsAgent::SetSessionTicketsEnabled(bool en) { - EXPECT_TRUE(EnsureTlsSetup()); - - SECStatus rv = SSL_OptionSet(ssl_fd(), SSL_ENABLE_SESSION_TICKETS, - en ? PR_TRUE : PR_FALSE); - EXPECT_EQ(SECSuccess, rv); -} - -void TlsAgent::SetSessionCacheEnabled(bool en) { - EXPECT_TRUE(EnsureTlsSetup()); - - SECStatus rv = SSL_OptionSet(ssl_fd(), SSL_NO_CACHE, en ? PR_FALSE : PR_TRUE); - EXPECT_EQ(SECSuccess, rv); -} - void TlsAgent::Set0RttEnabled(bool en) { - EXPECT_TRUE(EnsureTlsSetup()); - - SECStatus rv = - SSL_OptionSet(ssl_fd(), SSL_ENABLE_0RTT_DATA, en ? PR_TRUE : PR_FALSE); - EXPECT_EQ(SECSuccess, rv); -} - -void TlsAgent::SetFallbackSCSVEnabled(bool en) { - EXPECT_TRUE(role_ == CLIENT && EnsureTlsSetup()); - - SECStatus rv = SSL_OptionSet(ssl_fd(), SSL_ENABLE_FALLBACK_SCSV, - en ? PR_TRUE : PR_FALSE); - EXPECT_EQ(SECSuccess, rv); -} - -void TlsAgent::SetShortHeadersEnabled() { - EXPECT_TRUE(EnsureTlsSetup()); - - SECStatus rv = SSLInt_EnableShortHeaders(ssl_fd()); - EXPECT_EQ(SECSuccess, rv); + SetOption(SSL_ENABLE_0RTT_DATA, en ? PR_TRUE : PR_FALSE); } void TlsAgent::SetVersionRange(uint16_t minver, uint16_t maxver) { @@ -424,6 +416,27 @@ void TlsAgent::SetVersionRange(uint16_t minver, uint16_t maxver) { } } +SECStatus ResumptionTokenCallback(PRFileDesc* fd, + const PRUint8* resumptionToken, + unsigned int len, void* ctx) { + EXPECT_NE(nullptr, resumptionToken); + if (!resumptionToken) { + return SECFailure; + } + + std::vector<uint8_t> new_token(resumptionToken, resumptionToken + len); + reinterpret_cast<TlsAgent*>(ctx)->SetResumptionToken(new_token); + reinterpret_cast<TlsAgent*>(ctx)->SetResumptionCallbackCalled(); + return SECSuccess; +} + +void TlsAgent::SetResumptionTokenCallback() { + EXPECT_TRUE(EnsureTlsSetup()); + SECStatus rv = + SSL_SetResumptionTokenCallback(ssl_fd(), ResumptionTokenCallback, this); + EXPECT_EQ(SECSuccess, rv); +} + void TlsAgent::GetVersionRange(uint16_t* minver, uint16_t* maxver) { *minver = vrange_.min; *maxver = vrange_.max; @@ -437,8 +450,6 @@ void TlsAgent::SetServerKeyBits(uint16_t bits) { server_key_bits_ = bits; } void TlsAgent::ExpectReadWriteError() { expect_readwrite_error_ = true; } -void TlsAgent::ExpectShortHeaders() { expect_short_headers_ = true; } - void TlsAgent::SkipVersionChecks() { skip_version_checks_ = true; } void TlsAgent::SetSignatureSchemes(const SSLSignatureScheme* schemes, @@ -517,6 +528,12 @@ void TlsAgent::CheckKEA(SSLKEAType kea_type, SSLNamedGroup kea_group, } } +void TlsAgent::CheckOriginalKEA(SSLNamedGroup kea_group) const { + if (kea_group != ssl_grp_ffdhe_custom) { + EXPECT_EQ(kea_group, info_.originalKeaGroup); + } +} + void TlsAgent::CheckAuthType(SSLAuthType auth_type, SSLSignatureScheme sig_scheme) const { EXPECT_EQ(STATE_CONNECTED, state_); @@ -569,8 +586,7 @@ void TlsAgent::EnableFalseStart() { falsestart_enabled_ = true; EXPECT_EQ(SECSuccess, SSL_SetCanFalseStartCallback( ssl_fd(), CanFalseStartCallback, this)); - EXPECT_EQ(SECSuccess, - SSL_OptionSet(ssl_fd(), SSL_ENABLE_FALSE_START, PR_TRUE)); + SetOption(SSL_ENABLE_FALSE_START, PR_TRUE); } void TlsAgent::ExpectResumption() { expect_resumption_ = true; } @@ -578,7 +594,7 @@ void TlsAgent::ExpectResumption() { expect_resumption_ = true; } void TlsAgent::EnableAlpn(const uint8_t* val, size_t len) { EXPECT_TRUE(EnsureTlsSetup()); - EXPECT_EQ(SECSuccess, SSL_OptionSet(ssl_fd(), SSL_ENABLE_ALPN, PR_TRUE)); + SetOption(SSL_ENABLE_ALPN, PR_TRUE); EXPECT_EQ(SECSuccess, SSL_SetNextProtoNego(ssl_fd(), val, len)); } @@ -622,12 +638,8 @@ void TlsAgent::CheckErrorCode(int32_t expected) const { } static uint8_t GetExpectedAlertLevel(uint8_t alert) { - switch (alert) { - case kTlsAlertCloseNotify: - case kTlsAlertEndOfEarlyData: - return kTlsAlertWarning; - default: - break; + if (alert == kTlsAlertCloseNotify) { + return kTlsAlertWarning; } return kTlsAlertFatal; } @@ -730,6 +742,50 @@ void TlsAgent::ResetPreliminaryInfo() { expected_cipher_suite_ = 0; } +void TlsAgent::ValidateCipherSpecs() { + PRInt32 cipherSpecs = SSLInt_CountCipherSpecs(ssl_fd()); + // We use one ciphersuite in each direction. + PRInt32 expected = 2; + if (variant_ == ssl_variant_datagram) { + // For DTLS 1.3, the client retains the cipher spec for early data and the + // handshake so that it can retransmit EndOfEarlyData and its final flight. + // It also retains the handshake read cipher spec so that it can read ACKs + // from the server. The server retains the handshake read cipher spec so it + // can read the client's retransmitted Finished. + if (expected_version_ >= SSL_LIBRARY_VERSION_TLS_1_3) { + if (role_ == CLIENT) { + expected = info_.earlyDataAccepted ? 5 : 4; + } else { + expected = 3; + } + } else { + // For DTLS 1.1 and 1.2, the last endpoint to send maintains a cipher spec + // until the holddown timer runs down. + if (expect_resumption_) { + if (role_ == CLIENT) { + expected = 3; + } + } else { + if (role_ == SERVER) { + expected = 3; + } + } + } + } + // This function will be run before the handshake completes if false start is + // enabled. In that case, the client will still be reading cleartext, but + // will have a spec prepared for reading ciphertext. With DTLS, the client + // will also have a spec retained for retransmission of handshake messages. + if (role_ == CLIENT && falsestart_enabled_ && !handshake_callback_called_) { + EXPECT_GT(SSL_LIBRARY_VERSION_TLS_1_3, expected_version_); + expected = (variant_ == ssl_variant_datagram) ? 4 : 3; + } + EXPECT_EQ(expected, cipherSpecs); + if (expected != cipherSpecs) { + SSLInt_PrintCipherSpecs(role_str().c_str(), ssl_fd()); + } +} + void TlsAgent::Connected() { if (state_ == STATE_CONNECTED) { return; @@ -743,6 +799,8 @@ void TlsAgent::Connected() { EXPECT_EQ(SECSuccess, rv); EXPECT_EQ(sizeof(info_), info_.length); + EXPECT_EQ(expect_resumption_, info_.resumed == PR_TRUE); + // Preliminary values are exposed through callbacks during the handshake. // If either expected values were set or the callbacks were called, check // that the final values are correct. @@ -753,32 +811,13 @@ void TlsAgent::Connected() { EXPECT_EQ(SECSuccess, rv); EXPECT_EQ(sizeof(csinfo_), csinfo_.length); - if (expected_version_ >= SSL_LIBRARY_VERSION_TLS_1_3) { - PRInt32 cipherSuites = SSLInt_CountTls13CipherSpecs(ssl_fd()); - // We use one ciphersuite in each direction, plus one that's kept around - // by DTLS for retransmission. - PRInt32 expected = - ((variant_ == ssl_variant_datagram) && (role_ == CLIENT)) ? 3 : 2; - EXPECT_EQ(expected, cipherSuites); - if (expected != cipherSuites) { - SSLInt_PrintTls13CipherSpecs(ssl_fd()); - } - } + ValidateCipherSpecs(); - PRBool short_headers; - rv = SSLInt_UsingShortHeaders(ssl_fd(), &short_headers); - EXPECT_EQ(SECSuccess, rv); - EXPECT_EQ((PRBool)expect_short_headers_, short_headers); SetState(STATE_CONNECTED); } void TlsAgent::EnableExtendedMasterSecret() { - ASSERT_TRUE(EnsureTlsSetup()); - - SECStatus rv = - SSL_OptionSet(ssl_fd(), SSL_ENABLE_EXTENDED_MASTER_SECRET, PR_TRUE); - - ASSERT_EQ(SECSuccess, rv); + SetOption(SSL_ENABLE_EXTENDED_MASTER_SECRET, PR_TRUE); } void TlsAgent::CheckExtendedMasterSecret(bool expected) { @@ -801,21 +840,6 @@ void TlsAgent::CheckSecretsDestroyed() { ASSERT_EQ(PR_TRUE, SSLInt_CheckSecretsDestroyed(ssl_fd())); } -void TlsAgent::DisableRollbackDetection() { - ASSERT_TRUE(EnsureTlsSetup()); - - SECStatus rv = SSL_OptionSet(ssl_fd(), SSL_ROLLBACK_DETECTION, PR_FALSE); - - ASSERT_EQ(SECSuccess, rv); -} - -void TlsAgent::EnableCompression() { - ASSERT_TRUE(EnsureTlsSetup()); - - SECStatus rv = SSL_OptionSet(ssl_fd(), SSL_ENABLE_DEFLATE, PR_TRUE); - ASSERT_EQ(SECSuccess, rv); -} - void TlsAgent::SetDowngradeCheckVersion(uint16_t version) { ASSERT_TRUE(EnsureTlsSetup()); @@ -883,6 +907,14 @@ void TlsAgent::SendDirect(const DataBuffer& buf) { } } +void TlsAgent::SendRecordDirect(const TlsRecord& record) { + DataBuffer buf; + + auto rv = record.header.Write(&buf, 0, record.buffer); + EXPECT_EQ(record.header.header_length() + record.buffer.len(), rv); + SendDirect(buf); +} + static bool ErrorIsNonFatal(PRErrorCode code) { return code == PR_WOULD_BLOCK_ERROR || code == SSL_ERROR_RX_SHORT_DTLS_READ; } @@ -918,6 +950,27 @@ 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. + EXPECT_GE(expected_version_, SSL_LIBRARY_VERSION_TLS_1_3); + TlsRecordHeader header(wireVersion, kTlsApplicationDataType, seq); + DataBuffer padded = buf; + padded.Write(padded.len(), ct, 1); + DataBuffer ciphertext; + if (!spec->Protect(header, padded, &ciphertext)) { + return false; + } + + DataBuffer record; + auto rv = header.Write(&record, 0, ciphertext); + EXPECT_EQ(header.header_length() + ciphertext.len(), rv); + SendDirect(record); + return true; +} + void TlsAgent::ReadBytes(size_t amount) { uint8_t block[16384]; @@ -951,23 +1004,20 @@ void TlsAgent::ReadBytes(size_t amount) { void TlsAgent::ResetSentBytes() { send_ctr_ = 0; } -void TlsAgent::ConfigureSessionCache(SessionResumptionMode mode) { - EXPECT_TRUE(EnsureTlsSetup()); - - SECStatus rv = SSL_OptionSet(ssl_fd(), SSL_NO_CACHE, - mode & RESUME_SESSIONID ? PR_FALSE : PR_TRUE); - EXPECT_EQ(SECSuccess, rv); +void TlsAgent::SetOption(int32_t option, int value) { + ASSERT_TRUE(EnsureTlsSetup()); + EXPECT_EQ(SECSuccess, SSL_OptionSet(ssl_fd(), option, value)); +} - rv = SSL_OptionSet(ssl_fd(), SSL_ENABLE_SESSION_TICKETS, - mode & RESUME_TICKET ? PR_TRUE : PR_FALSE); - EXPECT_EQ(SECSuccess, rv); +void TlsAgent::ConfigureSessionCache(SessionResumptionMode mode) { + SetOption(SSL_NO_CACHE, mode & RESUME_SESSIONID ? PR_FALSE : PR_TRUE); + SetOption(SSL_ENABLE_SESSION_TICKETS, + mode & RESUME_TICKET ? PR_TRUE : PR_FALSE); } void TlsAgent::DisableECDHEServerKeyReuse() { - ASSERT_TRUE(EnsureTlsSetup()); ASSERT_EQ(TlsAgent::SERVER, role_); - SECStatus rv = SSL_OptionSet(ssl_fd(), SSL_REUSE_SERVER_ECDHE_KEY, PR_FALSE); - EXPECT_EQ(SECSuccess, rv); + SetOption(SSL_REUSE_SERVER_ECDHE_KEY, PR_FALSE); } static const std::string kTlsRolesAllArr[] = {"CLIENT", "SERVER"}; diff --git a/security/nss/gtests/ssl_gtest/tls_agent.h b/security/nss/gtests/ssl_gtest/tls_agent.h index 4bccb9a84..6cd6d5073 100644 --- a/security/nss/gtests/ssl_gtest/tls_agent.h +++ b/security/nss/gtests/ssl_gtest/tls_agent.h @@ -14,7 +14,6 @@ #include <iostream> #include "test_io.h" -#include "tls_filter.h" #define GTEST_HAS_RTTI 0 #include "gtest/gtest.h" @@ -37,7 +36,10 @@ enum SessionResumptionMode { RESUME_BOTH = RESUME_SESSIONID | RESUME_TICKET }; +class PacketFilter; class TlsAgent; +class TlsCipherSpec; +struct TlsRecord; const extern std::vector<SSLNamedGroup> kAllDHEGroups; const extern std::vector<SSLNamedGroup> kECDHEGroups; @@ -66,7 +68,6 @@ class TlsAgent : public PollTarget { static const std::string kServerRsaSign; static const std::string kServerRsaPss; static const std::string kServerRsaDecrypt; - static const std::string kServerRsaChain; // A cert that requires a chain. static const std::string kServerEcdsa256; static const std::string kServerEcdsa384; static const std::string kServerEcdsa521; @@ -81,20 +82,15 @@ class TlsAgent : public PollTarget { adapter_->SetPeer(peer->adapter_); } - void SetTlsRecordFilter(std::shared_ptr<TlsRecordFilter> filter) { - filter->SetAgent(this); + void SetFilter(std::shared_ptr<PacketFilter> filter) { adapter_->SetPacketFilter(filter); } - - void SetPacketFilter(std::shared_ptr<PacketFilter> filter) { - adapter_->SetPacketFilter(filter); - } - - void DeletePacketFilter() { adapter_->SetPacketFilter(nullptr); } + void ClearFilter() { adapter_->SetPacketFilter(nullptr); } void StartConnect(PRFileDesc* model = nullptr); void CheckKEA(SSLKEAType kea_type, SSLNamedGroup group, size_t kea_size = 0) const; + void CheckOriginalKEA(SSLNamedGroup kea_group) const; void CheckAuthType(SSLAuthType auth_type, SSLSignatureScheme sig_scheme) const; @@ -121,12 +117,10 @@ class TlsAgent : public PollTarget { void SetupClientAuth(); void RequestClientAuth(bool requireAuth); + void SetOption(int32_t option, int value); void ConfigureSessionCache(SessionResumptionMode mode); - void SetSessionTicketsEnabled(bool en); - void SetSessionCacheEnabled(bool en); void Set0RttEnabled(bool en); void SetFallbackSCSVEnabled(bool en); - void SetShortHeadersEnabled(); void SetVersionRange(uint16_t minver, uint16_t maxver); void GetVersionRange(uint16_t* minver, uint16_t* maxver); void CheckPreliminaryInfo(); @@ -136,7 +130,6 @@ class TlsAgent : public PollTarget { void ExpectReadWriteError(); void EnableFalseStart(); void ExpectResumption(); - void ExpectShortHeaders(); void SkipVersionChecks(); void SetSignatureSchemes(const SSLSignatureScheme* schemes, size_t count); void EnableAlpn(const uint8_t* val, size_t len); @@ -149,27 +142,49 @@ class TlsAgent : public PollTarget { // Send data on the socket, encrypting it. 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); // Send data directly to the underlying socket, skipping the TLS layer. void SendDirect(const DataBuffer& buf); + void SendRecordDirect(const TlsRecord& record); void ReadBytes(size_t max = 16384U); void ResetSentBytes(); // Hack to test drops. void EnableExtendedMasterSecret(); void CheckExtendedMasterSecret(bool expected); void CheckEarlyDataAccepted(bool expected); - void DisableRollbackDetection(); - void EnableCompression(); void SetDowngradeCheckVersion(uint16_t version); void CheckSecretsDestroyed(); void ConfigNamedGroups(const std::vector<SSLNamedGroup>& groups); void DisableECDHEServerKeyReuse(); bool GetPeerChainLength(size_t* count); void CheckCipherSuite(uint16_t cipher_suite); + void SetResumptionTokenCallback(); + bool MaybeSetResumptionToken(); + void SetResumptionToken(const std::vector<uint8_t>& resumption_token) { + resumption_token_ = resumption_token; + } + const std::vector<uint8_t>& GetResumptionToken() const { + return resumption_token_; + } + void GetTokenInfo(ScopedSSLResumptionTokenInfo& token) { + SECStatus rv = SSL_GetResumptionTokenInfo( + resumption_token_.data(), resumption_token_.size(), token.get(), + sizeof(SSLResumptionTokenInfo)); + ASSERT_EQ(SECSuccess, rv); + } + void SetResumptionCallbackCalled() { resumption_callback_called_ = true; } + bool resumption_callback_called() const { + return resumption_callback_called_; + } const std::string& name() const { return name_; } Role role() const { return role_; } std::string role_str() const { return role_ == SERVER ? "server" : "client"; } + SSLProtocolVariant variant() const { return variant_; } + State state() const { return state_; } const CERTCertificate* peer_cert() const { @@ -253,6 +268,7 @@ class TlsAgent : public PollTarget { const static char* states[]; void SetState(State state); + void ValidateCipherSpecs(); // Dummy auth certificate hook. static SECStatus AuthCertificateHook(void* arg, PRFileDesc* fd, @@ -378,6 +394,7 @@ class TlsAgent : public PollTarget { uint8_t expected_sent_alert_; uint8_t expected_sent_alert_level_; bool handshake_callback_called_; + bool resumption_callback_called_; SSLChannelInfo info_; SSLCipherSuiteInfo csinfo_; SSLVersionRange vrange_; @@ -388,8 +405,8 @@ class TlsAgent : public PollTarget { HandshakeCallbackFunction handshake_callback_; AuthCertificateCallbackFunction auth_certificate_callback_; SniCallbackFunction sni_callback_; - bool expect_short_headers_; bool skip_version_checks_; + std::vector<uint8_t> resumption_token_; }; inline std::ostream& operator<<(std::ostream& stream, @@ -440,7 +457,7 @@ class TlsAgentTestBase : public ::testing::Test { void ProcessMessage(const DataBuffer& buffer, TlsAgent::State expected_state, int32_t error_code = 0); - std::unique_ptr<TlsAgent> agent_; + std::shared_ptr<TlsAgent> agent_; TlsAgent::Role role_; SSLProtocolVariant variant_; uint16_t version_; diff --git a/security/nss/gtests/ssl_gtest/tls_connect.cc b/security/nss/gtests/ssl_gtest/tls_connect.cc index c8de5a1fe..8567b392f 100644 --- a/security/nss/gtests/ssl_gtest/tls_connect.cc +++ b/security/nss/gtests/ssl_gtest/tls_connect.cc @@ -5,6 +5,7 @@ * You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "tls_connect.h" +#include "sslexp.h" extern "C" { #include "libssl_internals.h" } @@ -88,6 +89,8 @@ std::string VersionString(uint16_t version) { switch (version) { case 0: return "(no version)"; + case SSL_LIBRARY_VERSION_3_0: + return "1.0"; case SSL_LIBRARY_VERSION_TLS_1_0: return "1.0"; case SSL_LIBRARY_VERSION_TLS_1_1: @@ -112,6 +115,7 @@ TlsConnectTestBase::TlsConnectTestBase(SSLProtocolVariant variant, server_model_(nullptr), version_(version), expected_resumption_mode_(RESUME_NONE), + expected_resumptions_(0), session_ids_(), expect_extended_master_secret_(false), expect_early_data_accepted_(false), @@ -161,6 +165,22 @@ void TlsConnectTestBase::CheckShares( EXPECT_EQ(shares.len(), i); } +void TlsConnectTestBase::CheckEpochs(uint16_t client_epoch, + uint16_t server_epoch) const { + uint16_t read_epoch = 0; + uint16_t write_epoch = 0; + + EXPECT_EQ(SECSuccess, + SSLInt_GetEpochs(client_->ssl_fd(), &read_epoch, &write_epoch)); + EXPECT_EQ(server_epoch, read_epoch) << "client read epoch"; + EXPECT_EQ(client_epoch, write_epoch) << "client write epoch"; + + EXPECT_EQ(SECSuccess, + SSLInt_GetEpochs(server_->ssl_fd(), &read_epoch, &write_epoch)); + EXPECT_EQ(client_epoch, read_epoch) << "server read epoch"; + EXPECT_EQ(server_epoch, write_epoch) << "server write epoch"; +} + void TlsConnectTestBase::ClearStats() { // Clear statistics. SSL3Statistics* stats = SSL_GetStatistics(); @@ -177,7 +197,7 @@ void TlsConnectTestBase::SetUp() { SSL_ConfigServerSessionIDCache(1024, 0, 0, g_working_dir_path.c_str()); SSLInt_ClearSelfEncryptKey(); SSLInt_SetTicketLifetime(30); - SSLInt_SetMaxEarlyDataSize(1024); + SSL_SetupAntiReplay(1 * PR_USEC_PER_SEC, 1, 3); ClearStats(); Init(); } @@ -209,7 +229,9 @@ void TlsConnectTestBase::Reset() { void TlsConnectTestBase::Reset(const std::string& server_name, const std::string& client_name) { + auto token = client_->GetResumptionToken(); client_.reset(new TlsAgent(client_name, TlsAgent::CLIENT, variant_)); + client_->SetResumptionToken(token); server_.reset(new TlsAgent(server_name, TlsAgent::SERVER, variant_)); if (skip_version_checks_) { client_->SkipVersionChecks(); @@ -219,12 +241,27 @@ void TlsConnectTestBase::Reset(const std::string& server_name, Init(); } -void TlsConnectTestBase::ExpectResumption(SessionResumptionMode expected) { +void TlsConnectTestBase::MakeNewServer() { + auto replacement = std::make_shared<TlsAgent>( + server_->name(), TlsAgent::SERVER, server_->variant()); + server_ = replacement; + if (version_) { + server_->SetVersionRange(version_, version_); + } + client_->SetPeer(server_); + server_->SetPeer(client_); + server_->StartConnect(); +} + +void TlsConnectTestBase::ExpectResumption(SessionResumptionMode expected, + uint8_t num_resumptions) { expected_resumption_mode_ = expected; if (expected != RESUME_NONE) { client_->ExpectResumption(); server_->ExpectResumption(); + expected_resumptions_ = num_resumptions; } + EXPECT_EQ(expected_resumptions_ == 0, expected == RESUME_NONE); } void TlsConnectTestBase::EnsureTlsSetup() { @@ -254,10 +291,16 @@ void TlsConnectTestBase::EnableExtendedMasterSecret() { void TlsConnectTestBase::Connect() { server_->StartConnect(server_model_ ? server_model_->ssl_fd() : nullptr); client_->StartConnect(client_model_ ? client_model_->ssl_fd() : nullptr); + client_->MaybeSetResumptionToken(); Handshake(); CheckConnected(); } +void TlsConnectTestBase::StartConnect() { + server_->StartConnect(server_model_ ? server_model_->ssl_fd() : nullptr); + client_->StartConnect(client_model_ ? client_model_->ssl_fd() : nullptr); +} + void TlsConnectTestBase::ConnectWithCipherSuite(uint16_t cipher_suite) { EnsureTlsSetup(); client_->EnableSingleCipher(cipher_suite); @@ -274,6 +317,19 @@ void TlsConnectTestBase::ConnectWithCipherSuite(uint16_t cipher_suite) { } void TlsConnectTestBase::CheckConnected() { + // Have the client read handshake twice to make sure we get the + // NST and the ACK. + if (client_->version() >= SSL_LIBRARY_VERSION_TLS_1_3 && + variant_ == ssl_variant_datagram) { + client_->Handshake(); + client_->Handshake(); + auto suites = SSLInt_CountCipherSpecs(client_->ssl_fd()); + // Verify that we dropped the client's retransmission cipher suites. + EXPECT_EQ(2, suites) << "Client has the wrong number of suites"; + if (suites != 2) { + SSLInt_PrintCipherSpecs("client", client_->ssl_fd()); + } + } EXPECT_EQ(client_->version(), server_->version()); if (!skip_version_checks_) { // Check the version is as expected @@ -314,10 +370,12 @@ void TlsConnectTestBase::CheckConnected() { void TlsConnectTestBase::CheckKeys(SSLKEAType kea_type, SSLNamedGroup kea_group, SSLAuthType auth_type, SSLSignatureScheme sig_scheme) const { - client_->CheckKEA(kea_type, kea_group); - server_->CheckKEA(kea_type, kea_group); - client_->CheckAuthType(auth_type, sig_scheme); + if (kea_group != ssl_grp_none) { + client_->CheckKEA(kea_type, kea_group); + server_->CheckKEA(kea_type, kea_group); + } server_->CheckAuthType(auth_type, sig_scheme); + client_->CheckAuthType(auth_type, sig_scheme); } void TlsConnectTestBase::CheckKeys(SSLKEAType kea_type, @@ -346,13 +404,13 @@ void TlsConnectTestBase::CheckKeys(SSLKEAType kea_type, break; case ssl_auth_rsa_sign: if (version_ >= SSL_LIBRARY_VERSION_TLS_1_2) { - scheme = ssl_sig_rsa_pss_sha256; + scheme = ssl_sig_rsa_pss_rsae_sha256; } else { scheme = ssl_sig_rsa_pkcs1_sha256; } break; case ssl_auth_rsa_pss: - scheme = ssl_sig_rsa_pss_sha256; + scheme = ssl_sig_rsa_pss_rsae_sha256; break; case ssl_auth_ecdsa: scheme = ssl_sig_ecdsa_secp256r1_sha256; @@ -372,9 +430,19 @@ void TlsConnectTestBase::CheckKeys() const { CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign); } +void TlsConnectTestBase::CheckKeysResumption(SSLKEAType kea_type, + SSLNamedGroup kea_group, + SSLNamedGroup original_kea_group, + SSLAuthType auth_type, + SSLSignatureScheme sig_scheme) { + CheckKeys(kea_type, kea_group, auth_type, sig_scheme); + EXPECT_TRUE(expected_resumption_mode_ != RESUME_NONE); + client_->CheckOriginalKEA(original_kea_group); + server_->CheckOriginalKEA(original_kea_group); +} + void TlsConnectTestBase::ConnectExpectFail() { - server_->StartConnect(); - client_->StartConnect(); + StartConnect(); Handshake(); ASSERT_EQ(TlsAgent::STATE_ERROR, client_->state()); ASSERT_EQ(TlsAgent::STATE_ERROR, server_->state()); @@ -395,8 +463,7 @@ void TlsConnectTestBase::ConnectExpectAlert(std::shared_ptr<TlsAgent>& sender, } void TlsConnectTestBase::ConnectExpectFailOneSide(TlsAgent::Role failing_side) { - server_->StartConnect(); - client_->StartConnect(); + StartConnect(); client_->SetServerKeyBits(server_->server_key_bits()); client_->Handshake(); server_->Handshake(); @@ -455,29 +522,33 @@ void TlsConnectTestBase::EnableSomeEcdhCiphers() { } } +void TlsConnectTestBase::ConfigureSelfEncrypt() { + ScopedCERTCertificate cert; + ScopedSECKEYPrivateKey privKey; + ASSERT_TRUE( + TlsAgent::LoadCertificate(TlsAgent::kServerRsaDecrypt, &cert, &privKey)); + + ScopedSECKEYPublicKey pubKey(CERT_ExtractPublicKey(cert.get())); + ASSERT_TRUE(pubKey); + + EXPECT_EQ(SECSuccess, + SSL_SetSessionTicketKeyPair(pubKey.get(), privKey.get())); +} + void TlsConnectTestBase::ConfigureSessionCache(SessionResumptionMode client, SessionResumptionMode server) { client_->ConfigureSessionCache(client); server_->ConfigureSessionCache(server); if ((server & RESUME_TICKET) != 0) { - ScopedCERTCertificate cert; - ScopedSECKEYPrivateKey privKey; - ASSERT_TRUE(TlsAgent::LoadCertificate(TlsAgent::kServerRsaDecrypt, &cert, - &privKey)); - - ScopedSECKEYPublicKey pubKey(CERT_ExtractPublicKey(cert.get())); - ASSERT_TRUE(pubKey); - - EXPECT_EQ(SECSuccess, - SSL_SetSessionTicketKeyPair(pubKey.get(), privKey.get())); + ConfigureSelfEncrypt(); } } void TlsConnectTestBase::CheckResumption(SessionResumptionMode expected) { EXPECT_NE(RESUME_BOTH, expected); - int resume_count = expected ? 1 : 0; - int stateless_count = (expected & RESUME_TICKET) ? 1 : 0; + int resume_count = expected ? expected_resumptions_ : 0; + int stateless_count = (expected & RESUME_TICKET) ? expected_resumptions_ : 0; // Note: hch == server counter; hsh == client counter. SSL3Statistics* stats = SSL_GetStatistics(); @@ -490,7 +561,7 @@ void TlsConnectTestBase::CheckResumption(SessionResumptionMode expected) { if (expected != RESUME_NONE) { if (client_->version() < SSL_LIBRARY_VERSION_TLS_1_3) { // Check that the last two session ids match. - ASSERT_EQ(2U, session_ids_.size()); + ASSERT_EQ(1U + expected_resumptions_, session_ids_.size()); EXPECT_EQ(session_ids_[session_ids_.size() - 1], session_ids_[session_ids_.size() - 2]); } else { @@ -540,31 +611,28 @@ void TlsConnectTestBase::CheckSrtp() const { server_->CheckSrtp(); } -void TlsConnectTestBase::SendReceive() { - client_->SendData(50); - server_->SendData(50); - Receive(50); +void TlsConnectTestBase::SendReceive(size_t total) { + ASSERT_GT(total, client_->received_bytes()); + ASSERT_GT(total, server_->received_bytes()); + client_->SendData(total - server_->received_bytes()); + server_->SendData(total - client_->received_bytes()); + Receive(total); // Receive() is cumulative } // Do a first connection so we can do 0-RTT on the second one. void TlsConnectTestBase::SetupForZeroRtt() { + // If we don't do this, then all 0-RTT attempts will be rejected. + SSLInt_RolloverAntiReplay(); + ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET); - client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1, - SSL_LIBRARY_VERSION_TLS_1_3); - server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1, - SSL_LIBRARY_VERSION_TLS_1_3); + ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3); server_->Set0RttEnabled(true); // So we signal that we allow 0-RTT. Connect(); SendReceive(); // Need to read so that we absorb the session ticket. CheckKeys(); Reset(); - client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1, - SSL_LIBRARY_VERSION_TLS_1_3); - server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1, - SSL_LIBRARY_VERSION_TLS_1_3); - server_->StartConnect(); - client_->StartConnect(); + StartConnect(); } // Do a first connection so we can do resumption @@ -584,10 +652,6 @@ void TlsConnectTestBase::ZeroRttSendReceive( const char* k0RttData = "ABCDEF"; const PRInt32 k0RttDataLen = static_cast<PRInt32>(strlen(k0RttData)); - if (expect_writable && expect_readable) { - ExpectAlert(client_, kTlsAlertEndOfEarlyData); - } - client_->Handshake(); // Send ClientHello. if (post_clienthello_check) { if (!post_clienthello_check()) return; @@ -599,7 +663,7 @@ void TlsConnectTestBase::ZeroRttSendReceive( } else { EXPECT_EQ(SECFailure, rv); } - server_->Handshake(); // Consume ClientHello, EE, Finished. + server_->Handshake(); // Consume ClientHello std::vector<uint8_t> buf(k0RttDataLen); rv = PR_Read(server_->ssl_fd(), buf.data(), k0RttDataLen); // 0-RTT read @@ -608,7 +672,8 @@ void TlsConnectTestBase::ZeroRttSendReceive( EXPECT_EQ(k0RttDataLen, rv); } else { EXPECT_EQ(SECFailure, rv); - EXPECT_EQ(PR_WOULD_BLOCK_ERROR, PORT_GetError()); + EXPECT_EQ(PR_WOULD_BLOCK_ERROR, PORT_GetError()) + << "Unexpected error: " << PORT_ErrorToName(PORT_GetError()); } // Do a second read. this should fail. @@ -653,6 +718,30 @@ void TlsConnectTestBase::SkipVersionChecks() { server_->SkipVersionChecks(); } +// Shift the DTLS timers, to the minimum time necessary to let the next timer +// run on either client or server. This allows tests to skip waiting without +// having timers run out of order. +void TlsConnectTestBase::ShiftDtlsTimers() { + PRIntervalTime time_shift = PR_INTERVAL_NO_TIMEOUT; + PRIntervalTime time; + SECStatus rv = DTLS_GetHandshakeTimeout(client_->ssl_fd(), &time); + if (rv == SECSuccess) { + time_shift = time; + } + rv = DTLS_GetHandshakeTimeout(server_->ssl_fd(), &time); + if (rv == SECSuccess && + (time < time_shift || time_shift == PR_INTERVAL_NO_TIMEOUT)) { + time_shift = time; + } + + if (time_shift == PR_INTERVAL_NO_TIMEOUT) { + return; + } + + EXPECT_EQ(SECSuccess, SSLInt_ShiftDtlsTimers(client_->ssl_fd(), time_shift)); + EXPECT_EQ(SECSuccess, SSLInt_ShiftDtlsTimers(server_->ssl_fd(), time_shift)); +} + TlsConnectGeneric::TlsConnectGeneric() : TlsConnectTestBase(std::get<0>(GetParam()), std::get<1>(GetParam())) {} @@ -668,20 +757,29 @@ TlsConnectTls12Plus::TlsConnectTls12Plus() TlsConnectTls13::TlsConnectTls13() : TlsConnectTestBase(GetParam(), SSL_LIBRARY_VERSION_TLS_1_3) {} +TlsConnectGenericResumption::TlsConnectGenericResumption() + : TlsConnectTestBase(std::get<0>(GetParam()), std::get<1>(GetParam())), + external_cache_(std::get<2>(GetParam())) {} + +TlsConnectTls13ResumptionToken::TlsConnectTls13ResumptionToken() + : TlsConnectTestBase(GetParam(), SSL_LIBRARY_VERSION_TLS_1_3) {} + +TlsConnectGenericResumptionToken::TlsConnectGenericResumptionToken() + : TlsConnectTestBase(std::get<0>(GetParam()), std::get<1>(GetParam())) {} + void TlsKeyExchangeTest::EnsureKeyShareSetup() { EnsureTlsSetup(); groups_capture_ = - std::make_shared<TlsExtensionCapture>(ssl_supported_groups_xtn); + std::make_shared<TlsExtensionCapture>(client_, ssl_supported_groups_xtn); shares_capture_ = - std::make_shared<TlsExtensionCapture>(ssl_tls13_key_share_xtn); - shares_capture2_ = - std::make_shared<TlsExtensionCapture>(ssl_tls13_key_share_xtn, true); + std::make_shared<TlsExtensionCapture>(client_, ssl_tls13_key_share_xtn); + shares_capture2_ = std::make_shared<TlsExtensionCapture>( + client_, ssl_tls13_key_share_xtn, true); std::vector<std::shared_ptr<PacketFilter>> captures = { groups_capture_, shares_capture_, shares_capture2_}; - client_->SetPacketFilter(std::make_shared<ChainedPacketFilter>(captures)); - capture_hrr_ = std::make_shared<TlsInspectorRecordHandshakeMessage>( - kTlsHandshakeHelloRetryRequest); - server_->SetPacketFilter(capture_hrr_); + client_->SetFilter(std::make_shared<ChainedPacketFilter>(captures)); + capture_hrr_ = MakeTlsFilter<TlsHandshakeRecorder>( + server_, kTlsHandshakeHelloRetryRequest); } void TlsKeyExchangeTest::ConfigNamedGroups( @@ -691,11 +789,15 @@ void TlsKeyExchangeTest::ConfigNamedGroups( } std::vector<SSLNamedGroup> TlsKeyExchangeTest::GetGroupDetails( - const DataBuffer& ext) { + const std::shared_ptr<TlsExtensionCapture>& capture) { + EXPECT_TRUE(capture->captured()); + const DataBuffer& ext = capture->extension(); + uint32_t tmp = 0; EXPECT_TRUE(ext.Read(0, 2, &tmp)); EXPECT_EQ(ext.len() - 2, static_cast<size_t>(tmp)); EXPECT_TRUE(ext.len() % 2 == 0); + std::vector<SSLNamedGroup> groups; for (size_t i = 1; i < ext.len() / 2; i += 1) { EXPECT_TRUE(ext.Read(2 * i, 2, &tmp)); @@ -705,10 +807,14 @@ std::vector<SSLNamedGroup> TlsKeyExchangeTest::GetGroupDetails( } std::vector<SSLNamedGroup> TlsKeyExchangeTest::GetShareDetails( - const DataBuffer& ext) { + const std::shared_ptr<TlsExtensionCapture>& capture) { + EXPECT_TRUE(capture->captured()); + const DataBuffer& ext = capture->extension(); + uint32_t tmp = 0; EXPECT_TRUE(ext.Read(0, 2, &tmp)); EXPECT_EQ(ext.len() - 2, static_cast<size_t>(tmp)); + std::vector<SSLNamedGroup> shares; size_t i = 2; while (i < ext.len()) { @@ -724,17 +830,15 @@ std::vector<SSLNamedGroup> TlsKeyExchangeTest::GetShareDetails( void TlsKeyExchangeTest::CheckKEXDetails( const std::vector<SSLNamedGroup>& expected_groups, const std::vector<SSLNamedGroup>& expected_shares, bool expect_hrr) { - std::vector<SSLNamedGroup> groups = - GetGroupDetails(groups_capture_->extension()); + std::vector<SSLNamedGroup> groups = GetGroupDetails(groups_capture_); EXPECT_EQ(expected_groups, groups); if (version_ >= SSL_LIBRARY_VERSION_TLS_1_3) { ASSERT_LT(0U, expected_shares.size()); - std::vector<SSLNamedGroup> shares = - GetShareDetails(shares_capture_->extension()); + std::vector<SSLNamedGroup> shares = GetShareDetails(shares_capture_); EXPECT_EQ(expected_shares, shares); } else { - EXPECT_EQ(0U, shares_capture_->extension().len()); + EXPECT_FALSE(shares_capture_->captured()); } EXPECT_EQ(expect_hrr, capture_hrr_->buffer().len() != 0); @@ -756,8 +860,6 @@ void TlsKeyExchangeTest::CheckKEXDetails( EXPECT_NE(expected_share2, it); } std::vector<SSLNamedGroup> expected_shares2 = {expected_share2}; - std::vector<SSLNamedGroup> shares = - GetShareDetails(shares_capture2_->extension()); - EXPECT_EQ(expected_shares2, shares); + EXPECT_EQ(expected_shares2, GetShareDetails(shares_capture2_)); } } // namespace nss_test diff --git a/security/nss/gtests/ssl_gtest/tls_connect.h b/security/nss/gtests/ssl_gtest/tls_connect.h index 73e8dc81a..7dffe7f8a 100644 --- a/security/nss/gtests/ssl_gtest/tls_connect.h +++ b/security/nss/gtests/ssl_gtest/tls_connect.h @@ -45,8 +45,8 @@ class TlsConnectTestBase : public ::testing::Test { TlsConnectTestBase(SSLProtocolVariant variant, uint16_t version); virtual ~TlsConnectTestBase(); - void SetUp(); - void TearDown(); + virtual void SetUp(); + virtual void TearDown(); // Initialize client and server. void Init(); @@ -55,13 +55,17 @@ class TlsConnectTestBase : public ::testing::Test { // Clear the server session cache. void ClearServerCache(); // Make sure TLS is configured for a connection. - void EnsureTlsSetup(); + virtual void EnsureTlsSetup(); // Reset and keep the same certificate names void Reset(); // Reset, and update the certificate names on both peers void Reset(const std::string& server_name, const std::string& client_name = "client"); + // Replace the server. + void MakeNewServer(); + // Set up + void StartConnect(); // Run the handshake. void Handshake(); // Connect and check that it works. @@ -81,20 +85,28 @@ class TlsConnectTestBase : public ::testing::Test { void CheckKeys(SSLKEAType kea_type, SSLAuthType auth_type) const; // This version assumes defaults. void CheckKeys() const; + // Check that keys on resumed sessions. + void CheckKeysResumption(SSLKEAType kea_type, SSLNamedGroup kea_group, + SSLNamedGroup original_kea_group, + SSLAuthType auth_type, + SSLSignatureScheme sig_scheme); void CheckGroups(const DataBuffer& groups, std::function<void(SSLNamedGroup)> check_group); void CheckShares(const DataBuffer& shares, std::function<void(SSLNamedGroup)> check_group); + void CheckEpochs(uint16_t client_epoch, uint16_t server_epoch) const; void ConfigureVersion(uint16_t version); void SetExpectedVersion(uint16_t version); // Expect resumption of a particular type. - void ExpectResumption(SessionResumptionMode expected); + void ExpectResumption(SessionResumptionMode expected, + uint8_t num_resumed = 1); void DisableAllCiphers(); void EnableOnlyStaticRsaCiphers(); void EnableOnlyDheCiphers(); void EnableSomeEcdhCiphers(); void EnableExtendedMasterSecret(); + void ConfigureSelfEncrypt(); void ConfigureSessionCache(SessionResumptionMode client, SessionResumptionMode server); void EnableAlpn(); @@ -103,7 +115,7 @@ class TlsConnectTestBase : public ::testing::Test { void CheckAlpn(const std::string& val); void EnableSrtp(); void CheckSrtp() const; - void SendReceive(); + void SendReceive(size_t total = 50); void SetupForZeroRtt(); void SetupForResume(); void ZeroRttSendReceive( @@ -115,6 +127,9 @@ class TlsConnectTestBase : public ::testing::Test { void DisableECDHEServerKeyReuse(); void SkipVersionChecks(); + // Move the DTLS timers for both endpoints to pop the next timer. + void ShiftDtlsTimers(); + protected: SSLProtocolVariant variant_; std::shared_ptr<TlsAgent> client_; @@ -123,6 +138,7 @@ class TlsConnectTestBase : public ::testing::Test { std::unique_ptr<TlsAgent> server_model_; uint16_t version_; SessionResumptionMode expected_resumption_mode_; + uint8_t expected_resumptions_; std::vector<std::vector<uint8_t>> session_ids_; // A simple value of "a", "b". Note that the preferred value of "a" is placed @@ -192,6 +208,52 @@ class TlsConnectGeneric : public TlsConnectTestBase, TlsConnectGeneric(); }; +class TlsConnectGenericResumption + : public TlsConnectTestBase, + public ::testing::WithParamInterface< + std::tuple<SSLProtocolVariant, uint16_t, bool>> { + private: + bool external_cache_; + + public: + TlsConnectGenericResumption(); + + virtual void EnsureTlsSetup() { + TlsConnectTestBase::EnsureTlsSetup(); + // Enable external resumption token cache. + if (external_cache_) { + client_->SetResumptionTokenCallback(); + } + } + + bool use_external_cache() const { return external_cache_; } +}; + +class TlsConnectTls13ResumptionToken + : public TlsConnectTestBase, + public ::testing::WithParamInterface<SSLProtocolVariant> { + public: + TlsConnectTls13ResumptionToken(); + + virtual void EnsureTlsSetup() { + TlsConnectTestBase::EnsureTlsSetup(); + client_->SetResumptionTokenCallback(); + } +}; + +class TlsConnectGenericResumptionToken + : public TlsConnectTestBase, + public ::testing::WithParamInterface< + std::tuple<SSLProtocolVariant, uint16_t>> { + public: + TlsConnectGenericResumptionToken(); + + virtual void EnsureTlsSetup() { + TlsConnectTestBase::EnsureTlsSetup(); + client_->SetResumptionTokenCallback(); + } +}; + // A Pre TLS 1.2 generic test. class TlsConnectPre12 : public TlsConnectTestBase, public ::testing::WithParamInterface< @@ -244,6 +306,11 @@ class TlsConnectDatagram13 : public TlsConnectTestBase { : TlsConnectTestBase(ssl_variant_datagram, SSL_LIBRARY_VERSION_TLS_1_3) {} }; +class TlsConnectDatagramPre13 : public TlsConnectDatagram { + public: + TlsConnectDatagramPre13() {} +}; + // A variant that is used only with Pre13. class TlsConnectGenericPre13 : public TlsConnectGeneric {}; @@ -252,12 +319,14 @@ class TlsKeyExchangeTest : public TlsConnectGeneric { std::shared_ptr<TlsExtensionCapture> groups_capture_; std::shared_ptr<TlsExtensionCapture> shares_capture_; std::shared_ptr<TlsExtensionCapture> shares_capture2_; - std::shared_ptr<TlsInspectorRecordHandshakeMessage> capture_hrr_; + std::shared_ptr<TlsHandshakeRecorder> capture_hrr_; void EnsureKeyShareSetup(); void ConfigNamedGroups(const std::vector<SSLNamedGroup>& groups); - std::vector<SSLNamedGroup> GetGroupDetails(const DataBuffer& ext); - std::vector<SSLNamedGroup> GetShareDetails(const DataBuffer& ext); + std::vector<SSLNamedGroup> GetGroupDetails( + const std::shared_ptr<TlsExtensionCapture>& capture); + std::vector<SSLNamedGroup> GetShareDetails( + const std::shared_ptr<TlsExtensionCapture>& capture); void CheckKEXDetails(const std::vector<SSLNamedGroup>& expectedGroups, const std::vector<SSLNamedGroup>& expectedShares); void CheckKEXDetails(const std::vector<SSLNamedGroup>& expectedGroups, diff --git a/security/nss/gtests/ssl_gtest/tls_filter.cc b/security/nss/gtests/ssl_gtest/tls_filter.cc index 76d9aaaff..d34b13bcb 100644 --- a/security/nss/gtests/ssl_gtest/tls_filter.cc +++ b/security/nss/gtests/ssl_gtest/tls_filter.cc @@ -12,6 +12,7 @@ extern "C" { #include "libssl_internals.h" } +#include <cassert> #include <iostream> #include "gtest_utils.h" #include "tls_agent.h" @@ -57,17 +58,22 @@ void TlsRecordFilter::CipherSpecChanged(void* arg, PRBool sending, PRBool isServer = self->agent()->role() == TlsAgent::SERVER; if (g_ssl_gtest_verbose) { - std::cerr << "Cipher spec changed. Role=" - << (isServer ? "server" : "client") - << " direction=" << (sending ? "send" : "receive") << std::endl; + std::cerr << (isServer ? "server" : "client") << ": " + << (sending ? "send" : "receive") + << " cipher spec changed: " << newSpec->epoch << " (" + << newSpec->phase << ")" << std::endl; + } + if (!sending) { + return; } - if (!sending) return; + self->in_sequence_number_ = 0; + self->out_sequence_number_ = 0; + self->dropped_record_ = false; self->cipher_spec_.reset(new TlsCipherSpec()); - bool ret = - self->cipher_spec_->Init(SSLInt_CipherSpecToAlgorithm(isServer, newSpec), - SSLInt_CipherSpecToKey(isServer, newSpec), - SSLInt_CipherSpecToIv(isServer, newSpec)); + bool ret = self->cipher_spec_->Init( + SSLInt_CipherSpecToEpoch(newSpec), SSLInt_CipherSpecToAlgorithm(newSpec), + SSLInt_CipherSpecToKey(newSpec), SSLInt_CipherSpecToIv(newSpec)); EXPECT_EQ(true, ret); } @@ -83,11 +89,23 @@ PacketFilter::Action TlsRecordFilter::Filter(const DataBuffer& input, TlsRecordHeader header; DataBuffer record; - if (!header.Parse(&parser, &record)) { + if (!header.Parse(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). + // + // 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_; + } + if (FilterRecord(header, record, &offset, output) != KEEP) { changed = true; } else { @@ -120,30 +138,49 @@ PacketFilter::Action TlsRecordFilter::FilterRecord( 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 + // previous packets were dropped. if (action == KEEP) { - return KEEP; + if (header.is_dtls() || !dropped_record_) { + return KEEP; + } + filtered = plaintext; } if (action == DROP) { - std::cerr << "record drop: " << record << std::endl; + std::cerr << "record drop: " << header << ":" << record << std::endl; + dropped_record_ = true; return DROP; } EXPECT_GT(0x10000U, filtered.len()); - std::cerr << "record old: " << plaintext << std::endl; - std::cerr << "record new: " << filtered << std::endl; + if (action != KEEP) { + std::cerr << "record old: " << plaintext << std::endl; + std::cerr << "record new: " << filtered << std::endl; + } + + uint64_t seq_num; + if (header.is_dtls() || !cipher_spec_ || + header.content_type() != kTlsApplicationDataType) { + seq_num = header.sequence_number(); + } else { + seq_num = out_sequence_number_++; + } + TlsRecordHeader out_header = {header.version(), header.content_type(), + seq_num}; DataBuffer ciphertext; - bool rv = Protect(header, inner_content_type, filtered, &ciphertext); + bool rv = Protect(out_header, inner_content_type, filtered, &ciphertext); EXPECT_TRUE(rv); if (!rv) { return KEEP; } - *offset = header.Write(output, *offset, ciphertext); + *offset = out_header.Write(output, *offset, ciphertext); return CHANGE; } -bool TlsRecordHeader::Parse(TlsParser* parser, DataBuffer* body) { +bool TlsRecordHeader::Parse(uint64_t sequence_number, TlsParser* parser, + DataBuffer* body) { if (!parser->Read(&content_type_)) { return false; } @@ -154,7 +191,7 @@ bool TlsRecordHeader::Parse(TlsParser* parser, DataBuffer* body) { } version_ = version; - sequence_number_ = 0; + // If this is DTLS, overwrite the sequence number. if (IsDtls(version)) { uint32_t tmp; if (!parser->Read(&tmp, 4)) { @@ -165,6 +202,8 @@ bool TlsRecordHeader::Parse(TlsParser* parser, DataBuffer* body) { return false; } sequence_number_ |= static_cast<uint64_t>(tmp); + } else { + sequence_number_ = sequence_number; } return parser->ReadVariable(body, 2); } @@ -193,7 +232,9 @@ bool TlsRecordFilter::Unprotect(const TlsRecordHeader& header, return true; } - if (!cipher_spec_->Unprotect(header, ciphertext, plaintext)) return false; + if (!cipher_spec_->Unprotect(header, ciphertext, plaintext)) { + return false; + } size_t len = plaintext->len(); while (len > 0 && !plaintext->data()[len - 1]) { @@ -206,6 +247,11 @@ bool TlsRecordFilter::Unprotect(const TlsRecordHeader& header, *inner_content_type = plaintext->data()[len - 1]; plaintext->Truncate(len - 1); + if (g_ssl_gtest_verbose) { + std::cerr << "unprotect: " << std::hex << header.sequence_number() + << std::dec << " type=" << static_cast<int>(*inner_content_type) + << " " << *plaintext << std::endl; + } return true; } @@ -218,16 +264,44 @@ bool TlsRecordFilter::Protect(const TlsRecordHeader& header, *ciphertext = plaintext; return true; } + if (g_ssl_gtest_verbose) { + std::cerr << "protect: " << header.sequence_number() << std::endl; + } DataBuffer padded = plaintext; padded.Write(padded.len(), inner_content_type, 1); return cipher_spec_->Protect(header, padded, ciphertext); } +bool IsHelloRetry(const DataBuffer& body) { + static const uint8_t ssl_hello_retry_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}; + return memcmp(body.data() + 2, ssl_hello_retry_random, + sizeof(ssl_hello_retry_random)) == 0; +} + +bool TlsHandshakeFilter::IsFilteredType(const HandshakeHeader& header, + const DataBuffer& body) { + if (handshake_types_.empty()) { + return true; + } + + uint8_t type = header.handshake_type(); + if (type == kTlsHandshakeServerHello) { + if (IsHelloRetry(body)) { + type = kTlsHandshakeHelloRetryRequest; + } + } + return handshake_types_.count(type) > 0U; +} + PacketFilter::Action TlsHandshakeFilter::FilterRecord( const TlsRecordHeader& record_header, const DataBuffer& input, DataBuffer* output) { // Check that the first byte is as requested. - if (record_header.content_type() != kTlsHandshakeType) { + if ((record_header.content_type() != kTlsHandshakeType) && + (record_header.content_type() != kTlsAltHandshakeType)) { return KEEP; } @@ -239,12 +313,29 @@ PacketFilter::Action TlsHandshakeFilter::FilterRecord( while (parser.remaining()) { HandshakeHeader header; DataBuffer handshake; - if (!header.Parse(&parser, record_header, &handshake)) { + bool complete = false; + if (!header.Parse(&parser, record_header, preceding_fragment_, &handshake, + &complete)) { return KEEP; } + if (!complete) { + EXPECT_TRUE(record_header.is_dtls()); + // Save the fragment and drop it from this record. Fragments are + // coalesced with the last fragment of the handshake message. + changed = true; + preceding_fragment_.Assign(handshake); + continue; + } + preceding_fragment_.Truncate(0); + DataBuffer filtered; - PacketFilter::Action action = FilterHandshake(header, handshake, &filtered); + PacketFilter::Action action; + if (!IsFilteredType(header, handshake)) { + action = KEEP; + } else { + action = FilterHandshake(header, handshake, &filtered); + } if (action == DROP) { changed = true; std::cerr << "handshake drop: " << handshake << std::endl; @@ -258,6 +349,8 @@ PacketFilter::Action TlsHandshakeFilter::FilterRecord( std::cerr << "handshake old: " << handshake << std::endl; std::cerr << "handshake new: " << filtered << std::endl; source = &filtered; + } else if (preceding_fragment_.len()) { + changed = true; } offset = header.Write(output, offset, *source); @@ -267,12 +360,16 @@ PacketFilter::Action TlsHandshakeFilter::FilterRecord( } bool TlsHandshakeFilter::HandshakeHeader::ReadLength( - TlsParser* parser, const TlsRecordHeader& header, uint32_t* length) { - if (!parser->Read(length, 3)) { + TlsParser* parser, const TlsRecordHeader& header, uint32_t expected_offset, + uint32_t* length, bool* last_fragment) { + uint32_t message_length; + if (!parser->Read(&message_length, 3)) { return false; // malformed } if (!header.is_dtls()) { + *last_fragment = true; + *length = message_length; return true; // nothing left to do } @@ -283,32 +380,50 @@ bool TlsHandshakeFilter::HandshakeHeader::ReadLength( } message_seq_ = message_seq_tmp; - uint32_t fragment_offset; - if (!parser->Read(&fragment_offset, 3)) { + uint32_t offset = 0; + if (!parser->Read(&offset, 3)) { + return false; + } + // We only parse if the fragments are all complete and in order. + if (offset != expected_offset) { + EXPECT_NE(0U, header.epoch()) + << "Received out of order handshake fragment for epoch 0"; return false; } - uint32_t fragment_length; - if (!parser->Read(&fragment_length, 3)) { + // For DTLS, we return the length of just this fragment. + if (!parser->Read(length, 3)) { return false; } - // All current tests where we are using this code don't fragment. - return (fragment_offset == 0 && fragment_length == *length); + // It's a fragment if the entire message is longer than what we have. + *last_fragment = message_length == (*length + offset); + return true; } bool TlsHandshakeFilter::HandshakeHeader::Parse( - TlsParser* parser, const TlsRecordHeader& record_header, DataBuffer* body) { + TlsParser* parser, const TlsRecordHeader& record_header, + const DataBuffer& preceding_fragment, DataBuffer* body, bool* complete) { + *complete = false; + version_ = record_header.version(); if (!parser->Read(&handshake_type_)) { return false; // malformed } + uint32_t length; - if (!ReadLength(parser, record_header, &length)) { + if (!ReadLength(parser, record_header, preceding_fragment.len(), &length, + complete)) { return false; } - return parser->Read(body, length); + if (!parser->Read(body, length)) { + return false; + } + if (preceding_fragment.len()) { + body->Splice(preceding_fragment, 0); + } + return true; } size_t TlsHandshakeFilter::HandshakeHeader::WriteFragment( @@ -337,7 +452,7 @@ size_t TlsHandshakeFilter::HandshakeHeader::Write( return offset; } -PacketFilter::Action TlsInspectorRecordHandshakeMessage::FilterHandshake( +PacketFilter::Action TlsHandshakeRecorder::FilterHandshake( const HandshakeHeader& header, const DataBuffer& input, DataBuffer* output) { // Only do this once. @@ -345,20 +460,23 @@ PacketFilter::Action TlsInspectorRecordHandshakeMessage::FilterHandshake( return KEEP; } - if (header.handshake_type() == handshake_type_) { - buffer_ = input; - } + buffer_ = input; return KEEP; } PacketFilter::Action TlsInspectorReplaceHandshakeMessage::FilterHandshake( const HandshakeHeader& header, const DataBuffer& input, DataBuffer* output) { - if (header.handshake_type() == handshake_type_) { - *output = buffer_; - return CHANGE; - } + *output = buffer_; + return CHANGE; +} +PacketFilter::Action TlsRecordRecorder::FilterRecord( + const TlsRecordHeader& header, const DataBuffer& input, + DataBuffer* output) { + if (!filter_ || (header.content_type() == ct_)) { + records_.push_back({header, input}); + } return KEEP; } @@ -369,15 +487,30 @@ PacketFilter::Action TlsConversationRecorder::FilterRecord( return KEEP; } +PacketFilter::Action TlsHeaderRecorder::FilterRecord( + const TlsRecordHeader& header, const DataBuffer& input, + DataBuffer* output) { + headers_.push_back(header); + return KEEP; +} + +const TlsRecordHeader* TlsHeaderRecorder::header(size_t index) { + if (index > headers_.size() + 1) { + return nullptr; + } + return &headers_[index]; +} + PacketFilter::Action ChainedPacketFilter::Filter(const DataBuffer& input, DataBuffer* output) { DataBuffer in(input); bool changed = false; for (auto it = filters_.begin(); it != filters_.end(); ++it) { - PacketFilter::Action action = (*it)->Filter(in, output); + PacketFilter::Action action = (*it)->Process(in, output); if (action == DROP) { return DROP; } + if (action == CHANGE) { in = *output; changed = true; @@ -430,15 +563,6 @@ bool FindServerHelloExtensions(TlsParser* parser, const TlsVersioned& header) { return true; } -static bool FindHelloRetryExtensions(TlsParser* parser, - const TlsVersioned& header) { - // TODO for -19 add cipher suite - if (!parser->Skip(2)) { // version - return false; - } - return true; -} - bool FindEncryptedExtensions(TlsParser* parser, const TlsVersioned& header) { return true; } @@ -448,13 +572,6 @@ static bool FindCertReqExtensions(TlsParser* parser, if (!parser->SkipVariable(1)) { // request context return false; } - // TODO remove the next two for -19 - if (!parser->SkipVariable(2)) { // signature_algorithms - return false; - } - if (!parser->SkipVariable(2)) { // certificate_authorities - return false; - } return true; } @@ -478,6 +595,9 @@ static bool FindNewSessionTicketExtensions(TlsParser* parser, if (!parser->Skip(8)) { // lifetime, age add return false; } + if (!parser->SkipVariable(1)) { // ticket_nonce + return false; + } if (!parser->SkipVariable(2)) { // ticket return false; } @@ -487,7 +607,6 @@ static bool FindNewSessionTicketExtensions(TlsParser* parser, static const std::map<uint16_t, TlsExtensionFinder> kExtensionFinders = { {kTlsHandshakeClientHello, FindClientHelloExtensions}, {kTlsHandshakeServerHello, FindServerHelloExtensions}, - {kTlsHandshakeHelloRetryRequest, FindHelloRetryExtensions}, {kTlsHandshakeEncryptedExtensions, FindEncryptedExtensions}, {kTlsHandshakeCertificateRequest, FindCertReqExtensions}, {kTlsHandshakeCertificate, FindCertificateExtensions}, @@ -505,10 +624,6 @@ bool TlsExtensionFilter::FindExtensions(TlsParser* parser, PacketFilter::Action TlsExtensionFilter::FilterHandshake( const HandshakeHeader& header, const DataBuffer& input, DataBuffer* output) { - if (handshake_types_.count(header.handshake_type()) == 0) { - return KEEP; - } - TlsParser parser(input); if (!FindExtensions(&parser, header)) { return KEEP; @@ -610,13 +725,45 @@ PacketFilter::Action TlsExtensionDropper::FilterExtension( return KEEP; } +PacketFilter::Action TlsExtensionInjector::FilterHandshake( + const HandshakeHeader& header, const DataBuffer& input, + DataBuffer* output) { + TlsParser parser(input); + if (!TlsExtensionFilter::FindExtensions(&parser, header)) { + return KEEP; + } + size_t offset = parser.consumed(); + + *output = input; + + // Increase the size of the extensions. + uint16_t ext_len; + memcpy(&ext_len, output->data() + offset, sizeof(ext_len)); + ext_len = htons(ntohs(ext_len) + data_.len() + 4); + memcpy(output->data() + offset, &ext_len, sizeof(ext_len)); + + // Insert the extension type and length. + DataBuffer type_length; + type_length.Allocate(4); + type_length.Write(0, extension_, 2); + type_length.Write(2, data_.len(), 2); + output->Splice(type_length, offset + 2); + + // Insert the payload. + if (data_.len() > 0) { + output->Splice(data_, offset + 6); + } + + return CHANGE; +} + PacketFilter::Action AfterRecordN::FilterRecord(const TlsRecordHeader& header, const DataBuffer& body, DataBuffer* out) { if (counter_++ == record_) { DataBuffer buf; header.Write(&buf, 0, body); - src_.lock()->SendDirect(buf); + agent()->SendDirect(buf); dest_.lock()->Handshake(); func_(); return DROP; @@ -625,13 +772,11 @@ PacketFilter::Action AfterRecordN::FilterRecord(const TlsRecordHeader& header, return KEEP; } -PacketFilter::Action TlsInspectorClientHelloVersionChanger::FilterHandshake( +PacketFilter::Action TlsClientHelloVersionChanger::FilterHandshake( const HandshakeHeader& header, const DataBuffer& input, DataBuffer* output) { - if (header.handshake_type() == kTlsHandshakeClientKeyExchange) { - EXPECT_EQ(SECSuccess, - SSLInt_IncrementClientHandshakeVersion(server_.lock()->ssl_fd())); - } + EXPECT_EQ(SECSuccess, + SSLInt_IncrementClientHandshakeVersion(server_.lock()->ssl_fd())); return KEEP; } @@ -643,15 +788,49 @@ PacketFilter::Action SelectiveDropFilter::Filter(const DataBuffer& input, return ((1 << counter_++) & pattern_) ? DROP : KEEP; } -PacketFilter::Action TlsInspectorClientHelloVersionSetter::FilterHandshake( +PacketFilter::Action SelectiveRecordDropFilter::FilterRecord( + const TlsRecordHeader& header, const DataBuffer& data, + DataBuffer* changed) { + if (counter_ >= 32) { + return KEEP; + } + return ((1 << counter_++) & pattern_) ? DROP : KEEP; +} + +/* static */ uint32_t SelectiveRecordDropFilter::ToPattern( + std::initializer_list<size_t> records) { + uint32_t pattern = 0; + for (auto it = records.begin(); it != records.end(); ++it) { + EXPECT_GT(32U, *it); + assert(*it < 32U); + pattern |= 1 << *it; + } + return pattern; +} + +PacketFilter::Action TlsClientHelloVersionSetter::FilterHandshake( const HandshakeHeader& header, const DataBuffer& input, DataBuffer* output) { - if (header.handshake_type() == kTlsHandshakeClientHello) { - *output = input; - output->Write(0, version_, 2); - return CHANGE; - } - return KEEP; + *output = input; + output->Write(0, version_, 2); + return CHANGE; +} + +PacketFilter::Action SelectedCipherSuiteReplacer::FilterHandshake( + const HandshakeHeader& header, const DataBuffer& input, + DataBuffer* output) { + *output = input; + uint32_t temp = 0; + EXPECT_TRUE(input.Read(0, 2, &temp)); + // Cipher suite is after version(2) and random(32). + size_t pos = 34; + if (temp < SSL_LIBRARY_VERSION_TLS_1_3) { + // In old versions, we have to skip a session_id too. + EXPECT_TRUE(input.Read(pos, 1, &temp)); + pos += 1 + temp; + } + output->Write(pos, static_cast<uint32_t>(cipher_suite_), 2); + return CHANGE; } } // namespace nss_test diff --git a/security/nss/gtests/ssl_gtest/tls_filter.h b/security/nss/gtests/ssl_gtest/tls_filter.h index e4030e23f..1bbe190ab 100644 --- a/security/nss/gtests/ssl_gtest/tls_filter.h +++ b/security/nss/gtests/ssl_gtest/tls_filter.h @@ -13,6 +13,7 @@ #include <vector> #include "test_io.h" +#include "tls_agent.h" #include "tls_parser.h" #include "tls_protect.h" @@ -23,7 +24,6 @@ extern "C" { namespace nss_test { class TlsCipherSpec; -class TlsAgent; class TlsVersioned { public: @@ -50,10 +50,13 @@ class TlsRecordHeader : public TlsVersioned { uint8_t content_type() const { return content_type_; } uint64_t sequence_number() const { return sequence_number_; } - size_t header_length() const { return is_dtls() ? 11 : 3; } + uint16_t epoch() const { + return static_cast<uint16_t>(sequence_number_ >> 48); + } + size_t header_length() const { return is_dtls() ? 13 : 5; } // Parse the header; return true if successful; body in an outparam if OK. - bool Parse(TlsParser* parser, DataBuffer* body); + bool Parse(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; @@ -63,13 +66,32 @@ class TlsRecordHeader : public TlsVersioned { uint64_t sequence_number_; }; +struct TlsRecord { + const TlsRecordHeader header; + const DataBuffer buffer; +}; + +// Make a filter and install it on a TlsAgent. +template <class T, typename... Args> +inline std::shared_ptr<T> MakeTlsFilter(const std::shared_ptr<TlsAgent>& agent, + Args&&... args) { + auto filter = std::make_shared<T>(agent, std::forward<Args>(args)...); + agent->SetFilter(filter); + return filter; +} + // Abstract filter that operates on entire (D)TLS records. class TlsRecordFilter : public PacketFilter { public: - TlsRecordFilter() : agent_(nullptr), count_(0), cipher_spec_() {} + TlsRecordFilter(const std::shared_ptr<TlsAgent>& agent) + : agent_(agent), + count_(0), + cipher_spec_(), + dropped_record_(false), + in_sequence_number_(0), + out_sequence_number_(0) {} - void SetAgent(const TlsAgent* agent) { agent_ = agent; } - const TlsAgent* agent() const { return agent_; } + std::shared_ptr<TlsAgent> agent() const { return agent_.lock(); } // External interface. Overrides PacketFilter. PacketFilter::Action Filter(const DataBuffer& input, DataBuffer* output); @@ -112,17 +134,24 @@ class TlsRecordFilter : public PacketFilter { static void CipherSpecChanged(void* arg, PRBool sending, ssl3CipherSpec* newSpec); - const TlsAgent* agent_; + std::weak_ptr<TlsAgent> agent_; size_t count_; std::unique_ptr<TlsCipherSpec> cipher_spec_; + // Whether we dropped a record since the cipher spec changed. + bool dropped_record_; + // The sequence number we use for reading records as they are written. + uint64_t in_sequence_number_; + // The sequence number we use for writing modified records. + uint64_t out_sequence_number_; }; -inline std::ostream& operator<<(std::ostream& stream, TlsVersioned v) { +inline std::ostream& operator<<(std::ostream& stream, const TlsVersioned& v) { v.WriteStream(stream); return stream; } -inline std::ostream& operator<<(std::ostream& stream, TlsRecordHeader& hdr) { +inline std::ostream& operator<<(std::ostream& stream, + const TlsRecordHeader& hdr) { hdr.WriteStream(stream); stream << ' '; switch (hdr.content_type()) { @@ -133,13 +162,17 @@ inline std::ostream& operator<<(std::ostream& stream, TlsRecordHeader& hdr) { stream << "Alert"; break; case kTlsHandshakeType: + case kTlsAltHandshakeType: stream << "Handshake"; break; case kTlsApplicationDataType: stream << "Data"; break; + case kTlsAckType: + stream << "ACK"; + break; default: - stream << '<' << hdr.content_type() << '>'; + stream << '<' << static_cast<int>(hdr.content_type()) << '>'; break; } return stream << ' ' << std::hex << hdr.sequence_number() << std::dec; @@ -150,7 +183,20 @@ inline std::ostream& operator<<(std::ostream& stream, TlsRecordHeader& hdr) { // records and that they don't span records or anything crazy like that. class TlsHandshakeFilter : public TlsRecordFilter { public: - TlsHandshakeFilter() {} + TlsHandshakeFilter(const std::shared_ptr<TlsAgent>& agent) + : TlsRecordFilter(agent), handshake_types_(), preceding_fragment_() {} + TlsHandshakeFilter(const std::shared_ptr<TlsAgent>& agent, + const std::set<uint8_t>& types) + : TlsRecordFilter(agent), + 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 + // will be filtered. + void SetHandshakeTypes(const std::set<uint8_t>& types) { + handshake_types_ = types; + } class HandshakeHeader : public TlsVersioned { public: @@ -158,7 +204,8 @@ class TlsHandshakeFilter : public TlsRecordFilter { uint8_t handshake_type() const { return handshake_type_; } bool Parse(TlsParser* parser, const TlsRecordHeader& record_header, - DataBuffer* body); + const DataBuffer& preceding_fragment, DataBuffer* body, + bool* complete); size_t Write(DataBuffer* buffer, size_t offset, const DataBuffer& body) const; size_t WriteFragment(DataBuffer* buffer, size_t offset, @@ -169,7 +216,8 @@ class TlsHandshakeFilter : public TlsRecordFilter { // Reads the length from the record header. // This also reads the DTLS fragment information and checks it. bool ReadLength(TlsParser* parser, const TlsRecordHeader& header, - uint32_t* length); + uint32_t expected_offset, uint32_t* length, + bool* last_fragment); uint8_t handshake_type_; uint16_t message_seq_; @@ -185,60 +233,115 @@ class TlsHandshakeFilter : public TlsRecordFilter { DataBuffer* output) = 0; private: + bool IsFilteredType(const HandshakeHeader& header, + const DataBuffer& handshake); + + std::set<uint8_t> handshake_types_; + DataBuffer preceding_fragment_; }; // Make a copy of the first instance of a handshake message. -class TlsInspectorRecordHandshakeMessage : public TlsHandshakeFilter { +class TlsHandshakeRecorder : public TlsHandshakeFilter { public: - TlsInspectorRecordHandshakeMessage(uint8_t handshake_type) - : handshake_type_(handshake_type), buffer_() {} + TlsHandshakeRecorder(const std::shared_ptr<TlsAgent>& agent, + uint8_t handshake_type) + : TlsHandshakeFilter(agent, {handshake_type}), buffer_() {} + TlsHandshakeRecorder(const std::shared_ptr<TlsAgent>& agent, + const std::set<uint8_t>& handshake_types) + : TlsHandshakeFilter(agent, handshake_types), buffer_() {} virtual PacketFilter::Action FilterHandshake(const HandshakeHeader& header, const DataBuffer& input, DataBuffer* output); + void Reset() { buffer_.Truncate(0); } + const DataBuffer& buffer() const { return buffer_; } private: - uint8_t handshake_type_; DataBuffer buffer_; }; // Replace all instances of a handshake message. class TlsInspectorReplaceHandshakeMessage : public TlsHandshakeFilter { public: - TlsInspectorReplaceHandshakeMessage(uint8_t handshake_type, + TlsInspectorReplaceHandshakeMessage(const std::shared_ptr<TlsAgent>& agent, + uint8_t handshake_type, const DataBuffer& replacement) - : handshake_type_(handshake_type), buffer_(replacement) {} + : TlsHandshakeFilter(agent, {handshake_type}), buffer_(replacement) {} virtual PacketFilter::Action FilterHandshake(const HandshakeHeader& header, const DataBuffer& input, DataBuffer* output); private: - uint8_t handshake_type_; DataBuffer buffer_; }; +// 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), + filter_(false), + ct_(content_handshake), // dummy (<optional> is C++14) + records_() {} + virtual PacketFilter::Action FilterRecord(const TlsRecordHeader& header, + const DataBuffer& input, + DataBuffer* output); + + size_t count() const { return records_.size(); } + void Clear() { records_.clear(); } + + const TlsRecord& record(size_t i) const { return records_[i]; } + + private: + bool filter_; + uint8_t ct_; + std::vector<TlsRecord> records_; +}; + // Make a copy of the complete conversation. class TlsConversationRecorder : public TlsRecordFilter { public: - TlsConversationRecorder(DataBuffer& buffer) : buffer_(buffer) {} + TlsConversationRecorder(const std::shared_ptr<TlsAgent>& agent, + DataBuffer& buffer) + : TlsRecordFilter(agent), buffer_(buffer) {} virtual PacketFilter::Action FilterRecord(const TlsRecordHeader& header, const DataBuffer& input, DataBuffer* output); private: - DataBuffer& buffer_; + DataBuffer buffer_; }; +// Make a copy of the records +class TlsHeaderRecorder : public TlsRecordFilter { + public: + TlsHeaderRecorder(const std::shared_ptr<TlsAgent>& agent) + : TlsRecordFilter(agent) {} + virtual PacketFilter::Action FilterRecord(const TlsRecordHeader& header, + const DataBuffer& input, + DataBuffer* output); + const TlsRecordHeader* header(size_t index); + + private: + std::vector<TlsRecordHeader> headers_; +}; + +typedef std::initializer_list<std::shared_ptr<PacketFilter>> + ChainedPacketFilterInit; + // Runs multiple packet filters in series. class ChainedPacketFilter : public PacketFilter { public: ChainedPacketFilter() {} ChainedPacketFilter(const std::vector<std::shared_ptr<PacketFilter>> filters) : filters_(filters.begin(), filters.end()) {} + ChainedPacketFilter(ChainedPacketFilterInit il) : filters_(il) {} virtual ~ChainedPacketFilter() {} virtual PacketFilter::Action Filter(const DataBuffer& input, @@ -256,13 +359,15 @@ typedef std::function<bool(TlsParser* parser, const TlsVersioned& header)> class TlsExtensionFilter : public TlsHandshakeFilter { public: - TlsExtensionFilter() : handshake_types_() { - handshake_types_.insert(kTlsHandshakeClientHello); - handshake_types_.insert(kTlsHandshakeServerHello); - } + TlsExtensionFilter(const std::shared_ptr<TlsAgent>& agent) + : TlsHandshakeFilter(agent, + {kTlsHandshakeClientHello, kTlsHandshakeServerHello, + kTlsHandshakeHelloRetryRequest, + kTlsHandshakeEncryptedExtensions}) {} - TlsExtensionFilter(const std::set<uint8_t>& types) - : handshake_types_(types) {} + TlsExtensionFilter(const std::shared_ptr<TlsAgent>& agent, + const std::set<uint8_t>& types) + : TlsHandshakeFilter(agent, types) {} static bool FindExtensions(TlsParser* parser, const HandshakeHeader& header); @@ -279,14 +384,17 @@ class TlsExtensionFilter : public TlsHandshakeFilter { PacketFilter::Action FilterExtensions(TlsParser* parser, const DataBuffer& input, DataBuffer* output); - - std::set<uint8_t> handshake_types_; }; class TlsExtensionCapture : public TlsExtensionFilter { public: - TlsExtensionCapture(uint16_t ext, bool last = false) - : extension_(ext), captured_(false), last_(last), data_() {} + TlsExtensionCapture(const std::shared_ptr<TlsAgent>& agent, uint16_t ext, + bool last = false) + : TlsExtensionFilter(agent), + extension_(ext), + captured_(false), + last_(last), + data_() {} const DataBuffer& extension() const { return data_; } bool captured() const { return captured_; } @@ -305,8 +413,9 @@ class TlsExtensionCapture : public TlsExtensionFilter { class TlsExtensionReplacer : public TlsExtensionFilter { public: - TlsExtensionReplacer(uint16_t extension, const DataBuffer& data) - : extension_(extension), data_(data) {} + TlsExtensionReplacer(const std::shared_ptr<TlsAgent>& agent, + uint16_t extension, const DataBuffer& data) + : TlsExtensionFilter(agent), extension_(extension), data_(data) {} PacketFilter::Action FilterExtension(uint16_t extension_type, const DataBuffer& input, DataBuffer* output) override; @@ -318,7 +427,9 @@ class TlsExtensionReplacer : public TlsExtensionFilter { class TlsExtensionDropper : public TlsExtensionFilter { public: - TlsExtensionDropper(uint16_t extension) : extension_(extension) {} + TlsExtensionDropper(const std::shared_ptr<TlsAgent>& agent, + uint16_t extension) + : TlsExtensionFilter(agent), extension_(extension) {} PacketFilter::Action FilterExtension(uint16_t extension_type, const DataBuffer&, DataBuffer*) override; @@ -326,21 +437,41 @@ class TlsExtensionDropper : public TlsExtensionFilter { uint16_t extension_; }; +class TlsExtensionInjector : public TlsHandshakeFilter { + public: + TlsExtensionInjector(const std::shared_ptr<TlsAgent>& agent, uint16_t ext, + const DataBuffer& data) + : TlsHandshakeFilter(agent), extension_(ext), data_(data) {} + + protected: + PacketFilter::Action FilterHandshake(const HandshakeHeader& header, + const DataBuffer& input, + DataBuffer* output) override; + + private: + const uint16_t extension_; + const DataBuffer data_; +}; + class TlsAgent; typedef std::function<void(void)> VoidFunction; class AfterRecordN : public TlsRecordFilter { public: - AfterRecordN(std::shared_ptr<TlsAgent>& src, std::shared_ptr<TlsAgent>& dest, - unsigned int record, VoidFunction func) - : src_(src), dest_(dest), record_(record), func_(func), counter_(0) {} + AfterRecordN(const std::shared_ptr<TlsAgent>& src, + const std::shared_ptr<TlsAgent>& dest, unsigned int record, + VoidFunction func) + : TlsRecordFilter(src), + dest_(dest), + record_(record), + func_(func), + counter_(0) {} virtual PacketFilter::Action FilterRecord(const TlsRecordHeader& header, const DataBuffer& body, DataBuffer* out) override; private: - std::weak_ptr<TlsAgent> src_; std::weak_ptr<TlsAgent> dest_; unsigned int record_; VoidFunction func_; @@ -349,10 +480,12 @@ class AfterRecordN : public TlsRecordFilter { // When we see the ClientKeyExchange from |client|, increment the // ClientHelloVersion on |server|. -class TlsInspectorClientHelloVersionChanger : public TlsHandshakeFilter { +class TlsClientHelloVersionChanger : public TlsHandshakeFilter { public: - TlsInspectorClientHelloVersionChanger(std::shared_ptr<TlsAgent>& server) - : server_(server) {} + TlsClientHelloVersionChanger(const std::shared_ptr<TlsAgent>& client, + const std::shared_ptr<TlsAgent>& server) + : TlsHandshakeFilter(client, {kTlsHandshakeClientKeyExchange}), + server_(server) {} virtual PacketFilter::Action FilterHandshake(const HandshakeHeader& header, const DataBuffer& input, @@ -377,10 +510,51 @@ class SelectiveDropFilter : public PacketFilter { uint8_t counter_; }; +// This class selectively drops complete records. The difference from +// SelectiveDropFilter is that if multiple DTLS records are in the same +// datagram, we just drop one. +class SelectiveRecordDropFilter : public TlsRecordFilter { + public: + SelectiveRecordDropFilter(const std::shared_ptr<TlsAgent>& agent, + uint32_t pattern, bool enabled = true) + : TlsRecordFilter(agent), pattern_(pattern), counter_(0) { + if (!enabled) { + Disable(); + } + } + SelectiveRecordDropFilter(const std::shared_ptr<TlsAgent>& agent, + std::initializer_list<size_t> records) + : SelectiveRecordDropFilter(agent, ToPattern(records), true) {} + + void Reset(uint32_t pattern) { + counter_ = 0; + PacketFilter::Enable(); + pattern_ = pattern; + } + + void Reset(std::initializer_list<size_t> records) { + Reset(ToPattern(records)); + } + + protected: + PacketFilter::Action FilterRecord(const TlsRecordHeader& header, + const DataBuffer& data, + DataBuffer* changed) override; + + private: + static uint32_t ToPattern(std::initializer_list<size_t> records); + + uint32_t pattern_; + uint8_t counter_; +}; + // Set the version number in the ClientHello. -class TlsInspectorClientHelloVersionSetter : public TlsHandshakeFilter { +class TlsClientHelloVersionSetter : public TlsHandshakeFilter { public: - TlsInspectorClientHelloVersionSetter(uint16_t version) : version_(version) {} + TlsClientHelloVersionSetter(const std::shared_ptr<TlsAgent>& agent, + uint16_t version) + : TlsHandshakeFilter(agent, {kTlsHandshakeClientHello}), + version_(version) {} virtual PacketFilter::Action FilterHandshake(const HandshakeHeader& header, const DataBuffer& input, @@ -393,7 +567,8 @@ class TlsInspectorClientHelloVersionSetter : public TlsHandshakeFilter { // Damages the last byte of a handshake message. class TlsLastByteDamager : public TlsHandshakeFilter { public: - TlsLastByteDamager(uint8_t type) : type_(type) {} + TlsLastByteDamager(const std::shared_ptr<TlsAgent>& agent, uint8_t type) + : TlsHandshakeFilter(agent), type_(type) {} PacketFilter::Action FilterHandshake( const TlsHandshakeFilter::HandshakeHeader& header, const DataBuffer& input, DataBuffer* output) override { @@ -411,6 +586,22 @@ class TlsLastByteDamager : public TlsHandshakeFilter { uint8_t type_; }; +class SelectedCipherSuiteReplacer : public TlsHandshakeFilter { + public: + SelectedCipherSuiteReplacer(const std::shared_ptr<TlsAgent>& agent, + uint16_t suite) + : TlsHandshakeFilter(agent, {kTlsHandshakeServerHello}), + cipher_suite_(suite) {} + + protected: + PacketFilter::Action FilterHandshake(const HandshakeHeader& header, + const DataBuffer& input, + DataBuffer* output) override; + + private: + uint16_t cipher_suite_; +}; + } // namespace nss_test #endif diff --git a/security/nss/gtests/ssl_gtest/tls_hkdf_unittest.cc b/security/nss/gtests/ssl_gtest/tls_hkdf_unittest.cc index 51ff938b1..45f6cf2bd 100644 --- a/security/nss/gtests/ssl_gtest/tls_hkdf_unittest.cc +++ b/security/nss/gtests/ssl_gtest/tls_hkdf_unittest.cc @@ -241,13 +241,13 @@ TEST_P(TlsHkdfTest, HkdfExpandLabel) { {/* ssl_hash_md5 */}, {/* ssl_hash_sha1 */}, {/* ssl_hash_sha224 */}, - {0x34, 0x7c, 0x67, 0x80, 0xff, 0x0b, 0xba, 0xd7, 0x1c, 0x28, 0x3b, - 0x16, 0xeb, 0x2f, 0x9c, 0xf6, 0x2d, 0x24, 0xe6, 0xcd, 0xb6, 0x13, - 0xd5, 0x17, 0x76, 0x54, 0x8c, 0xb0, 0x7d, 0xcd, 0xe7, 0x4c}, - {0x4b, 0x1e, 0x5e, 0xc1, 0x49, 0x30, 0x78, 0xea, 0x35, 0xbd, 0x3f, 0x01, - 0x04, 0xe6, 0x1a, 0xea, 0x14, 0xcc, 0x18, 0x2a, 0xd1, 0xc4, 0x76, 0x21, - 0xc4, 0x64, 0xc0, 0x4e, 0x4b, 0x36, 0x16, 0x05, 0x6f, 0x04, 0xab, 0xe9, - 0x43, 0xb1, 0x2d, 0xa8, 0xa7, 0x17, 0x9a, 0x5f, 0x09, 0x91, 0x7d, 0x1f}}; + {0xc6, 0xdd, 0x6e, 0xc4, 0x76, 0xb8, 0x55, 0xf2, 0xa4, 0xfc, 0x59, + 0x04, 0xa4, 0x90, 0xdc, 0xa7, 0xa7, 0x0d, 0x94, 0x8f, 0xc2, 0xdc, + 0x15, 0x6d, 0x48, 0x93, 0x9d, 0x05, 0xbb, 0x9a, 0xbc, 0xc1}, + {0x41, 0xea, 0x77, 0x09, 0x8c, 0x90, 0x04, 0x10, 0xec, 0xbc, 0x37, 0xd8, + 0x5b, 0x54, 0xcd, 0x7b, 0x08, 0x15, 0x13, 0x20, 0xed, 0x1e, 0x3f, 0x54, + 0x74, 0xf7, 0x8b, 0x06, 0x38, 0x28, 0x06, 0x37, 0x75, 0x23, 0xa2, 0xb7, + 0x34, 0xb1, 0x72, 0x2e, 0x59, 0x6d, 0x5a, 0x31, 0xf5, 0x53, 0xab, 0x99}}; const DataBuffer expected_data(tv[hash_type_], kHashLength[hash_type_]); HkdfExpandLabel(&k1_, hash_type_, kSessionHash, kHashLength[hash_type_], diff --git a/security/nss/gtests/ssl_gtest/tls_protect.cc b/security/nss/gtests/ssl_gtest/tls_protect.cc index efcd89e14..6c945f66e 100644 --- a/security/nss/gtests/ssl_gtest/tls_protect.cc +++ b/security/nss/gtests/ssl_gtest/tls_protect.cc @@ -32,7 +32,6 @@ void AeadCipher::FormatNonce(uint64_t seq, uint8_t *nonce) { } DataBuffer d(nonce, 12); - std::cerr << "Nonce " << d << std::endl; } bool AeadCipher::AeadInner(bool decrypt, void *params, size_t param_length, @@ -92,8 +91,9 @@ bool AeadCipherChacha20Poly1305::Aead(bool decrypt, uint64_t seq, in, inlen, out, outlen, maxlen); } -bool TlsCipherSpec::Init(SSLCipherAlgorithm cipher, PK11SymKey *key, - const uint8_t *iv) { +bool TlsCipherSpec::Init(uint16_t epoch, SSLCipherAlgorithm cipher, + PK11SymKey *key, const uint8_t *iv) { + epoch_ = epoch; switch (cipher) { case ssl_calg_aes_gcm: aead_.reset(new AeadCipherAesGcm()); diff --git a/security/nss/gtests/ssl_gtest/tls_protect.h b/security/nss/gtests/ssl_gtest/tls_protect.h index 4efbd6e6b..93ffd6322 100644 --- a/security/nss/gtests/ssl_gtest/tls_protect.h +++ b/security/nss/gtests/ssl_gtest/tls_protect.h @@ -20,7 +20,7 @@ class TlsRecordHeader; class AeadCipher { public: AeadCipher(CK_MECHANISM_TYPE mech) : mech_(mech), key_(nullptr) {} - ~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, @@ -58,16 +58,19 @@ class AeadCipherAesGcm : public AeadCipher { // Our analog of ssl3CipherSpec class TlsCipherSpec { public: - TlsCipherSpec() : aead_() {} + TlsCipherSpec() : epoch_(0), aead_() {} - bool Init(SSLCipherAlgorithm cipher, PK11SymKey *key, const uint8_t *iv); + bool Init(uint16_t epoch, SSLCipherAlgorithm cipher, PK11SymKey *key, + const uint8_t *iv); bool Protect(const TlsRecordHeader &header, const DataBuffer &plaintext, DataBuffer *ciphertext); bool Unprotect(const TlsRecordHeader &header, const DataBuffer &ciphertext, DataBuffer *plaintext); + uint16_t epoch() const { return epoch_; } private: + uint16_t epoch_; std::unique_ptr<AeadCipher> aead_; }; diff --git a/security/nss/gtests/util_gtest/manifest.mn b/security/nss/gtests/util_gtest/manifest.mn index edede657f..a90e8431e 100644 --- a/security/nss/gtests/util_gtest/manifest.mn +++ b/security/nss/gtests/util_gtest/manifest.mn @@ -10,6 +10,8 @@ CPPSRCS = \ util_utf8_unittest.cc \ util_b64_unittest.cc \ util_pkcs11uri_unittest.cc \ + util_aligned_malloc_unittest.cc \ + util_memcmpzero_unittest.cc \ $(NULL) INCLUDES += \ diff --git a/security/nss/gtests/util_gtest/util_aligned_malloc_unittest.cc b/security/nss/gtests/util_gtest/util_aligned_malloc_unittest.cc new file mode 100644 index 000000000..9745ca7d3 --- /dev/null +++ b/security/nss/gtests/util_gtest/util_aligned_malloc_unittest.cc @@ -0,0 +1,82 @@ +/* -*- 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 "gtest/gtest.h" +#include "scoped_ptrs_util.h" + +namespace nss_test { + +struct SomeContext { + uint8_t some_buf[13]; + void *mem; +}; + +template <class T> +struct ScopedDelete { + void operator()(T *ptr) { + if (ptr) { + PORT_Free(ptr->mem); + } + } +}; +typedef std::unique_ptr<SomeContext, ScopedDelete<SomeContext> > + ScopedSomeContext; + +class AlignedMallocTest : public ::testing::Test, + public ::testing::WithParamInterface<size_t> { + protected: + ScopedSomeContext test_align_new(size_t alignment) { + ScopedSomeContext ctx(PORT_ZNewAligned(SomeContext, alignment, mem)); + return ctx; + }; + ScopedSomeContext test_align_alloc(size_t alignment) { + void *mem = nullptr; + ScopedSomeContext ctx((SomeContext *)PORT_ZAllocAligned(sizeof(SomeContext), + alignment, &mem)); + if (ctx) { + ctx->mem = mem; + } + return ctx; + } +}; + +TEST_P(AlignedMallocTest, TestNew) { + size_t alignment = GetParam(); + ScopedSomeContext ctx = test_align_new(alignment); + EXPECT_TRUE(ctx.get()); + EXPECT_EQ(0U, (uintptr_t)ctx.get() % alignment); +} + +TEST_P(AlignedMallocTest, TestAlloc) { + size_t alignment = GetParam(); + ScopedSomeContext ctx = test_align_alloc(alignment); + EXPECT_TRUE(ctx.get()); + EXPECT_EQ(0U, (uintptr_t)ctx.get() % alignment); +} + +class AlignedMallocTestBadSize : public AlignedMallocTest {}; + +TEST_P(AlignedMallocTestBadSize, TestNew) { + size_t alignment = GetParam(); + ScopedSomeContext ctx = test_align_new(alignment); + EXPECT_FALSE(ctx.get()); +} + +TEST_P(AlignedMallocTestBadSize, TestAlloc) { + size_t alignment = GetParam(); + ScopedSomeContext ctx = test_align_alloc(alignment); + EXPECT_FALSE(ctx.get()); +} + +static const size_t kSizes[] = {1, 2, 4, 8, 16, 32, 64}; +static const size_t kBadSizes[] = {0, 7, 17, 24, 56}; + +INSTANTIATE_TEST_CASE_P(AllAligned, AlignedMallocTest, + ::testing::ValuesIn(kSizes)); +INSTANTIATE_TEST_CASE_P(AllAlignedBadSize, AlignedMallocTestBadSize, + ::testing::ValuesIn(kBadSizes)); + +} // namespace nss_test diff --git a/security/nss/gtests/util_gtest/util_gtest.gyp b/security/nss/gtests/util_gtest/util_gtest.gyp index 7abd71b2f..1c54329b2 100644 --- a/security/nss/gtests/util_gtest/util_gtest.gyp +++ b/security/nss/gtests/util_gtest/util_gtest.gyp @@ -14,6 +14,8 @@ 'util_utf8_unittest.cc', 'util_b64_unittest.cc', 'util_pkcs11uri_unittest.cc', + 'util_aligned_malloc_unittest.cc', + 'util_memcmpzero_unittest.cc', '<(DEPTH)/gtests/common/gtests.cc', ], 'dependencies': [ diff --git a/security/nss/gtests/util_gtest/util_memcmpzero_unittest.cc b/security/nss/gtests/util_gtest/util_memcmpzero_unittest.cc new file mode 100644 index 000000000..29cac3f67 --- /dev/null +++ b/security/nss/gtests/util_gtest/util_memcmpzero_unittest.cc @@ -0,0 +1,45 @@ +/* -*- 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 "gtest/gtest.h" +#include "scoped_ptrs_util.h" + +namespace nss_test { + +class MemcmpZeroTest : public ::testing::Test { + protected: + unsigned int test_memcmp_zero(const std::vector<uint8_t> &mem) { + return NSS_SecureMemcmpZero(mem.data(), mem.size()); + }; +}; + +TEST_F(MemcmpZeroTest, TestMemcmpZeroTrue) { + unsigned int rv = test_memcmp_zero(std::vector<uint8_t>(37, 0)); + EXPECT_EQ(0U, rv); +} + +TEST_F(MemcmpZeroTest, TestMemcmpZeroFalse5) { + std::vector<uint8_t> vec(37, 0); + vec[5] = 1; + unsigned int rv = test_memcmp_zero(vec); + EXPECT_NE(0U, rv); +} + +TEST_F(MemcmpZeroTest, TestMemcmpZeroFalse37) { + std::vector<uint8_t> vec(37, 0); + vec[vec.size() - 1] = 0xFF; + unsigned int rv = test_memcmp_zero(vec); + EXPECT_NE(0U, rv); +} + +TEST_F(MemcmpZeroTest, TestMemcmpZeroFalse0) { + std::vector<uint8_t> vec(37, 0); + vec[0] = 1; + unsigned int rv = test_memcmp_zero(vec); + EXPECT_NE(0U, rv); +} + +} // namespace nss_test diff --git a/security/nss/help.txt b/security/nss/help.txt new file mode 100644 index 000000000..b4ffc0382 --- /dev/null +++ b/security/nss/help.txt @@ -0,0 +1,50 @@ +Usage: build.sh [-hcv] [-cc] [-j <n>] [--nspr] [--gyp|-g] [--opt|-o] [-m32] + [--test] [--pprof] [--scan-build[=output]] [--ct-verif] + [--asan] [--ubsan] [--msan] [--sancov[=edge|bb|func|...]] + [--disable-tests] [--fuzz[=tls|oss]] [--system-sqlite] + [--no-zdefs] [--with-nspr] [--system-nspr] [--enable-libpkix] + [--enable-fips] + +This script builds NSS with gyp and ninja. + +This build system is still under development. It does not yet support all +the features or platforms that NSS supports. + +NSS build tool options: + + -h display this help and exit + -c clean before build + -cc clean without building + -v verbose build + -j <n> run at most <n> concurrent jobs + --nspr force a rebuild of NSPR + --gyp|-g force a rerun of gyp + --opt|-o do an opt build + -m32 do a 32-bit build on a 64-bit system + --clang build with clang and clang++ + --gcc build with gcc and g++ + --test ignore map files and export everything we have + --fuzz build fuzzing targets (this always enables test builds) + --fuzz=tls to enable TLS fuzzing mode + --fuzz=oss to build for OSS-Fuzz + --pprof build with gperftool support + --ct-verif build with valgrind for ct-verif + --scan-build run the build with scan-build (scan-build has to be in the path) + --scan-build=/out/path sets the output path for scan-build + --asan do an asan build + --ubsan do an ubsan build + --ubsan=bool,shift,... sets specific UB sanitizers + --msan do an msan build + --sancov do sanitize coverage builds + --sancov=func sets coverage to function level for example + --emit-llvm emit LLVM bitcode while building + (requires the gold linker, use clang-3.8 for SAW) + --disable-tests don't build tests and corresponding cmdline utils + --system-sqlite use system sqlite + --no-zdefs don't set -Wl,-z,defs + --with-nspr don't build NSPR but use the one at the given location, e.g. + --with-nspr=/path/to/nspr/include:/path/to/nspr/lib + --system-nspr use system nspr. This requires an installation of NSPR and + might not work on all systems. + --enable-libpkix make libpkix part of the build. + --enable-fips don't disable FIPS checks. diff --git a/security/nss/lib/certdb/alg1485.c b/security/nss/lib/certdb/alg1485.c index 38b2fe4b5..9a69c5bc5 100644 --- a/security/nss/lib/certdb/alg1485.c +++ b/security/nss/lib/certdb/alg1485.c @@ -703,14 +703,19 @@ CERT_GetOidString(const SECItem* oid) return NULL; } + /* If the OID has length 1, we bail. */ + if (oid->len < 2) { + return NULL; + } + /* first will point to the next sequence of bytes to decode */ first = (PRUint8*)oid->data; /* stop points to one past the legitimate data */ stop = &first[oid->len]; /* - * Check for our pseudo-encoded single-digit OIDs - */ + * Check for our pseudo-encoded single-digit OIDs + */ if ((*first == 0x80) && (2 == oid->len)) { /* Funky encoding. The second byte is the number */ rvString = PR_smprintf("%lu", (PRUint32)first[1]); @@ -728,6 +733,10 @@ CERT_GetOidString(const SECItem* oid) break; } } + /* There's no first bit set, so this isn't valid. Bail.*/ + if (last == stop) { + goto unsupported; + } bytesBeforeLast = (unsigned int)(last - first); if (bytesBeforeLast <= 3U) { /* 0-28 bit number */ PRUint32 n = 0; @@ -748,12 +757,12 @@ CERT_GetOidString(const SECItem* oid) CASE(2, 0x7f); CASE(1, 0x7f); case 0: - n |= - last[0] & 0x7f; + n |= last[0] & 0x7f; break; } - if (last[0] & 0x80) + if (last[0] & 0x80) { goto unsupported; + } if (!rvString) { /* This is the first number.. decompose it */ @@ -1305,8 +1314,7 @@ CERT_GetCertificateEmailAddress(CERTCertificate* cert) } } else if (current->type == certRFC822Name) { rawEmailAddr = - (char*)PORT_ArenaZAlloc(cert->arena, current->name.other.len + - 1); + (char*)PORT_ArenaZAlloc(cert->arena, current->name.other.len + 1); if (!rawEmailAddr) { goto finish; } diff --git a/security/nss/lib/certdb/cert.h b/security/nss/lib/certdb/cert.h index 4224da108..c76a5a9b0 100644 --- a/security/nss/lib/certdb/cert.h +++ b/security/nss/lib/certdb/cert.h @@ -504,6 +504,8 @@ extern CERTCertificate *CERT_FindCertByKeyID(CERTCertDBHandle *handle, */ extern CERTCertificate *CERT_FindCertByIssuerAndSN( CERTCertDBHandle *handle, CERTIssuerAndSN *issuerAndSN); +extern CERTCertificate *CERT_FindCertByIssuerAndSNCX( + CERTCertDBHandle *handle, CERTIssuerAndSN *issuerAndSN, void *wincx); /* ** Find a certificate in the database by a subject key ID @@ -547,6 +549,9 @@ CERTCertificate *CERT_FindCertByEmailAddr(CERTCertDBHandle *handle, */ CERTCertificate *CERT_FindCertByNicknameOrEmailAddr(CERTCertDBHandle *handle, const char *name); +CERTCertificate *CERT_FindCertByNicknameOrEmailAddrCX(CERTCertDBHandle *handle, + const char *name, + void *wincx); /* ** Find a certificate in the database by a email address or nickname @@ -555,6 +560,9 @@ CERTCertificate *CERT_FindCertByNicknameOrEmailAddr(CERTCertDBHandle *handle, */ CERTCertificate *CERT_FindCertByNicknameOrEmailAddrForUsage( CERTCertDBHandle *handle, const char *name, SECCertUsage lookingForUsage); +CERTCertificate *CERT_FindCertByNicknameOrEmailAddrForUsageCX( + CERTCertDBHandle *handle, const char *name, SECCertUsage lookingForUsage, + void *wincx); /* ** Find a certificate in the database by a digest of a subject public key diff --git a/security/nss/lib/certdb/certdb.c b/security/nss/lib/certdb/certdb.c index 7864edc08..1a676a720 100644 --- a/security/nss/lib/certdb/certdb.c +++ b/security/nss/lib/certdb/certdb.c @@ -1192,6 +1192,7 @@ CERT_CheckKeyUsage(CERTCertificate *cert, unsigned int requiredUsage) case rsaKey: requiredUsage |= KU_KEY_ENCIPHERMENT; break; + case rsaPssKey: case dsaKey: requiredUsage |= KU_DIGITAL_SIGNATURE; break; diff --git a/security/nss/lib/certdb/crl.c b/security/nss/lib/certdb/crl.c index 87469085e..d1c48dfba 100644 --- a/security/nss/lib/certdb/crl.c +++ b/security/nss/lib/certdb/crl.c @@ -1294,8 +1294,7 @@ DPCache_AddCRL(CRLDPCache* cache, CachedCrl* newcrl, PRBool* added) } } - newcrls = (CachedCrl**)PORT_Realloc(cache->crls, (cache->ncrls + 1) * - sizeof(CachedCrl*)); + newcrls = (CachedCrl**)PORT_Realloc(cache->crls, (cache->ncrls + 1) * sizeof(CachedCrl*)); if (!newcrls) { return SECFailure; } diff --git a/security/nss/lib/certdb/stanpcertdb.c b/security/nss/lib/certdb/stanpcertdb.c index 4d42bd50d..d5d19c39d 100644 --- a/security/nss/lib/certdb/stanpcertdb.c +++ b/security/nss/lib/certdb/stanpcertdb.c @@ -30,6 +30,7 @@ #include "pkistore.h" #include "dev3hack.h" #include "dev.h" +#include "secmodi.h" PRBool SEC_CertNicknameConflict(const char *nickname, const SECItem *derSubject, @@ -280,6 +281,18 @@ __CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname, nssCertificateStore_RemoveCertLOCKED(context->certStore, c); nssCertificateStore_Unlock(context->certStore, &lockTrace, &unlockTrace); c->object.cryptoContext = NULL; + + /* if the id has not been set explicitly yet, create one from the public + * key. */ + if (c->id.data == NULL) { + SECItem *keyID = pk11_mkcertKeyID(cert); + if (keyID) { + nssItem_Create(c->object.arena, &c->id, keyID->len, keyID->data); + SECITEM_FreeItem(keyID, PR_TRUE); + } + /* if any of these failed, continue with our null c->id */ + } + /* Import the perm instance onto the internal token */ slot = PK11_GetInternalKeySlot(); internal = PK11Slot_GetNSSToken(slot); @@ -343,7 +356,7 @@ CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert, /* First, see if it is already a temp cert */ c = NSSCryptoContext_FindCertificateByEncodedCertificate(gCC, &encoding); - if (!c) { + if (!c && handle) { /* Then, see if it is already a perm cert */ c = NSSTrustDomain_FindCertificateByEncodedCertificate(handle, &encoding); @@ -457,15 +470,15 @@ __CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert, return CERT_NewTempCertificate(handle, derCert, nickname, isperm, copyDER); } -/* maybe all the wincx's should be some const for internal token login? */ -CERTCertificate * -CERT_FindCertByIssuerAndSN(CERTCertDBHandle *handle, - CERTIssuerAndSN *issuerAndSN) +static CERTCertificate * +common_FindCertByIssuerAndSN(CERTCertDBHandle *handle, + CERTIssuerAndSN *issuerAndSN, + void *wincx) { PK11SlotInfo *slot; CERTCertificate *cert; - cert = PK11_FindCertByIssuerAndSN(&slot, issuerAndSN, NULL); + cert = PK11_FindCertByIssuerAndSN(&slot, issuerAndSN, wincx); if (cert && slot) { PK11_FreeSlot(slot); } @@ -473,6 +486,23 @@ CERT_FindCertByIssuerAndSN(CERTCertDBHandle *handle, return cert; } +/* maybe all the wincx's should be some const for internal token login? */ +CERTCertificate * +CERT_FindCertByIssuerAndSN(CERTCertDBHandle *handle, + CERTIssuerAndSN *issuerAndSN) +{ + return common_FindCertByIssuerAndSN(handle, issuerAndSN, NULL); +} + +/* maybe all the wincx's should be some const for internal token login? */ +CERTCertificate * +CERT_FindCertByIssuerAndSNCX(CERTCertDBHandle *handle, + CERTIssuerAndSN *issuerAndSN, + void *wincx) +{ + return common_FindCertByIssuerAndSN(handle, issuerAndSN, wincx); +} + static NSSCertificate * get_best_temp_or_perm(NSSCertificate *ct, NSSCertificate *cp) { @@ -587,7 +617,8 @@ CERT_FindCertByDERCert(CERTCertDBHandle *handle, SECItem *derCert) static CERTCertificate * common_FindCertByNicknameOrEmailAddrForUsage(CERTCertDBHandle *handle, const char *name, PRBool anyUsage, - SECCertUsage lookingForUsage) + SECCertUsage lookingForUsage, + void *wincx) { NSSCryptoContext *cc; NSSCertificate *c, *ct; @@ -620,7 +651,7 @@ common_FindCertByNicknameOrEmailAddrForUsage(CERTCertDBHandle *handle, } if (anyUsage) { - cert = PK11_FindCertFromNickname(name, NULL); + cert = PK11_FindCertFromNickname(name, wincx); } else { if (ct) { /* Does ct really have the required usage? */ @@ -632,7 +663,7 @@ common_FindCertByNicknameOrEmailAddrForUsage(CERTCertDBHandle *handle, } } - certlist = PK11_FindCertsFromNickname(name, NULL); + certlist = PK11_FindCertsFromNickname(name, wincx); if (certlist) { SECStatus rv = CERT_FilterCertListByUsage(certlist, lookingForUsage, PR_FALSE); @@ -659,7 +690,15 @@ CERTCertificate * CERT_FindCertByNicknameOrEmailAddr(CERTCertDBHandle *handle, const char *name) { return common_FindCertByNicknameOrEmailAddrForUsage(handle, name, PR_TRUE, - 0); + 0, NULL); +} + +CERTCertificate * +CERT_FindCertByNicknameOrEmailAddrCX(CERTCertDBHandle *handle, const char *name, + void *wincx) +{ + return common_FindCertByNicknameOrEmailAddrForUsage(handle, name, PR_TRUE, + 0, wincx); } CERTCertificate * @@ -668,7 +707,17 @@ CERT_FindCertByNicknameOrEmailAddrForUsage(CERTCertDBHandle *handle, SECCertUsage lookingForUsage) { return common_FindCertByNicknameOrEmailAddrForUsage(handle, name, PR_FALSE, - lookingForUsage); + lookingForUsage, NULL); +} + +CERTCertificate * +CERT_FindCertByNicknameOrEmailAddrForUsageCX(CERTCertDBHandle *handle, + const char *name, + SECCertUsage lookingForUsage, + void *wincx) +{ + return common_FindCertByNicknameOrEmailAddrForUsage(handle, name, PR_FALSE, + lookingForUsage, wincx); } static void diff --git a/security/nss/lib/ckfw/builtins/certdata.txt b/security/nss/lib/ckfw/builtins/certdata.txt index 45b659b7a..5d2baf3a5 100644 --- a/security/nss/lib/ckfw/builtins/certdata.txt +++ b/security/nss/lib/ckfw/builtins/certdata.txt @@ -69,34 +69,6 @@ CKA_PRIVATE CK_BBOOL CK_FALSE CKA_MODIFIABLE CK_BBOOL CK_FALSE CKA_LABEL UTF8 "Mozilla Builtin Roots" -# Distrust "Distrust a pb.com certificate that does not comply with the baseline requirements." -# Issuer: OU=Equifax Secure Certificate Authority,O=Equifax,C=US -# Serial Number: 1407252 (0x157914) -# Subject: CN=*.pb.com,OU=Meters,O=Pitney Bowes,L=Danbury,ST=Connecticut,C=US -# Not Valid Before: Mon Feb 01 14:54:04 2010 -# Not Valid After : Tue Sep 30 00:00:00 2014 -# Fingerprint (MD5): 8F:46:BE:99:47:6F:93:DC:5C:01:54:50:D0:4A:BD:AC -# Fingerprint (SHA1): 30:F1:82:CA:1A:5E:4E:4F:F3:6E:D0:E6:38:18:B8:B9:41:CB:5F:8C -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 "Distrust a pb.com certificate that does not comply with the baseline requirements." -CKA_ISSUER MULTILINE_OCTAL -\060\116\061\013\060\011\006\003\125\004\006\023\002\125\123\061 -\020\060\016\006\003\125\004\012\023\007\105\161\165\151\146\141 -\170\061\055\060\053\006\003\125\004\013\023\044\105\161\165\151 -\146\141\170\040\123\145\143\165\162\145\040\103\145\162\164\151 -\146\151\143\141\164\145\040\101\165\164\150\157\162\151\164\171 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\003\025\171\024 -END -CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED -CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED -CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED -CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE - # # Certificate "GlobalSign Root CA" # @@ -2426,7 +2398,7 @@ END CKA_SERIAL_NUMBER MULTILINE_OCTAL \002\003\001\000\040 END -CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR +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 @@ -3684,7 +3656,7 @@ END CKA_SERIAL_NUMBER MULTILINE_OCTAL \002\001\000 END -CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR +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 @@ -3843,7 +3815,7 @@ END CKA_SERIAL_NUMBER MULTILINE_OCTAL \002\001\000 END -CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR +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 @@ -4293,213 +4265,6 @@ CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE # -# Certificate "StartCom Certification Authority" -# -# Issuer: CN=StartCom Certification Authority,OU=Secure Digital Certificate Signing,O=StartCom Ltd.,C=IL -# Serial Number: 1 (0x1) -# Subject: CN=StartCom Certification Authority,OU=Secure Digital Certificate Signing,O=StartCom Ltd.,C=IL -# Not Valid Before: Sun Sep 17 19:46:36 2006 -# Not Valid After : Wed Sep 17 19:46:36 2036 -# Fingerprint (MD5): 22:4D:8F:8A:FC:F7:35:C2:BB:57:34:90:7B:8B:22:16 -# Fingerprint (SHA1): 3E:2B:F7:F2:03:1B:96:F3:8C:E6:C4:D8:A8:5D:3E:2D:58:47:6A:0F -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 "StartCom Certification Authority" -CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 -CKA_SUBJECT MULTILINE_OCTAL -\060\175\061\013\060\011\006\003\125\004\006\023\002\111\114\061 -\026\060\024\006\003\125\004\012\023\015\123\164\141\162\164\103 -\157\155\040\114\164\144\056\061\053\060\051\006\003\125\004\013 -\023\042\123\145\143\165\162\145\040\104\151\147\151\164\141\154 -\040\103\145\162\164\151\146\151\143\141\164\145\040\123\151\147 -\156\151\156\147\061\051\060\047\006\003\125\004\003\023\040\123 -\164\141\162\164\103\157\155\040\103\145\162\164\151\146\151\143 -\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171 -END -CKA_ID UTF8 "0" -CKA_ISSUER MULTILINE_OCTAL -\060\175\061\013\060\011\006\003\125\004\006\023\002\111\114\061 -\026\060\024\006\003\125\004\012\023\015\123\164\141\162\164\103 -\157\155\040\114\164\144\056\061\053\060\051\006\003\125\004\013 -\023\042\123\145\143\165\162\145\040\104\151\147\151\164\141\154 -\040\103\145\162\164\151\146\151\143\141\164\145\040\123\151\147 -\156\151\156\147\061\051\060\047\006\003\125\004\003\023\040\123 -\164\141\162\164\103\157\155\040\103\145\162\164\151\146\151\143 -\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\001\001 -END -CKA_VALUE MULTILINE_OCTAL -\060\202\007\311\060\202\005\261\240\003\002\001\002\002\001\001 -\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060 -\175\061\013\060\011\006\003\125\004\006\023\002\111\114\061\026 -\060\024\006\003\125\004\012\023\015\123\164\141\162\164\103\157 -\155\040\114\164\144\056\061\053\060\051\006\003\125\004\013\023 -\042\123\145\143\165\162\145\040\104\151\147\151\164\141\154\040 -\103\145\162\164\151\146\151\143\141\164\145\040\123\151\147\156 -\151\156\147\061\051\060\047\006\003\125\004\003\023\040\123\164 -\141\162\164\103\157\155\040\103\145\162\164\151\146\151\143\141 -\164\151\157\156\040\101\165\164\150\157\162\151\164\171\060\036 -\027\015\060\066\060\071\061\067\061\071\064\066\063\066\132\027 -\015\063\066\060\071\061\067\061\071\064\066\063\066\132\060\175 -\061\013\060\011\006\003\125\004\006\023\002\111\114\061\026\060 -\024\006\003\125\004\012\023\015\123\164\141\162\164\103\157\155 -\040\114\164\144\056\061\053\060\051\006\003\125\004\013\023\042 -\123\145\143\165\162\145\040\104\151\147\151\164\141\154\040\103 -\145\162\164\151\146\151\143\141\164\145\040\123\151\147\156\151 -\156\147\061\051\060\047\006\003\125\004\003\023\040\123\164\141 -\162\164\103\157\155\040\103\145\162\164\151\146\151\143\141\164 -\151\157\156\040\101\165\164\150\157\162\151\164\171\060\202\002 -\042\060\015\006\011\052\206\110\206\367\015\001\001\001\005\000 -\003\202\002\017\000\060\202\002\012\002\202\002\001\000\301\210 -\333\011\274\154\106\174\170\237\225\173\265\063\220\362\162\142 -\326\301\066\040\042\044\136\316\351\167\362\103\012\242\006\144 -\244\314\216\066\370\070\346\043\360\156\155\261\074\335\162\243 -\205\034\241\323\075\264\063\053\323\057\257\376\352\260\101\131 -\147\266\304\006\175\012\236\164\205\326\171\114\200\067\172\337 -\071\005\122\131\367\364\033\106\103\244\322\205\205\322\303\161 -\363\165\142\064\272\054\212\177\036\217\356\355\064\320\021\307 -\226\315\122\075\272\063\326\335\115\336\013\073\112\113\237\302 -\046\057\372\265\026\034\162\065\167\312\074\135\346\312\341\046 -\213\032\066\166\134\001\333\164\024\045\376\355\265\240\210\017 -\335\170\312\055\037\007\227\060\001\055\162\171\372\106\326\023 -\052\250\271\246\253\203\111\035\345\362\357\335\344\001\216\030 -\012\217\143\123\026\205\142\251\016\031\072\314\265\146\246\302 -\153\164\007\344\053\341\166\076\264\155\330\366\104\341\163\142 -\037\073\304\276\240\123\126\045\154\121\011\367\252\253\312\277 -\166\375\155\233\363\235\333\277\075\146\274\014\126\252\257\230 -\110\225\072\113\337\247\130\120\331\070\165\251\133\352\103\014 -\002\377\231\353\350\154\115\160\133\051\145\234\335\252\135\314 -\257\001\061\354\014\353\322\215\350\352\234\173\346\156\367\047 -\146\014\032\110\327\156\102\343\077\336\041\076\173\341\015\160 -\373\143\252\250\154\032\124\264\134\045\172\311\242\311\213\026 -\246\273\054\176\027\136\005\115\130\156\022\035\001\356\022\020 -\015\306\062\177\030\377\374\364\372\315\156\221\350\066\111\276 -\032\110\151\213\302\226\115\032\022\262\151\027\301\012\220\326 -\372\171\042\110\277\272\173\151\370\160\307\372\172\067\330\330 -\015\322\166\117\127\377\220\267\343\221\322\335\357\302\140\267 -\147\072\335\376\252\234\360\324\213\177\162\042\316\306\237\227 -\266\370\257\212\240\020\250\331\373\030\306\266\265\134\122\074 -\211\266\031\052\163\001\012\017\003\263\022\140\362\172\057\201 -\333\243\156\377\046\060\227\365\213\335\211\127\266\255\075\263 -\257\053\305\267\166\002\360\245\326\053\232\206\024\052\162\366 -\343\063\214\135\011\113\023\337\273\214\164\023\122\113\002\003 -\001\000\001\243\202\002\122\060\202\002\116\060\014\006\003\125 -\035\023\004\005\060\003\001\001\377\060\013\006\003\125\035\017 -\004\004\003\002\001\256\060\035\006\003\125\035\016\004\026\004 -\024\116\013\357\032\244\100\133\245\027\151\207\060\312\064\150 -\103\320\101\256\362\060\144\006\003\125\035\037\004\135\060\133 -\060\054\240\052\240\050\206\046\150\164\164\160\072\057\057\143 -\145\162\164\056\163\164\141\162\164\143\157\155\056\157\162\147 -\057\163\146\163\143\141\055\143\162\154\056\143\162\154\060\053 -\240\051\240\047\206\045\150\164\164\160\072\057\057\143\162\154 -\056\163\164\141\162\164\143\157\155\056\157\162\147\057\163\146 -\163\143\141\055\143\162\154\056\143\162\154\060\202\001\135\006 -\003\125\035\040\004\202\001\124\060\202\001\120\060\202\001\114 -\006\013\053\006\001\004\001\201\265\067\001\001\001\060\202\001 -\073\060\057\006\010\053\006\001\005\005\007\002\001\026\043\150 -\164\164\160\072\057\057\143\145\162\164\056\163\164\141\162\164 -\143\157\155\056\157\162\147\057\160\157\154\151\143\171\056\160 -\144\146\060\065\006\010\053\006\001\005\005\007\002\001\026\051 -\150\164\164\160\072\057\057\143\145\162\164\056\163\164\141\162 -\164\143\157\155\056\157\162\147\057\151\156\164\145\162\155\145 -\144\151\141\164\145\056\160\144\146\060\201\320\006\010\053\006 -\001\005\005\007\002\002\060\201\303\060\047\026\040\123\164\141 -\162\164\040\103\157\155\155\145\162\143\151\141\154\040\050\123 -\164\141\162\164\103\157\155\051\040\114\164\144\056\060\003\002 -\001\001\032\201\227\114\151\155\151\164\145\144\040\114\151\141 -\142\151\154\151\164\171\054\040\162\145\141\144\040\164\150\145 -\040\163\145\143\164\151\157\156\040\052\114\145\147\141\154\040 -\114\151\155\151\164\141\164\151\157\156\163\052\040\157\146\040 -\164\150\145\040\123\164\141\162\164\103\157\155\040\103\145\162 -\164\151\146\151\143\141\164\151\157\156\040\101\165\164\150\157 -\162\151\164\171\040\120\157\154\151\143\171\040\141\166\141\151 -\154\141\142\154\145\040\141\164\040\150\164\164\160\072\057\057 -\143\145\162\164\056\163\164\141\162\164\143\157\155\056\157\162 -\147\057\160\157\154\151\143\171\056\160\144\146\060\021\006\011 -\140\206\110\001\206\370\102\001\001\004\004\003\002\000\007\060 -\070\006\011\140\206\110\001\206\370\102\001\015\004\053\026\051 -\123\164\141\162\164\103\157\155\040\106\162\145\145\040\123\123 -\114\040\103\145\162\164\151\146\151\143\141\164\151\157\156\040 -\101\165\164\150\157\162\151\164\171\060\015\006\011\052\206\110 -\206\367\015\001\001\005\005\000\003\202\002\001\000\026\154\231 -\364\146\014\064\365\320\205\136\175\012\354\332\020\116\070\034 -\136\337\246\045\005\113\221\062\301\350\073\361\075\335\104\011 -\133\007\111\212\051\313\146\002\267\261\232\367\045\230\011\074 -\216\033\341\335\066\207\053\113\273\150\323\071\146\075\240\046 -\307\362\071\221\035\121\253\202\173\176\325\316\132\344\342\003 -\127\160\151\227\010\371\136\130\246\012\337\214\006\232\105\026 -\026\070\012\136\127\366\142\307\172\002\005\346\274\036\265\362 -\236\364\251\051\203\370\262\024\343\156\050\207\104\303\220\032 -\336\070\251\074\254\103\115\144\105\316\335\050\251\134\362\163 -\173\004\370\027\350\253\261\363\056\134\144\156\163\061\072\022 -\270\274\263\021\344\175\217\201\121\232\073\215\211\364\115\223 -\146\173\074\003\355\323\232\035\232\363\145\120\365\240\320\165 -\237\057\257\360\352\202\103\230\370\151\234\211\171\304\103\216 -\106\162\343\144\066\022\257\367\045\036\070\211\220\167\176\303 -\153\152\271\303\313\104\113\254\170\220\213\347\307\054\036\113 -\021\104\310\064\122\047\315\012\135\237\205\301\211\325\032\170 -\362\225\020\123\062\335\200\204\146\165\331\265\150\050\373\141 -\056\276\204\250\070\300\231\022\206\245\036\147\144\255\006\056 -\057\251\160\205\307\226\017\174\211\145\365\216\103\124\016\253 -\335\245\200\071\224\140\300\064\311\226\160\054\243\022\365\037 -\110\173\275\034\176\153\267\235\220\364\042\073\256\370\374\052 -\312\372\202\122\240\357\257\113\125\223\353\301\265\360\042\213 -\254\064\116\046\042\004\241\207\054\165\112\267\345\175\023\327 -\270\014\144\300\066\322\311\057\206\022\214\043\011\301\033\202 -\073\163\111\243\152\127\207\224\345\326\170\305\231\103\143\343 -\115\340\167\055\341\145\231\162\151\004\032\107\011\346\017\001 -\126\044\373\037\277\016\171\251\130\056\271\304\011\001\176\225 -\272\155\000\006\076\262\352\112\020\071\330\320\053\365\277\354 -\165\277\227\002\305\011\033\010\334\125\067\342\201\373\067\204 -\103\142\040\312\347\126\113\145\352\376\154\301\044\223\044\241 -\064\353\005\377\232\042\256\233\175\077\361\145\121\012\246\060 -\152\263\364\210\034\200\015\374\162\212\350\203\136 -END -CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE - -# Trust for Certificate "StartCom Certification Authority" -# Issuer: CN=StartCom Certification Authority,OU=Secure Digital Certificate Signing,O=StartCom Ltd.,C=IL -# Serial Number: 1 (0x1) -# Subject: CN=StartCom Certification Authority,OU=Secure Digital Certificate Signing,O=StartCom Ltd.,C=IL -# Not Valid Before: Sun Sep 17 19:46:36 2006 -# Not Valid After : Wed Sep 17 19:46:36 2036 -# Fingerprint (MD5): 22:4D:8F:8A:FC:F7:35:C2:BB:57:34:90:7B:8B:22:16 -# Fingerprint (SHA1): 3E:2B:F7:F2:03:1B:96:F3:8C:E6:C4:D8:A8:5D:3E:2D:58:47:6A:0F -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 "StartCom Certification Authority" -CKA_CERT_SHA1_HASH MULTILINE_OCTAL -\076\053\367\362\003\033\226\363\214\346\304\330\250\135\076\055 -\130\107\152\017 -END -CKA_CERT_MD5_HASH MULTILINE_OCTAL -\042\115\217\212\374\367\065\302\273\127\064\220\173\213\042\026 -END -CKA_ISSUER MULTILINE_OCTAL -\060\175\061\013\060\011\006\003\125\004\006\023\002\111\114\061 -\026\060\024\006\003\125\004\012\023\015\123\164\141\162\164\103 -\157\155\040\114\164\144\056\061\053\060\051\006\003\125\004\013 -\023\042\123\145\143\165\162\145\040\104\151\147\151\164\141\154 -\040\103\145\162\164\151\146\151\143\141\164\145\040\123\151\147 -\156\151\156\147\061\051\060\047\006\003\125\004\003\023\040\123 -\164\141\162\164\103\157\155\040\103\145\162\164\151\146\151\143 -\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\001\001 -END -CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR -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 "Taiwan GRCA" # # Issuer: O=Government Root Certification Authority,C=TW @@ -5345,149 +5110,6 @@ CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE # -# Certificate "DST ACES CA X6" -# -# Issuer: CN=DST ACES CA X6,OU=DST ACES,O=Digital Signature Trust,C=US -# Serial Number:0d:5e:99:0a:d6:9d:b7:78:ec:d8:07:56:3b:86:15:d9 -# Subject: CN=DST ACES CA X6,OU=DST ACES,O=Digital Signature Trust,C=US -# Not Valid Before: Thu Nov 20 21:19:58 2003 -# Not Valid After : Mon Nov 20 21:19:58 2017 -# Fingerprint (MD5): 21:D8:4C:82:2B:99:09:33:A2:EB:14:24:8D:8E:5F:E8 -# Fingerprint (SHA1): 40:54:DA:6F:1C:3F:40:74:AC:ED:0F:EC:CD:DB:79:D1:53:FB:90:1D -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 "DST ACES CA X6" -CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 -CKA_SUBJECT MULTILINE_OCTAL -\060\133\061\013\060\011\006\003\125\004\006\023\002\125\123\061 -\040\060\036\006\003\125\004\012\023\027\104\151\147\151\164\141 -\154\040\123\151\147\156\141\164\165\162\145\040\124\162\165\163 -\164\061\021\060\017\006\003\125\004\013\023\010\104\123\124\040 -\101\103\105\123\061\027\060\025\006\003\125\004\003\023\016\104 -\123\124\040\101\103\105\123\040\103\101\040\130\066 -END -CKA_ID UTF8 "0" -CKA_ISSUER MULTILINE_OCTAL -\060\133\061\013\060\011\006\003\125\004\006\023\002\125\123\061 -\040\060\036\006\003\125\004\012\023\027\104\151\147\151\164\141 -\154\040\123\151\147\156\141\164\165\162\145\040\124\162\165\163 -\164\061\021\060\017\006\003\125\004\013\023\010\104\123\124\040 -\101\103\105\123\061\027\060\025\006\003\125\004\003\023\016\104 -\123\124\040\101\103\105\123\040\103\101\040\130\066 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\020\015\136\231\012\326\235\267\170\354\330\007\126\073\206 -\025\331 -END -CKA_VALUE MULTILINE_OCTAL -\060\202\004\011\060\202\002\361\240\003\002\001\002\002\020\015 -\136\231\012\326\235\267\170\354\330\007\126\073\206\025\331\060 -\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060\133 -\061\013\060\011\006\003\125\004\006\023\002\125\123\061\040\060 -\036\006\003\125\004\012\023\027\104\151\147\151\164\141\154\040 -\123\151\147\156\141\164\165\162\145\040\124\162\165\163\164\061 -\021\060\017\006\003\125\004\013\023\010\104\123\124\040\101\103 -\105\123\061\027\060\025\006\003\125\004\003\023\016\104\123\124 -\040\101\103\105\123\040\103\101\040\130\066\060\036\027\015\060 -\063\061\061\062\060\062\061\061\071\065\070\132\027\015\061\067 -\061\061\062\060\062\061\061\071\065\070\132\060\133\061\013\060 -\011\006\003\125\004\006\023\002\125\123\061\040\060\036\006\003 -\125\004\012\023\027\104\151\147\151\164\141\154\040\123\151\147 -\156\141\164\165\162\145\040\124\162\165\163\164\061\021\060\017 -\006\003\125\004\013\023\010\104\123\124\040\101\103\105\123\061 -\027\060\025\006\003\125\004\003\023\016\104\123\124\040\101\103 -\105\123\040\103\101\040\130\066\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\271\075\365\054\311\224\334 -\165\212\225\135\143\350\204\167\166\146\271\131\221\134\106\335 -\222\076\237\371\016\003\264\075\141\222\275\043\046\265\143\356 -\222\322\236\326\074\310\015\220\137\144\201\261\250\010\015\114 -\330\371\323\005\050\122\264\001\045\305\225\034\014\176\076\020 -\204\165\317\301\031\221\143\317\350\250\221\210\271\103\122\273 -\200\261\125\211\213\061\372\320\267\166\276\101\075\060\232\244 -\042\045\027\163\350\036\342\323\254\052\275\133\070\041\325\052 -\113\327\125\175\343\072\125\275\327\155\153\002\127\153\346\107 -\174\010\310\202\272\336\247\207\075\241\155\270\060\126\302\263 -\002\201\137\055\365\342\232\060\030\050\270\146\323\313\001\226 -\157\352\212\105\125\326\340\235\377\147\053\027\002\246\116\032 -\152\021\013\176\267\173\347\230\326\214\166\157\301\073\333\120 -\223\176\345\320\216\037\067\270\275\272\306\237\154\351\174\063 -\362\062\074\046\107\372\047\044\002\311\176\035\133\210\102\023 -\152\065\174\175\065\351\056\146\221\162\223\325\062\046\304\164 -\365\123\243\263\135\232\366\011\313\002\003\001\000\001\243\201 -\310\060\201\305\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\306\060\037\006\003\125\035\021\004\030\060\026 -\201\024\160\153\151\055\157\160\163\100\164\162\165\163\164\144 -\163\164\056\143\157\155\060\142\006\003\125\035\040\004\133\060 -\131\060\127\006\012\140\206\110\001\145\003\002\001\001\001\060 -\111\060\107\006\010\053\006\001\005\005\007\002\001\026\073\150 -\164\164\160\072\057\057\167\167\167\056\164\162\165\163\164\144 -\163\164\056\143\157\155\057\143\145\162\164\151\146\151\143\141 -\164\145\163\057\160\157\154\151\143\171\057\101\103\105\123\055 -\151\156\144\145\170\056\150\164\155\154\060\035\006\003\125\035 -\016\004\026\004\024\011\162\006\116\030\103\017\345\326\314\303 -\152\213\061\173\170\217\250\203\270\060\015\006\011\052\206\110 -\206\367\015\001\001\005\005\000\003\202\001\001\000\243\330\216 -\326\262\333\316\005\347\062\315\001\323\004\003\345\166\344\126 -\053\234\231\220\350\010\060\154\337\175\075\356\345\277\265\044 -\100\204\111\341\321\050\256\304\302\072\123\060\210\361\365\167 -\156\121\312\372\377\231\257\044\137\033\240\375\362\254\204\312 -\337\251\360\137\004\056\255\026\277\041\227\020\201\075\343\377 -\207\215\062\334\224\345\107\212\136\152\023\311\224\225\075\322 -\356\310\064\225\320\200\324\255\062\010\200\124\074\340\275\122 -\123\327\122\174\262\151\077\177\172\317\152\164\312\372\004\052 -\234\114\132\006\245\351\040\255\105\146\017\151\361\335\277\351 -\343\062\213\372\340\301\206\115\162\074\056\330\223\170\012\052 -\370\330\322\047\075\031\211\137\132\173\212\073\314\014\332\121 -\256\307\013\367\053\260\067\005\354\274\127\043\342\070\322\233 -\150\363\126\022\210\117\102\174\270\061\304\265\333\344\310\041 -\064\351\110\021\065\356\372\307\222\127\305\237\064\344\307\366 -\367\016\013\114\234\150\170\173\161\061\307\353\036\340\147\101 -\363\267\240\247\315\345\172\063\066\152\372\232\053 -END -CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE - -# Trust for Certificate "DST ACES CA X6" -# Issuer: CN=DST ACES CA X6,OU=DST ACES,O=Digital Signature Trust,C=US -# Serial Number:0d:5e:99:0a:d6:9d:b7:78:ec:d8:07:56:3b:86:15:d9 -# Subject: CN=DST ACES CA X6,OU=DST ACES,O=Digital Signature Trust,C=US -# Not Valid Before: Thu Nov 20 21:19:58 2003 -# Not Valid After : Mon Nov 20 21:19:58 2017 -# Fingerprint (MD5): 21:D8:4C:82:2B:99:09:33:A2:EB:14:24:8D:8E:5F:E8 -# Fingerprint (SHA1): 40:54:DA:6F:1C:3F:40:74:AC:ED:0F:EC:CD:DB:79:D1:53:FB:90:1D -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 "DST ACES CA X6" -CKA_CERT_SHA1_HASH MULTILINE_OCTAL -\100\124\332\157\034\077\100\164\254\355\017\354\315\333\171\321 -\123\373\220\035 -END -CKA_CERT_MD5_HASH MULTILINE_OCTAL -\041\330\114\202\053\231\011\063\242\353\024\044\215\216\137\350 -END -CKA_ISSUER MULTILINE_OCTAL -\060\133\061\013\060\011\006\003\125\004\006\023\002\125\123\061 -\040\060\036\006\003\125\004\012\023\027\104\151\147\151\164\141 -\154\040\123\151\147\156\141\164\165\162\145\040\124\162\165\163 -\164\061\021\060\017\006\003\125\004\013\023\010\104\123\124\040 -\101\103\105\123\061\027\060\025\006\003\125\004\003\023\016\104 -\123\124\040\101\103\105\123\040\103\101\040\130\066 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\020\015\136\231\012\326\235\267\170\354\330\007\126\073\206 -\025\331 -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 "SwissSign Platinum CA - G2" # # Issuer: CN=SwissSign Platinum CA - G2,O=SwissSign AG,C=CH @@ -7152,311 +6774,6 @@ CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE # -# Certificate "MD5 Collisions Forged Rogue CA 25c3" -# -# Issuer: CN=Equifax Secure Global eBusiness CA-1,O=Equifax Secure Inc.,C=US -# Serial Number: 66 (0x42) -# Subject: CN=MD5 Collisions Inc. (http://www.phreedom.org/md5) -# Not Valid Before: Sat Jul 31 00:00:01 2004 -# Not Valid After : Thu Sep 02 00:00:01 2004 -# Fingerprint (MD5): 16:7A:13:15:B9:17:39:A3:F1:05:6A:E6:3E:D9:3A:38 -# Fingerprint (SHA1): 64:23:13:7E:5C:53:D6:4A:A6:64:85:ED:36:54:F5:AB:05:5A:8B:8A -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 "MD5 Collisions Forged Rogue CA 25c3" -CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 -CKA_SUBJECT MULTILINE_OCTAL -\060\074\061\072\060\070\006\003\125\004\003\023\061\115\104\065 -\040\103\157\154\154\151\163\151\157\156\163\040\111\156\143\056 -\040\050\150\164\164\160\072\057\057\167\167\167\056\160\150\162 -\145\145\144\157\155\056\157\162\147\057\155\144\065\051 -END -CKA_ID UTF8 "0" -CKA_ISSUER MULTILINE_OCTAL -\060\132\061\013\060\011\006\003\125\004\006\023\002\125\123\061 -\034\060\032\006\003\125\004\012\023\023\105\161\165\151\146\141 -\170\040\123\145\143\165\162\145\040\111\156\143\056\061\055\060 -\053\006\003\125\004\003\023\044\105\161\165\151\146\141\170\040 -\123\145\143\165\162\145\040\107\154\157\142\141\154\040\145\102 -\165\163\151\156\145\163\163\040\103\101\055\061 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\001\102 -END -CKA_VALUE MULTILINE_OCTAL -\060\202\004\062\060\202\003\233\240\003\002\001\002\002\001\102 -\060\015\006\011\052\206\110\206\367\015\001\001\004\005\000\060 -\132\061\013\060\011\006\003\125\004\006\023\002\125\123\061\034 -\060\032\006\003\125\004\012\023\023\105\161\165\151\146\141\170 -\040\123\145\143\165\162\145\040\111\156\143\056\061\055\060\053 -\006\003\125\004\003\023\044\105\161\165\151\146\141\170\040\123 -\145\143\165\162\145\040\107\154\157\142\141\154\040\145\102\165 -\163\151\156\145\163\163\040\103\101\055\061\060\036\027\015\060 -\064\060\067\063\061\060\060\060\060\060\061\132\027\015\060\064 -\060\071\060\062\060\060\060\060\060\061\132\060\074\061\072\060 -\070\006\003\125\004\003\023\061\115\104\065\040\103\157\154\154 -\151\163\151\157\156\163\040\111\156\143\056\040\050\150\164\164 -\160\072\057\057\167\167\167\056\160\150\162\145\145\144\157\155 -\056\157\162\147\057\155\144\065\051\060\201\237\060\015\006\011 -\052\206\110\206\367\015\001\001\001\005\000\003\201\215\000\060 -\201\211\002\201\201\000\272\246\131\311\054\050\326\052\260\370 -\355\237\106\244\244\067\356\016\031\150\131\321\263\003\231\121 -\326\026\232\136\067\153\025\340\016\113\365\204\144\370\243\333 -\101\157\065\325\233\025\037\333\304\070\122\160\201\227\136\217 -\240\265\367\176\071\360\062\254\036\255\104\322\263\372\110\303 -\316\221\233\354\364\234\174\341\132\365\310\067\153\232\203\336 -\347\312\040\227\061\102\163\025\221\150\364\210\257\371\050\050 -\305\351\017\163\260\027\113\023\114\231\165\320\104\346\176\010 -\154\032\362\117\033\101\002\003\001\000\001\243\202\002\044\060 -\202\002\040\060\013\006\003\125\035\017\004\004\003\002\001\306 -\060\017\006\003\125\035\023\001\001\377\004\005\060\003\001\001 -\377\060\035\006\003\125\035\016\004\026\004\024\247\004\140\037 -\253\162\103\010\305\177\010\220\125\126\034\326\316\346\070\353 -\060\037\006\003\125\035\043\004\030\060\026\200\024\276\250\240 -\164\162\120\153\104\267\311\043\330\373\250\377\263\127\153\150 -\154\060\202\001\276\006\011\140\206\110\001\206\370\102\001\015 -\004\202\001\257\026\202\001\253\063\000\000\000\047\136\071\340 -\211\141\017\116\243\305\105\013\066\273\001\321\123\252\303\010 -\217\157\370\117\076\207\207\104\021\334\140\340\337\222\125\371 -\270\163\033\124\223\305\237\320\106\304\140\266\065\142\315\271 -\257\034\250\151\032\311\133\074\226\067\300\355\147\357\273\376 -\300\213\234\120\057\051\275\203\042\236\216\010\372\254\023\160 -\242\130\177\142\142\212\021\367\211\366\337\266\147\131\163\026 -\373\143\026\212\264\221\070\316\056\365\266\276\114\244\224\111 -\344\145\021\012\102\025\311\301\060\342\151\325\105\175\245\046 -\273\271\141\354\142\144\360\071\341\347\274\150\330\120\121\236 -\035\140\323\321\243\247\012\370\003\040\241\160\001\027\221\066 -\117\002\160\061\206\203\335\367\017\330\007\035\021\263\023\004 -\245\334\360\256\120\261\050\016\143\151\052\014\202\157\217\107 -\063\337\154\242\006\222\361\117\105\276\331\060\066\243\053\214 -\326\167\256\065\143\177\116\114\232\223\110\066\331\237\002\003 -\001\000\001\243\201\275\060\201\272\060\016\006\003\125\035\017 -\001\001\377\004\004\003\002\004\360\060\035\006\003\125\035\016 -\004\026\004\024\315\246\203\372\245\140\067\367\226\067\027\051 -\336\101\170\361\207\211\125\347\060\073\006\003\125\035\037\004 -\064\060\062\060\060\240\056\240\054\206\052\150\164\164\160\072 -\057\057\143\162\154\056\147\145\157\164\162\165\163\164\056\143 -\157\155\057\143\162\154\163\057\147\154\157\142\141\154\143\141 -\061\056\143\162\154\060\037\006\003\125\035\043\004\030\060\026 -\200\024\276\250\240\164\162\120\153\104\267\311\043\330\373\250 -\377\263\127\153\150\154\060\035\006\003\125\035\045\004\026\060 -\024\006\010\053\006\001\005\005\007\003\001\006\010\053\006\001 -\005\005\007\003\002\060\014\006\003\125\035\023\001\001\377\004 -\002\060\000\060\015\006\011\052\206\110\206\367\015\001\001\004 -\005\000\003\201\201\000\247\041\002\215\321\016\242\200\167\045 -\375\103\140\025\217\354\357\220\107\324\204\102\025\046\021\034 -\315\302\074\020\051\251\266\337\253\127\165\221\332\345\053\263 -\220\105\034\060\143\126\077\212\331\120\372\355\130\154\300\145 -\254\146\127\336\034\306\166\073\365\000\016\216\105\316\177\114 -\220\354\053\306\315\263\264\217\142\320\376\267\305\046\162\104 -\355\366\230\133\256\313\321\225\365\332\010\276\150\106\261\165 -\310\354\035\217\036\172\224\361\252\123\170\242\105\256\124\352 -\321\236\164\310\166\147 -END - -# Trust for Certificate "MD5 Collisions Forged Rogue CA 25c3" -# Issuer: CN=Equifax Secure Global eBusiness CA-1,O=Equifax Secure Inc.,C=US -# Serial Number: 66 (0x42) -# Subject: CN=MD5 Collisions Inc. (http://www.phreedom.org/md5) -# Not Valid Before: Sat Jul 31 00:00:01 2004 -# Not Valid After : Thu Sep 02 00:00:01 2004 -# Fingerprint (MD5): 16:7A:13:15:B9:17:39:A3:F1:05:6A:E6:3E:D9:3A:38 -# Fingerprint (SHA1): 64:23:13:7E:5C:53:D6:4A:A6:64:85:ED:36:54:F5:AB:05:5A:8B:8A -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 "MD5 Collisions Forged Rogue CA 25c3" -CKA_CERT_SHA1_HASH MULTILINE_OCTAL -\144\043\023\176\134\123\326\112\246\144\205\355\066\124\365\253 -\005\132\213\212 -END -CKA_CERT_MD5_HASH MULTILINE_OCTAL -\026\172\023\025\271\027\071\243\361\005\152\346\076\331\072\070 -END -CKA_ISSUER MULTILINE_OCTAL -\060\132\061\013\060\011\006\003\125\004\006\023\002\125\123\061 -\034\060\032\006\003\125\004\012\023\023\105\161\165\151\146\141 -\170\040\123\145\143\165\162\145\040\111\156\143\056\061\055\060 -\053\006\003\125\004\003\023\044\105\161\165\151\146\141\170\040 -\123\145\143\165\162\145\040\107\154\157\142\141\154\040\145\102 -\165\163\151\156\145\163\163\040\103\101\055\061 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\001\102 -END -CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED -CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED -CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED -CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE - -# Distrust "Distrusted AC DG Tresor SSL" -# Issuer: CN=AC DGTPE Signature Authentification,O=DGTPE,C=FR -# Serial Number: 204199 (0x31da7) -# Subject: CN=AC DG Tr..sor SSL,O=DG Tr..sor,C=FR -# Not Valid Before: Thu Jul 18 10:05:28 2013 -# Not Valid After : Fri Jul 18 10:05:28 2014 -# Fingerprint (MD5): 3A:EA:9E:FC:00:0C:E2:06:6C:E0:AC:39:C1:31:DE:C8 -# Fingerprint (SHA1): 5C:E3:39:46:5F:41:A1:E4:23:14:9F:65:54:40:95:40:4D:E6:EB:E2 -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 "Distrusted AC DG Tresor SSL" -CKA_ISSUER MULTILINE_OCTAL -\060\113\061\013\060\011\006\003\125\004\006\023\002\106\122\061 -\016\060\014\006\003\125\004\012\023\005\104\107\124\120\105\061 -\054\060\052\006\003\125\004\003\023\043\101\103\040\104\107\124 -\120\105\040\123\151\147\156\141\164\165\162\145\040\101\165\164 -\150\145\156\164\151\146\151\143\141\164\151\157\156 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\003\003\035\247 -END -CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED -CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED -CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED -CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE - -# -# Certificate "Security Communication EV RootCA1" -# -# Issuer: OU=Security Communication EV RootCA1,O="SECOM Trust Systems CO.,LTD.",C=JP -# Serial Number: 0 (0x0) -# Subject: OU=Security Communication EV RootCA1,O="SECOM Trust Systems CO.,LTD.",C=JP -# Not Valid Before: Wed Jun 06 02:12:32 2007 -# Not Valid After : Sat Jun 06 02:12:32 2037 -# Fingerprint (MD5): 22:2D:A6:01:EA:7C:0A:F7:F0:6C:56:43:3F:77:76:D3 -# Fingerprint (SHA1): FE:B8:C4:32:DC:F9:76:9A:CE:AE:3D:D8:90:8F:FD:28:86:65:64:7D -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 "Security Communication EV RootCA1" -CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 -CKA_SUBJECT MULTILINE_OCTAL -\060\140\061\013\060\011\006\003\125\004\006\023\002\112\120\061 -\045\060\043\006\003\125\004\012\023\034\123\105\103\117\115\040 -\124\162\165\163\164\040\123\171\163\164\145\155\163\040\103\117 -\056\054\114\124\104\056\061\052\060\050\006\003\125\004\013\023 -\041\123\145\143\165\162\151\164\171\040\103\157\155\155\165\156 -\151\143\141\164\151\157\156\040\105\126\040\122\157\157\164\103 -\101\061 -END -CKA_ID UTF8 "0" -CKA_ISSUER MULTILINE_OCTAL -\060\140\061\013\060\011\006\003\125\004\006\023\002\112\120\061 -\045\060\043\006\003\125\004\012\023\034\123\105\103\117\115\040 -\124\162\165\163\164\040\123\171\163\164\145\155\163\040\103\117 -\056\054\114\124\104\056\061\052\060\050\006\003\125\004\013\023 -\041\123\145\143\165\162\151\164\171\040\103\157\155\155\165\156 -\151\143\141\164\151\157\156\040\105\126\040\122\157\157\164\103 -\101\061 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\001\000 -END -CKA_VALUE MULTILINE_OCTAL -\060\202\003\175\060\202\002\145\240\003\002\001\002\002\001\000 -\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060 -\140\061\013\060\011\006\003\125\004\006\023\002\112\120\061\045 -\060\043\006\003\125\004\012\023\034\123\105\103\117\115\040\124 -\162\165\163\164\040\123\171\163\164\145\155\163\040\103\117\056 -\054\114\124\104\056\061\052\060\050\006\003\125\004\013\023\041 -\123\145\143\165\162\151\164\171\040\103\157\155\155\165\156\151 -\143\141\164\151\157\156\040\105\126\040\122\157\157\164\103\101 -\061\060\036\027\015\060\067\060\066\060\066\060\062\061\062\063 -\062\132\027\015\063\067\060\066\060\066\060\062\061\062\063\062 -\132\060\140\061\013\060\011\006\003\125\004\006\023\002\112\120 -\061\045\060\043\006\003\125\004\012\023\034\123\105\103\117\115 -\040\124\162\165\163\164\040\123\171\163\164\145\155\163\040\103 -\117\056\054\114\124\104\056\061\052\060\050\006\003\125\004\013 -\023\041\123\145\143\165\162\151\164\171\040\103\157\155\155\165 -\156\151\143\141\164\151\157\156\040\105\126\040\122\157\157\164 -\103\101\061\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\274\177\354\127\233\044\340\376\234\272\102\171 -\251\210\212\372\200\340\365\007\051\103\352\216\012\064\066\215 -\034\372\247\265\071\170\377\227\165\367\057\344\252\153\004\204 -\104\312\246\342\150\216\375\125\120\142\017\244\161\016\316\007 -\070\055\102\205\120\255\074\226\157\213\325\242\016\317\336\111 -\211\075\326\144\056\070\345\036\154\265\127\212\236\357\110\016 -\315\172\151\026\207\104\265\220\344\006\235\256\241\004\227\130 -\171\357\040\112\202\153\214\042\277\354\037\017\351\204\161\355 -\361\016\344\270\030\023\314\126\066\135\321\232\036\121\153\071 -\156\140\166\210\064\013\363\263\321\260\235\312\141\342\144\035 -\301\106\007\270\143\335\036\063\145\263\216\011\125\122\075\265 -\275\377\007\353\255\141\125\030\054\251\151\230\112\252\100\305 -\063\024\145\164\000\371\221\336\257\003\110\305\100\124\334\017 -\204\220\150\040\305\222\226\334\056\345\002\105\252\300\137\124 -\370\155\352\111\317\135\154\113\257\357\232\302\126\134\306\065 -\126\102\152\060\137\302\253\366\342\075\077\263\311\021\217\061 -\114\327\237\111\002\003\001\000\001\243\102\060\100\060\035\006 -\003\125\035\016\004\026\004\024\065\112\365\115\257\077\327\202 -\070\254\253\161\145\027\165\214\235\125\223\346\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\005\005\000\003\202\001\001 -\000\250\207\351\354\370\100\147\135\303\301\146\307\100\113\227 -\374\207\023\220\132\304\357\240\312\137\213\267\247\267\361\326 -\265\144\267\212\263\270\033\314\332\373\254\146\210\101\316\350 -\374\344\333\036\210\246\355\047\120\033\002\060\044\106\171\376 -\004\207\160\227\100\163\321\300\301\127\031\232\151\245\047\231 -\253\235\142\204\366\121\301\054\311\043\025\330\050\267\253\045 -\023\265\106\341\206\002\377\046\214\304\210\222\035\126\376\031 -\147\362\125\344\200\243\153\234\253\167\341\121\161\015\040\333 -\020\232\333\275\166\171\007\167\231\050\255\232\136\332\261\117 -\104\054\065\216\245\226\307\375\203\360\130\306\171\326\230\174 -\250\215\376\206\076\007\026\222\341\173\347\035\354\063\166\176 -\102\056\112\205\371\221\211\150\204\003\201\245\233\232\276\343 -\067\305\124\253\126\073\030\055\101\244\014\370\102\333\231\240 -\340\162\157\273\135\341\026\117\123\012\144\371\116\364\277\116 -\124\275\170\154\210\352\277\234\023\044\302\160\151\242\177\017 -\310\074\255\010\311\260\230\100\243\052\347\210\203\355\167\217 -\164 -END -CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE - -# Trust for Certificate "Security Communication EV RootCA1" -# Issuer: OU=Security Communication EV RootCA1,O="SECOM Trust Systems CO.,LTD.",C=JP -# Serial Number: 0 (0x0) -# Subject: OU=Security Communication EV RootCA1,O="SECOM Trust Systems CO.,LTD.",C=JP -# Not Valid Before: Wed Jun 06 02:12:32 2007 -# Not Valid After : Sat Jun 06 02:12:32 2037 -# Fingerprint (MD5): 22:2D:A6:01:EA:7C:0A:F7:F0:6C:56:43:3F:77:76:D3 -# Fingerprint (SHA1): FE:B8:C4:32:DC:F9:76:9A:CE:AE:3D:D8:90:8F:FD:28:86:65:64:7D -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 "Security Communication EV RootCA1" -CKA_CERT_SHA1_HASH MULTILINE_OCTAL -\376\270\304\062\334\371\166\232\316\256\075\330\220\217\375\050 -\206\145\144\175 -END -CKA_CERT_MD5_HASH MULTILINE_OCTAL -\042\055\246\001\352\174\012\367\360\154\126\103\077\167\166\323 -END -CKA_ISSUER MULTILINE_OCTAL -\060\140\061\013\060\011\006\003\125\004\006\023\002\112\120\061 -\045\060\043\006\003\125\004\012\023\034\123\105\103\117\115\040 -\124\162\165\163\164\040\123\171\163\164\145\155\163\040\103\117 -\056\054\114\124\104\056\061\052\060\050\006\003\125\004\013\023 -\041\123\145\143\165\162\151\164\171\040\103\157\155\155\165\156 -\151\143\141\164\151\157\156\040\105\126\040\122\157\157\164\103 -\101\061 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\001\000 -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 "OISTE WISeKey Global Root GA CA" # # Issuer: CN=OISTE WISeKey Global Root GA CA,OU=OISTE Foundation Endorsed,OU=Copyright (c) 2005,O=WISeKey,C=CH @@ -8651,203 +7968,6 @@ CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE # -# Certificate "TUBITAK UEKAE Kok Sertifika Hizmet Saglayicisi - Surum 3" -# -# Issuer: CN=T..B..TAK UEKAE K..k Sertifika Hizmet Sa..lay..c..s.. - S..r..m ...,OU=Kamu Sertifikasyon Merkezi,OU=Ulusal Elektronik ve Kriptoloji Ara..t..rma Enstit..s.. - UEKAE,O=T..rkiye Bilimsel ve Teknolojik Ara..t..rma Kurumu - T..B..TAK,L=Gebze - Kocaeli,C=TR -# Serial Number: 17 (0x11) -# Subject: CN=T..B..TAK UEKAE K..k Sertifika Hizmet Sa..lay..c..s.. - S..r..m ...,OU=Kamu Sertifikasyon Merkezi,OU=Ulusal Elektronik ve Kriptoloji Ara..t..rma Enstit..s.. - UEKAE,O=T..rkiye Bilimsel ve Teknolojik Ara..t..rma Kurumu - T..B..TAK,L=Gebze - Kocaeli,C=TR -# Not Valid Before: Fri Aug 24 11:37:07 2007 -# Not Valid After : Mon Aug 21 11:37:07 2017 -# Fingerprint (MD5): ED:41:F5:8C:50:C5:2B:9C:73:E6:EE:6C:EB:C2:A8:26 -# Fingerprint (SHA1): 1B:4B:39:61:26:27:6B:64:91:A2:68:6D:D7:02:43:21:2D:1F:1D:96 -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\xc3\x9c\x42\xC4\xB0TAK UEKAE K\xC3\xB6k Sertifika Hizmet Sa\xC4\x9Flay\xc4\xb1\x63\xc4\xb1s\xc4\xb1 - S\xC3\xBCr\xC3\xBCm 3" -CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 -CKA_SUBJECT MULTILINE_OCTAL -\060\202\001\053\061\013\060\011\006\003\125\004\006\023\002\124 -\122\061\030\060\026\006\003\125\004\007\014\017\107\145\142\172 -\145\040\055\040\113\157\143\141\145\154\151\061\107\060\105\006 -\003\125\004\012\014\076\124\303\274\162\153\151\171\145\040\102 -\151\154\151\155\163\145\154\040\166\145\040\124\145\153\156\157 -\154\157\152\151\153\040\101\162\141\305\237\164\304\261\162\155 -\141\040\113\165\162\165\155\165\040\055\040\124\303\234\102\304 -\260\124\101\113\061\110\060\106\006\003\125\004\013\014\077\125 -\154\165\163\141\154\040\105\154\145\153\164\162\157\156\151\153 -\040\166\145\040\113\162\151\160\164\157\154\157\152\151\040\101 -\162\141\305\237\164\304\261\162\155\141\040\105\156\163\164\151 -\164\303\274\163\303\274\040\055\040\125\105\113\101\105\061\043 -\060\041\006\003\125\004\013\014\032\113\141\155\165\040\123\145 -\162\164\151\146\151\153\141\163\171\157\156\040\115\145\162\153 -\145\172\151\061\112\060\110\006\003\125\004\003\014\101\124\303 -\234\102\304\260\124\101\113\040\125\105\113\101\105\040\113\303 -\266\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\055\040\123\303\274\162\303\274\155\040\063 -END -CKA_ID UTF8 "0" -CKA_ISSUER MULTILINE_OCTAL -\060\202\001\053\061\013\060\011\006\003\125\004\006\023\002\124 -\122\061\030\060\026\006\003\125\004\007\014\017\107\145\142\172 -\145\040\055\040\113\157\143\141\145\154\151\061\107\060\105\006 -\003\125\004\012\014\076\124\303\274\162\153\151\171\145\040\102 -\151\154\151\155\163\145\154\040\166\145\040\124\145\153\156\157 -\154\157\152\151\153\040\101\162\141\305\237\164\304\261\162\155 -\141\040\113\165\162\165\155\165\040\055\040\124\303\234\102\304 -\260\124\101\113\061\110\060\106\006\003\125\004\013\014\077\125 -\154\165\163\141\154\040\105\154\145\153\164\162\157\156\151\153 -\040\166\145\040\113\162\151\160\164\157\154\157\152\151\040\101 -\162\141\305\237\164\304\261\162\155\141\040\105\156\163\164\151 -\164\303\274\163\303\274\040\055\040\125\105\113\101\105\061\043 -\060\041\006\003\125\004\013\014\032\113\141\155\165\040\123\145 -\162\164\151\146\151\153\141\163\171\157\156\040\115\145\162\153 -\145\172\151\061\112\060\110\006\003\125\004\003\014\101\124\303 -\234\102\304\260\124\101\113\040\125\105\113\101\105\040\113\303 -\266\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\055\040\123\303\274\162\303\274\155\040\063 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\001\021 -END -CKA_VALUE MULTILINE_OCTAL -\060\202\005\027\060\202\003\377\240\003\002\001\002\002\001\021 -\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060 -\202\001\053\061\013\060\011\006\003\125\004\006\023\002\124\122 -\061\030\060\026\006\003\125\004\007\014\017\107\145\142\172\145 -\040\055\040\113\157\143\141\145\154\151\061\107\060\105\006\003 -\125\004\012\014\076\124\303\274\162\153\151\171\145\040\102\151 -\154\151\155\163\145\154\040\166\145\040\124\145\153\156\157\154 -\157\152\151\153\040\101\162\141\305\237\164\304\261\162\155\141 -\040\113\165\162\165\155\165\040\055\040\124\303\234\102\304\260 -\124\101\113\061\110\060\106\006\003\125\004\013\014\077\125\154 -\165\163\141\154\040\105\154\145\153\164\162\157\156\151\153\040 -\166\145\040\113\162\151\160\164\157\154\157\152\151\040\101\162 -\141\305\237\164\304\261\162\155\141\040\105\156\163\164\151\164 -\303\274\163\303\274\040\055\040\125\105\113\101\105\061\043\060 -\041\006\003\125\004\013\014\032\113\141\155\165\040\123\145\162 -\164\151\146\151\153\141\163\171\157\156\040\115\145\162\153\145 -\172\151\061\112\060\110\006\003\125\004\003\014\101\124\303\234 -\102\304\260\124\101\113\040\125\105\113\101\105\040\113\303\266 -\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\055\040\123\303\274\162\303\274\155\040\063\060\036 -\027\015\060\067\060\070\062\064\061\061\063\067\060\067\132\027 -\015\061\067\060\070\062\061\061\061\063\067\060\067\132\060\202 -\001\053\061\013\060\011\006\003\125\004\006\023\002\124\122\061 -\030\060\026\006\003\125\004\007\014\017\107\145\142\172\145\040 -\055\040\113\157\143\141\145\154\151\061\107\060\105\006\003\125 -\004\012\014\076\124\303\274\162\153\151\171\145\040\102\151\154 -\151\155\163\145\154\040\166\145\040\124\145\153\156\157\154\157 -\152\151\153\040\101\162\141\305\237\164\304\261\162\155\141\040 -\113\165\162\165\155\165\040\055\040\124\303\234\102\304\260\124 -\101\113\061\110\060\106\006\003\125\004\013\014\077\125\154\165 -\163\141\154\040\105\154\145\153\164\162\157\156\151\153\040\166 -\145\040\113\162\151\160\164\157\154\157\152\151\040\101\162\141 -\305\237\164\304\261\162\155\141\040\105\156\163\164\151\164\303 -\274\163\303\274\040\055\040\125\105\113\101\105\061\043\060\041 -\006\003\125\004\013\014\032\113\141\155\165\040\123\145\162\164 -\151\146\151\153\141\163\171\157\156\040\115\145\162\153\145\172 -\151\061\112\060\110\006\003\125\004\003\014\101\124\303\234\102 -\304\260\124\101\113\040\125\105\113\101\105\040\113\303\266\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\055\040\123\303\274\162\303\274\155\040\063\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\212\155 -\113\377\020\210\072\303\366\176\224\350\352\040\144\160\256\041 -\201\276\072\173\074\333\361\035\122\177\131\372\363\042\114\225 -\240\220\274\110\116\021\253\373\267\265\215\172\203\050\214\046 -\106\330\116\225\100\207\141\237\305\236\155\201\207\127\154\212 -\073\264\146\352\314\100\374\343\252\154\262\313\001\333\062\277 -\322\353\205\317\241\015\125\303\133\070\127\160\270\165\306\171 -\321\024\060\355\033\130\133\153\357\065\362\241\041\116\305\316 -\174\231\137\154\271\270\042\223\120\247\315\114\160\152\276\152 -\005\177\023\234\053\036\352\376\107\316\004\245\157\254\223\056 -\174\053\237\236\171\023\221\350\352\236\312\070\165\216\142\260 -\225\223\052\345\337\351\136\227\156\040\137\137\204\172\104\071 -\031\100\034\272\125\053\373\060\262\201\357\204\343\334\354\230 -\070\071\003\205\010\251\124\003\005\051\360\311\217\213\352\013 -\206\145\031\021\323\351\011\043\336\150\223\003\311\066\034\041 -\156\316\214\146\361\231\060\330\327\263\303\035\370\201\056\250 -\275\202\013\146\376\202\313\341\340\032\202\303\100\201\002\003 -\001\000\001\243\102\060\100\060\035\006\003\125\035\016\004\026 -\004\024\275\210\207\311\217\366\244\012\013\252\353\305\376\221 -\043\235\253\112\212\062\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\005\005\000\003\202\001\001\000\035\174\372\111\217 -\064\351\267\046\222\026\232\005\164\347\113\320\155\071\154\303 -\046\366\316\270\061\274\304\337\274\052\370\067\221\030\334\004 -\310\144\231\053\030\155\200\003\131\311\256\370\130\320\076\355 -\303\043\237\151\074\206\070\034\236\357\332\047\170\321\204\067 -\161\212\074\113\071\317\176\105\006\326\055\330\212\115\170\022 -\326\255\302\323\313\322\320\101\363\046\066\112\233\225\154\014 -\356\345\321\103\047\146\301\210\367\172\263\040\154\352\260\151 -\053\307\040\350\014\003\304\101\005\231\342\077\344\153\370\240 -\206\201\307\204\306\037\325\113\201\022\262\026\041\054\023\241 -\200\262\136\014\112\023\236\040\330\142\100\253\220\352\144\112 -\057\254\015\001\022\171\105\250\057\207\031\150\310\342\205\307 -\060\262\165\371\070\077\262\300\223\264\153\342\003\104\316\147 -\240\337\211\326\255\214\166\243\023\303\224\141\053\153\331\154 -\301\007\012\042\007\205\154\205\044\106\251\276\077\213\170\204 -\202\176\044\014\235\375\201\067\343\045\250\355\066\116\225\054 -\311\234\220\332\354\251\102\074\255\266\002 -END -CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE - -# Trust for Certificate "TUBITAK UEKAE Kok Sertifika Hizmet Saglayicisi - Surum 3" -# Issuer: CN=T..B..TAK UEKAE K..k Sertifika Hizmet Sa..lay..c..s.. - S..r..m ...,OU=Kamu Sertifikasyon Merkezi,OU=Ulusal Elektronik ve Kriptoloji Ara..t..rma Enstit..s.. - UEKAE,O=T..rkiye Bilimsel ve Teknolojik Ara..t..rma Kurumu - T..B..TAK,L=Gebze - Kocaeli,C=TR -# Serial Number: 17 (0x11) -# Subject: CN=T..B..TAK UEKAE K..k Sertifika Hizmet Sa..lay..c..s.. - S..r..m ...,OU=Kamu Sertifikasyon Merkezi,OU=Ulusal Elektronik ve Kriptoloji Ara..t..rma Enstit..s.. - UEKAE,O=T..rkiye Bilimsel ve Teknolojik Ara..t..rma Kurumu - T..B..TAK,L=Gebze - Kocaeli,C=TR -# Not Valid Before: Fri Aug 24 11:37:07 2007 -# Not Valid After : Mon Aug 21 11:37:07 2017 -# Fingerprint (MD5): ED:41:F5:8C:50:C5:2B:9C:73:E6:EE:6C:EB:C2:A8:26 -# Fingerprint (SHA1): 1B:4B:39:61:26:27:6B:64:91:A2:68:6D:D7:02:43:21:2D:1F:1D:96 -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\xc3\x9c\x42\xC4\xB0TAK UEKAE K\xC3\xB6k Sertifika Hizmet Sa\xC4\x9Flay\xc4\xb1\x63\xc4\xb1s\xc4\xb1 - S\xC3\xBCr\xC3\xBCm 3" -CKA_CERT_SHA1_HASH MULTILINE_OCTAL -\033\113\071\141\046\047\153\144\221\242\150\155\327\002\103\041 -\055\037\035\226 -END -CKA_CERT_MD5_HASH MULTILINE_OCTAL -\355\101\365\214\120\305\053\234\163\346\356\154\353\302\250\046 -END -CKA_ISSUER MULTILINE_OCTAL -\060\202\001\053\061\013\060\011\006\003\125\004\006\023\002\124 -\122\061\030\060\026\006\003\125\004\007\014\017\107\145\142\172 -\145\040\055\040\113\157\143\141\145\154\151\061\107\060\105\006 -\003\125\004\012\014\076\124\303\274\162\153\151\171\145\040\102 -\151\154\151\155\163\145\154\040\166\145\040\124\145\153\156\157 -\154\157\152\151\153\040\101\162\141\305\237\164\304\261\162\155 -\141\040\113\165\162\165\155\165\040\055\040\124\303\234\102\304 -\260\124\101\113\061\110\060\106\006\003\125\004\013\014\077\125 -\154\165\163\141\154\040\105\154\145\153\164\162\157\156\151\153 -\040\166\145\040\113\162\151\160\164\157\154\157\152\151\040\101 -\162\141\305\237\164\304\261\162\155\141\040\105\156\163\164\151 -\164\303\274\163\303\274\040\055\040\125\105\113\101\105\061\043 -\060\041\006\003\125\004\013\014\032\113\141\155\165\040\123\145 -\162\164\151\146\151\153\141\163\171\157\156\040\115\145\162\153 -\145\172\151\061\112\060\110\006\003\125\004\003\014\101\124\303 -\234\102\304\260\124\101\113\040\125\105\113\101\105\040\113\303 -\266\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\055\040\123\303\274\162\303\274\155\040\063 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\001\021 -END -CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR -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 "certSIGN ROOT CA" # # Issuer: OU=certSIGN ROOT CA,O=certSIGN,C=RO @@ -10461,172 +9581,6 @@ CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE # -# Certificate "ACEDICOM Root" -# -# Issuer: C=ES,O=EDICOM,OU=PKI,CN=ACEDICOM Root -# Serial Number:61:8d:c7:86:3b:01:82:05 -# Subject: C=ES,O=EDICOM,OU=PKI,CN=ACEDICOM Root -# Not Valid Before: Fri Apr 18 16:24:22 2008 -# Not Valid After : Thu Apr 13 16:24:22 2028 -# Fingerprint (MD5): 42:81:A0:E2:1C:E3:55:10:DE:55:89:42:65:96:22:E6 -# Fingerprint (SHA1): E0:B4:32:2E:B2:F6:A5:68:B6:54:53:84:48:18:4A:50:36:87:43:84 -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 "ACEDICOM Root" -CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 -CKA_SUBJECT MULTILINE_OCTAL -\060\104\061\026\060\024\006\003\125\004\003\014\015\101\103\105 -\104\111\103\117\115\040\122\157\157\164\061\014\060\012\006\003 -\125\004\013\014\003\120\113\111\061\017\060\015\006\003\125\004 -\012\014\006\105\104\111\103\117\115\061\013\060\011\006\003\125 -\004\006\023\002\105\123 -END -CKA_ID UTF8 "0" -CKA_ISSUER MULTILINE_OCTAL -\060\104\061\026\060\024\006\003\125\004\003\014\015\101\103\105 -\104\111\103\117\115\040\122\157\157\164\061\014\060\012\006\003 -\125\004\013\014\003\120\113\111\061\017\060\015\006\003\125\004 -\012\014\006\105\104\111\103\117\115\061\013\060\011\006\003\125 -\004\006\023\002\105\123 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\010\141\215\307\206\073\001\202\005 -END -CKA_VALUE MULTILINE_OCTAL -\060\202\005\265\060\202\003\235\240\003\002\001\002\002\010\141 -\215\307\206\073\001\202\005\060\015\006\011\052\206\110\206\367 -\015\001\001\005\005\000\060\104\061\026\060\024\006\003\125\004 -\003\014\015\101\103\105\104\111\103\117\115\040\122\157\157\164 -\061\014\060\012\006\003\125\004\013\014\003\120\113\111\061\017 -\060\015\006\003\125\004\012\014\006\105\104\111\103\117\115\061 -\013\060\011\006\003\125\004\006\023\002\105\123\060\036\027\015 -\060\070\060\064\061\070\061\066\062\064\062\062\132\027\015\062 -\070\060\064\061\063\061\066\062\064\062\062\132\060\104\061\026 -\060\024\006\003\125\004\003\014\015\101\103\105\104\111\103\117 -\115\040\122\157\157\164\061\014\060\012\006\003\125\004\013\014 -\003\120\113\111\061\017\060\015\006\003\125\004\012\014\006\105 -\104\111\103\117\115\061\013\060\011\006\003\125\004\006\023\002 -\105\123\060\202\002\042\060\015\006\011\052\206\110\206\367\015 -\001\001\001\005\000\003\202\002\017\000\060\202\002\012\002\202 -\002\001\000\377\222\225\341\150\006\166\264\054\310\130\110\312 -\375\200\124\051\125\143\044\377\220\145\233\020\165\173\303\152 -\333\142\002\001\362\030\206\265\174\132\070\261\344\130\271\373 -\323\330\055\237\275\062\067\277\054\025\155\276\265\364\041\322 -\023\221\331\007\255\001\005\326\363\275\167\316\137\102\201\012 -\371\152\343\203\000\250\053\056\125\023\143\201\312\107\034\173 -\134\026\127\172\033\203\140\004\072\076\145\303\315\001\336\336 -\244\326\014\272\216\336\331\004\356\027\126\042\233\217\143\375 -\115\026\013\267\173\167\214\371\045\265\321\155\231\022\056\117 -\032\270\346\352\004\222\256\075\021\271\121\102\075\207\260\061 -\205\257\171\132\234\376\347\116\136\222\117\103\374\253\072\255 -\245\022\046\146\271\342\014\327\230\316\324\130\245\225\100\012 -\267\104\235\023\164\053\302\245\353\042\025\230\020\330\213\305 -\004\237\035\217\140\345\006\033\233\317\271\171\240\075\242\043 -\077\102\077\153\372\034\003\173\060\215\316\154\300\277\346\033 -\137\277\147\270\204\031\325\025\357\173\313\220\066\061\142\311 -\274\002\253\106\137\233\376\032\150\224\064\075\220\216\255\366 -\344\035\011\177\112\210\070\077\276\147\375\064\226\365\035\274 -\060\164\313\070\356\325\154\253\324\374\364\000\267\000\133\205 -\062\026\166\063\351\330\243\231\235\005\000\252\026\346\363\201 -\175\157\175\252\206\155\255\025\164\323\304\242\161\252\364\024 -\175\347\062\270\037\274\325\361\116\275\157\027\002\071\327\016 -\225\102\072\307\000\076\351\046\143\021\352\013\321\112\377\030 -\235\262\327\173\057\072\331\226\373\350\036\222\256\023\125\310 -\331\047\366\334\110\033\260\044\301\205\343\167\235\232\244\363 -\014\021\035\015\310\264\024\356\265\202\127\011\277\040\130\177 -\057\042\043\330\160\313\171\154\311\113\362\251\052\310\374\207 -\053\327\032\120\370\047\350\057\103\343\072\275\330\127\161\375 -\316\246\122\133\371\335\115\355\345\366\157\211\355\273\223\234 -\166\041\165\360\222\114\051\367\057\234\001\056\376\120\106\236 -\144\014\024\263\007\133\305\302\163\154\361\007\134\105\044\024 -\065\256\203\361\152\115\211\172\372\263\330\055\146\360\066\207 -\365\053\123\002\003\001\000\001\243\201\252\060\201\247\060\017 -\006\003\125\035\023\001\001\377\004\005\060\003\001\001\377\060 -\037\006\003\125\035\043\004\030\060\026\200\024\246\263\341\053 -\053\111\266\327\163\241\252\224\365\001\347\163\145\114\254\120 -\060\016\006\003\125\035\017\001\001\377\004\004\003\002\001\206 -\060\035\006\003\125\035\016\004\026\004\024\246\263\341\053\053 -\111\266\327\163\241\252\224\365\001\347\163\145\114\254\120\060 -\104\006\003\125\035\040\004\075\060\073\060\071\006\004\125\035 -\040\000\060\061\060\057\006\010\053\006\001\005\005\007\002\001 -\026\043\150\164\164\160\072\057\057\141\143\145\144\151\143\157 -\155\056\145\144\151\143\157\155\147\162\157\165\160\056\143\157 -\155\057\144\157\143\060\015\006\011\052\206\110\206\367\015\001 -\001\005\005\000\003\202\002\001\000\316\054\013\122\121\142\046 -\175\014\047\203\217\305\366\332\240\150\173\117\222\136\352\244 -\163\062\021\123\104\262\104\313\235\354\017\171\102\263\020\246 -\307\015\235\313\266\372\077\072\174\352\277\210\123\033\074\367 -\202\372\005\065\063\341\065\250\127\300\347\375\215\117\077\223 -\062\117\170\146\003\167\007\130\351\225\310\176\076\320\171\000 -\214\362\033\121\063\233\274\224\351\072\173\156\122\055\062\236 -\043\244\105\373\266\056\023\260\213\030\261\335\316\325\035\247 -\102\177\125\276\373\133\273\107\324\374\044\315\004\256\226\005 -\025\326\254\316\060\363\312\013\305\272\342\042\340\246\255\042 -\344\002\356\164\021\177\114\377\170\035\065\332\346\002\064\353 -\030\022\141\167\006\011\026\143\352\030\255\242\207\037\362\307 -\200\011\011\165\116\020\250\217\075\206\270\165\021\300\044\142 -\212\226\173\112\105\351\354\131\305\276\153\203\346\341\350\254 -\265\060\036\376\005\007\200\371\341\043\015\120\217\005\230\377 -\054\137\350\073\266\255\317\201\265\041\207\312\010\052\043\047 -\060\040\053\317\355\224\133\254\262\172\322\307\050\241\212\013 -\233\115\112\054\155\205\077\011\162\074\147\342\331\334\007\272 -\353\145\173\132\001\143\326\220\133\117\027\146\075\177\013\031 -\243\223\143\020\122\052\237\024\026\130\342\334\245\364\241\026 -\213\016\221\213\201\312\233\131\372\330\153\221\007\145\125\137 -\122\037\257\072\373\220\335\151\245\133\234\155\016\054\266\372 -\316\254\245\174\062\112\147\100\334\060\064\043\335\327\004\043 -\146\360\374\125\200\247\373\146\031\202\065\147\142\160\071\136 -\157\307\352\220\100\104\010\036\270\262\326\333\356\131\247\015 -\030\171\064\274\124\030\136\123\312\064\121\355\105\012\346\216 -\307\202\066\076\247\070\143\251\060\054\027\020\140\222\237\125 -\207\022\131\020\302\017\147\151\021\314\116\036\176\112\232\255 -\257\100\250\165\254\126\220\164\270\240\234\245\171\157\334\351 -\032\310\151\005\351\272\372\003\263\174\344\340\116\302\316\235 -\350\266\106\015\156\176\127\072\147\224\302\313\037\234\167\112 -\147\116\151\206\103\223\070\373\266\333\117\203\221\324\140\176 -\113\076\053\070\007\125\230\136\244 -END -CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE - -# Trust for Certificate "ACEDICOM Root" -# Issuer: C=ES,O=EDICOM,OU=PKI,CN=ACEDICOM Root -# Serial Number:61:8d:c7:86:3b:01:82:05 -# Subject: C=ES,O=EDICOM,OU=PKI,CN=ACEDICOM Root -# Not Valid Before: Fri Apr 18 16:24:22 2008 -# Not Valid After : Thu Apr 13 16:24:22 2028 -# Fingerprint (MD5): 42:81:A0:E2:1C:E3:55:10:DE:55:89:42:65:96:22:E6 -# Fingerprint (SHA1): E0:B4:32:2E:B2:F6:A5:68:B6:54:53:84:48:18:4A:50:36:87:43:84 -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 "ACEDICOM Root" -CKA_CERT_SHA1_HASH MULTILINE_OCTAL -\340\264\062\056\262\366\245\150\266\124\123\204\110\030\112\120 -\066\207\103\204 -END -CKA_CERT_MD5_HASH MULTILINE_OCTAL -\102\201\240\342\034\343\125\020\336\125\211\102\145\226\042\346 -END -CKA_ISSUER MULTILINE_OCTAL -\060\104\061\026\060\024\006\003\125\004\003\014\015\101\103\105 -\104\111\103\117\115\040\122\157\157\164\061\014\060\012\006\003 -\125\004\013\014\003\120\113\111\061\017\060\015\006\003\125\004 -\012\014\006\105\104\111\103\117\115\061\013\060\011\006\003\125 -\004\006\023\002\105\123 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\010\141\215\307\206\073\001\202\005 -END -CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR -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 "Microsec e-Szigno Root CA 2009" # # Issuer: E=info@e-szigno.hu,CN=Microsec e-Szigno Root CA 2009,O=Microsec Ltd.,L=Budapest,C=HU @@ -11667,1725 +10621,6 @@ CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE # -# Certificate "Bogus Mozilla Addons" -# -# Issuer: CN=UTN-USERFirst-Hardware,OU=http://www.usertrust.com,O=The USERTRUST Network,L=Salt Lake City,ST=UT,C=US -# Serial Number:00:92:39:d5:34:8f:40:d1:69:5a:74:54:70:e1:f2:3f:43 -# Subject: CN=addons.mozilla.org,OU=PlatinumSSL,OU=Hosted by GTI Group Corporation,OU=Tech Dept.,O=Google Ltd.,STREET=Sea Village 10,L=English,ST=Florida,postalCode=38477,C=US -# Not Valid Before: Tue Mar 15 00:00:00 2011 -# Not Valid After : Fri Mar 14 23:59:59 2014 -# Fingerprint (MD5): 84:C5:18:67:1F:2A:1A:90:BE:E2:B1:18:4F:03:00:32 -# Fingerprint (SHA1): 30:5F:8B:D1:7A:A2:CB:C4:83:A4:C4:1B:19:A3:9A:0C:75:DA:39:D6 -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 "Bogus Mozilla Addons" -CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 -CKA_SUBJECT MULTILINE_OCTAL -\060\201\342\061\013\060\011\006\003\125\004\006\023\002\125\123 -\061\016\060\014\006\003\125\004\021\023\005\063\070\064\067\067 -\061\020\060\016\006\003\125\004\010\023\007\106\154\157\162\151 -\144\141\061\020\060\016\006\003\125\004\007\023\007\105\156\147 -\154\151\163\150\061\027\060\025\006\003\125\004\011\023\016\123 -\145\141\040\126\151\154\154\141\147\145\040\061\060\061\024\060 -\022\006\003\125\004\012\023\013\107\157\157\147\154\145\040\114 -\164\144\056\061\023\060\021\006\003\125\004\013\023\012\124\145 -\143\150\040\104\145\160\164\056\061\050\060\046\006\003\125\004 -\013\023\037\110\157\163\164\145\144\040\142\171\040\107\124\111 -\040\107\162\157\165\160\040\103\157\162\160\157\162\141\164\151 -\157\156\061\024\060\022\006\003\125\004\013\023\013\120\154\141 -\164\151\156\165\155\123\123\114\061\033\060\031\006\003\125\004 -\003\023\022\141\144\144\157\156\163\056\155\157\172\151\154\154 -\141\056\157\162\147 -END -CKA_ID UTF8 "0" -CKA_ISSUER MULTILINE_OCTAL -\060\201\227\061\013\060\011\006\003\125\004\006\023\002\125\123 -\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060 -\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153 -\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023 -\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116 -\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023 -\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162 -\164\162\165\163\164\056\143\157\155\061\037\060\035\006\003\125 -\004\003\023\026\125\124\116\055\125\123\105\122\106\151\162\163 -\164\055\110\141\162\144\167\141\162\145 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\021\000\222\071\325\064\217\100\321\151\132\164\124\160\341 -\362\077\103 -END -CKA_VALUE MULTILINE_OCTAL -\060\202\005\370\060\202\004\340\240\003\002\001\002\002\021\000 -\222\071\325\064\217\100\321\151\132\164\124\160\341\362\077\103 -\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060 -\201\227\061\013\060\011\006\003\125\004\006\023\002\125\123\061 -\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060\025 -\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153\145 -\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023\025 -\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116\145 -\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023\030 -\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162\164 -\162\165\163\164\056\143\157\155\061\037\060\035\006\003\125\004 -\003\023\026\125\124\116\055\125\123\105\122\106\151\162\163\164 -\055\110\141\162\144\167\141\162\145\060\036\027\015\061\061\060 -\063\061\065\060\060\060\060\060\060\132\027\015\061\064\060\063 -\061\064\062\063\065\071\065\071\132\060\201\342\061\013\060\011 -\006\003\125\004\006\023\002\125\123\061\016\060\014\006\003\125 -\004\021\023\005\063\070\064\067\067\061\020\060\016\006\003\125 -\004\010\023\007\106\154\157\162\151\144\141\061\020\060\016\006 -\003\125\004\007\023\007\105\156\147\154\151\163\150\061\027\060 -\025\006\003\125\004\011\023\016\123\145\141\040\126\151\154\154 -\141\147\145\040\061\060\061\024\060\022\006\003\125\004\012\023 -\013\107\157\157\147\154\145\040\114\164\144\056\061\023\060\021 -\006\003\125\004\013\023\012\124\145\143\150\040\104\145\160\164 -\056\061\050\060\046\006\003\125\004\013\023\037\110\157\163\164 -\145\144\040\142\171\040\107\124\111\040\107\162\157\165\160\040 -\103\157\162\160\157\162\141\164\151\157\156\061\024\060\022\006 -\003\125\004\013\023\013\120\154\141\164\151\156\165\155\123\123 -\114\061\033\060\031\006\003\125\004\003\023\022\141\144\144\157 -\156\163\056\155\157\172\151\154\154\141\056\157\162\147\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\253 -\306\155\066\363\025\163\170\203\163\316\164\205\325\256\354\262 -\360\340\044\037\023\203\270\040\254\273\232\376\210\273\253\241 -\035\013\037\105\000\252\111\267\065\067\014\152\357\107\114\271 -\321\276\343\127\022\004\215\222\307\266\354\001\274\266\332\307 -\201\070\040\255\162\205\346\016\374\201\154\007\255\150\166\070 -\305\104\327\314\306\112\305\227\076\144\364\121\346\360\176\262 -\354\126\367\045\202\115\111\230\313\026\230\335\043\361\211\221 -\321\027\227\100\231\046\326\342\242\053\136\337\275\211\362\033 -\032\123\055\314\120\101\172\320\075\052\014\125\160\024\001\351 -\130\111\020\172\013\223\202\213\341\036\355\072\200\020\202\316 -\226\212\064\360\314\327\323\271\264\120\207\125\124\011\270\235 -\102\050\125\000\345\214\065\124\277\335\045\221\106\267\015\345 -\135\203\250\345\213\373\204\344\074\256\166\332\304\103\053\133 -\164\013\370\276\135\150\361\170\133\265\316\175\361\135\231\100 -\332\312\356\070\201\120\276\230\241\154\270\044\255\363\257\214 -\017\327\021\050\054\204\030\114\175\265\331\217\060\265\033\002 -\003\001\000\001\243\202\001\360\060\202\001\354\060\037\006\003 -\125\035\043\004\030\060\026\200\024\241\162\137\046\033\050\230 -\103\225\135\007\067\325\205\226\235\113\322\303\105\060\035\006 -\003\125\035\016\004\026\004\024\335\200\322\124\075\367\114\160 -\312\243\260\335\064\172\062\344\350\073\132\073\060\016\006\003 -\125\035\017\001\001\377\004\004\003\002\005\240\060\014\006\003 -\125\035\023\001\001\377\004\002\060\000\060\035\006\003\125\035 -\045\004\026\060\024\006\010\053\006\001\005\005\007\003\001\006 -\010\053\006\001\005\005\007\003\002\060\106\006\003\125\035\040 -\004\077\060\075\060\073\006\014\053\006\001\004\001\262\061\001 -\002\001\003\004\060\053\060\051\006\010\053\006\001\005\005\007 -\002\001\026\035\150\164\164\160\163\072\057\057\163\145\143\165 -\162\145\056\143\157\155\157\144\157\056\143\157\155\057\103\120 -\123\060\173\006\003\125\035\037\004\164\060\162\060\070\240\066 -\240\064\206\062\150\164\164\160\072\057\057\143\162\154\056\143 -\157\155\157\144\157\143\141\056\143\157\155\057\125\124\116\055 -\125\123\105\122\106\151\162\163\164\055\110\141\162\144\167\141 -\162\145\056\143\162\154\060\066\240\064\240\062\206\060\150\164 -\164\160\072\057\057\143\162\154\056\143\157\155\157\144\157\056 -\156\145\164\057\125\124\116\055\125\123\105\122\106\151\162\163 -\164\055\110\141\162\144\167\141\162\145\056\143\162\154\060\161 -\006\010\053\006\001\005\005\007\001\001\004\145\060\143\060\073 -\006\010\053\006\001\005\005\007\060\002\206\057\150\164\164\160 -\072\057\057\143\162\164\056\143\157\155\157\144\157\143\141\056 -\143\157\155\057\125\124\116\101\144\144\124\162\165\163\164\123 -\145\162\166\145\162\103\101\056\143\162\164\060\044\006\010\053 -\006\001\005\005\007\060\001\206\030\150\164\164\160\072\057\057 -\157\143\163\160\056\143\157\155\157\144\157\143\141\056\143\157 -\155\060\065\006\003\125\035\021\004\056\060\054\202\022\141\144 -\144\157\156\163\056\155\157\172\151\154\154\141\056\157\162\147 -\202\026\167\167\167\056\141\144\144\157\156\163\056\155\157\172 -\151\154\154\141\056\157\162\147\060\015\006\011\052\206\110\206 -\367\015\001\001\005\005\000\003\202\001\001\000\063\073\143\025 -\374\261\354\024\054\223\335\165\224\336\201\132\331\116\231\276 -\373\112\244\071\125\115\241\100\172\336\023\052\207\251\067\317 -\350\325\373\255\321\173\155\157\214\040\207\202\124\346\127\111 -\274\040\050\204\315\326\001\331\223\213\027\156\043\146\345\204 -\310\200\077\306\241\160\200\344\354\115\035\371\374\221\132\163 -\142\051\232\367\040\034\141\340\213\071\237\312\274\176\215\335 -\274\331\261\343\237\236\337\025\123\221\041\122\013\331\032\043 -\017\146\066\333\254\223\226\112\243\245\042\317\051\367\242\231 -\250\366\266\331\100\256\331\176\266\366\130\056\233\254\066\312 -\144\217\145\122\334\206\234\202\253\156\120\113\332\137\372\005 -\000\210\060\016\336\215\126\277\201\107\215\075\006\342\262\142 -\222\147\217\236\310\232\262\345\006\270\160\044\270\167\174\043 -\012\070\303\171\010\330\261\121\235\254\225\021\307\100\027\236 -\243\034\217\362\021\247\150\047\332\111\005\204\030\174\130\055 -\001\147\134\345\237\241\051\273\112\071\105\057\277\021\252\171 -\242\355\264\324\265\145\103\267\223\106\212\323 -END - -# Trust for Certificate "Bogus Mozilla Addons" -# Issuer: CN=UTN-USERFirst-Hardware,OU=http://www.usertrust.com,O=The USERTRUST Network,L=Salt Lake City,ST=UT,C=US -# Serial Number:00:92:39:d5:34:8f:40:d1:69:5a:74:54:70:e1:f2:3f:43 -# Subject: CN=addons.mozilla.org,OU=PlatinumSSL,OU=Hosted by GTI Group Corporation,OU=Tech Dept.,O=Google Ltd.,STREET=Sea Village 10,L=English,ST=Florida,postalCode=38477,C=US -# Not Valid Before: Tue Mar 15 00:00:00 2011 -# Not Valid After : Fri Mar 14 23:59:59 2014 -# Fingerprint (MD5): 84:C5:18:67:1F:2A:1A:90:BE:E2:B1:18:4F:03:00:32 -# Fingerprint (SHA1): 30:5F:8B:D1:7A:A2:CB:C4:83:A4:C4:1B:19:A3:9A:0C:75:DA:39:D6 -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 "Bogus Mozilla Addons" -CKA_CERT_SHA1_HASH MULTILINE_OCTAL -\060\137\213\321\172\242\313\304\203\244\304\033\031\243\232\014 -\165\332\071\326 -END -CKA_CERT_MD5_HASH MULTILINE_OCTAL -\204\305\030\147\037\052\032\220\276\342\261\030\117\003\000\062 -END -CKA_ISSUER MULTILINE_OCTAL -\060\201\227\061\013\060\011\006\003\125\004\006\023\002\125\123 -\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060 -\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153 -\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023 -\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116 -\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023 -\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162 -\164\162\165\163\164\056\143\157\155\061\037\060\035\006\003\125 -\004\003\023\026\125\124\116\055\125\123\105\122\106\151\162\163 -\164\055\110\141\162\144\167\141\162\145 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\021\000\222\071\325\064\217\100\321\151\132\164\124\160\341 -\362\077\103 -END -CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED -CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED -CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED -CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE - -# -# Certificate "Bogus Global Trustee" -# -# Issuer: CN=UTN-USERFirst-Hardware,OU=http://www.usertrust.com,O=The USERTRUST Network,L=Salt Lake City,ST=UT,C=US -# Serial Number:00:d8:f3:5f:4e:b7:87:2b:2d:ab:06:92:e3:15:38:2f:b0 -# Subject: CN=global trustee,OU=PlatinumSSL,OU=Hosted by GTI Group Corporation,OU=Global Trustee,O=Global Trustee,STREET=Sea Village 10,L=Tampa,ST=Florida,postalCode=38477,C=US -# Not Valid Before: Tue Mar 15 00:00:00 2011 -# Not Valid After : Fri Mar 14 23:59:59 2014 -# Fingerprint (MD5): FE:0D:01:6E:71:CB:8C:D8:3F:0E:0C:CD:49:35:B8:57 -# Fingerprint (SHA1): 61:79:3F:CB:FA:4F:90:08:30:9B:BA:5F:F1:2D:2C:B2:9C:D4:15:1A -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 "Bogus Global Trustee" -CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 -CKA_SUBJECT MULTILINE_OCTAL -\060\201\343\061\013\060\011\006\003\125\004\006\023\002\125\123 -\061\016\060\014\006\003\125\004\021\023\005\063\070\064\067\067 -\061\020\060\016\006\003\125\004\010\023\007\106\154\157\162\151 -\144\141\061\016\060\014\006\003\125\004\007\023\005\124\141\155 -\160\141\061\027\060\025\006\003\125\004\011\023\016\123\145\141 -\040\126\151\154\154\141\147\145\040\061\060\061\027\060\025\006 -\003\125\004\012\023\016\107\154\157\142\141\154\040\124\162\165 -\163\164\145\145\061\027\060\025\006\003\125\004\013\023\016\107 -\154\157\142\141\154\040\124\162\165\163\164\145\145\061\050\060 -\046\006\003\125\004\013\023\037\110\157\163\164\145\144\040\142 -\171\040\107\124\111\040\107\162\157\165\160\040\103\157\162\160 -\157\162\141\164\151\157\156\061\024\060\022\006\003\125\004\013 -\023\013\120\154\141\164\151\156\165\155\123\123\114\061\027\060 -\025\006\003\125\004\003\023\016\147\154\157\142\141\154\040\164 -\162\165\163\164\145\145 -END -CKA_ID UTF8 "0" -CKA_ISSUER MULTILINE_OCTAL -\060\201\227\061\013\060\011\006\003\125\004\006\023\002\125\123 -\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060 -\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153 -\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023 -\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116 -\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023 -\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162 -\164\162\165\163\164\056\143\157\155\061\037\060\035\006\003\125 -\004\003\023\026\125\124\116\055\125\123\105\122\106\151\162\163 -\164\055\110\141\162\144\167\141\162\145 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\021\000\330\363\137\116\267\207\053\055\253\006\222\343\025 -\070\057\260 -END -CKA_VALUE MULTILINE_OCTAL -\060\202\006\335\060\202\005\305\240\003\002\001\002\002\021\000 -\330\363\137\116\267\207\053\055\253\006\222\343\025\070\057\260 -\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060 -\201\227\061\013\060\011\006\003\125\004\006\023\002\125\123\061 -\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060\025 -\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153\145 -\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023\025 -\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116\145 -\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023\030 -\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162\164 -\162\165\163\164\056\143\157\155\061\037\060\035\006\003\125\004 -\003\023\026\125\124\116\055\125\123\105\122\106\151\162\163\164 -\055\110\141\162\144\167\141\162\145\060\036\027\015\061\061\060 -\063\061\065\060\060\060\060\060\060\132\027\015\061\064\060\063 -\061\064\062\063\065\071\065\071\132\060\201\343\061\013\060\011 -\006\003\125\004\006\023\002\125\123\061\016\060\014\006\003\125 -\004\021\023\005\063\070\064\067\067\061\020\060\016\006\003\125 -\004\010\023\007\106\154\157\162\151\144\141\061\016\060\014\006 -\003\125\004\007\023\005\124\141\155\160\141\061\027\060\025\006 -\003\125\004\011\023\016\123\145\141\040\126\151\154\154\141\147 -\145\040\061\060\061\027\060\025\006\003\125\004\012\023\016\107 -\154\157\142\141\154\040\124\162\165\163\164\145\145\061\027\060 -\025\006\003\125\004\013\023\016\107\154\157\142\141\154\040\124 -\162\165\163\164\145\145\061\050\060\046\006\003\125\004\013\023 -\037\110\157\163\164\145\144\040\142\171\040\107\124\111\040\107 -\162\157\165\160\040\103\157\162\160\157\162\141\164\151\157\156 -\061\024\060\022\006\003\125\004\013\023\013\120\154\141\164\151 -\156\165\155\123\123\114\061\027\060\025\006\003\125\004\003\023 -\016\147\154\157\142\141\154\040\164\162\165\163\164\145\145\060 -\202\002\042\060\015\006\011\052\206\110\206\367\015\001\001\001 -\005\000\003\202\002\017\000\060\202\002\012\002\202\002\001\000 -\331\164\362\252\101\035\337\365\302\026\103\111\134\051\277\266 -\211\164\051\274\234\215\014\106\117\131\176\262\101\027\146\064 -\014\145\211\341\154\045\343\206\012\236\042\105\042\214\335\235 -\346\243\225\336\334\210\002\125\134\343\133\221\165\353\046\151 -\143\271\056\306\312\056\047\337\210\272\002\040\156\376\271\013 -\051\327\247\326\327\110\032\034\316\335\037\251\047\016\142\117 -\241\226\036\335\124\072\064\143\112\166\365\167\175\131\147\330 -\020\324\265\017\072\103\042\230\333\364\011\304\012\160\316\335 -\220\324\057\357\164\023\303\315\302\211\071\142\025\235\346\164 -\250\350\233\360\143\156\234\211\266\016\255\233\367\314\202\350 -\350\055\270\013\332\042\354\111\205\007\210\231\230\077\364\164 -\251\011\367\201\174\227\013\131\231\030\162\213\333\224\202\053 -\247\350\252\153\227\277\210\176\165\260\213\105\105\014\307\250 -\011\352\033\101\130\060\073\137\170\145\025\064\322\344\074\064 -\015\035\330\144\074\212\245\126\111\231\050\055\113\362\317\315 -\331\156\111\144\233\251\171\220\167\125\251\010\033\255\032\164 -\236\340\003\223\012\011\267\255\247\264\134\357\203\154\267\232 -\264\306\150\100\200\035\102\321\156\171\233\251\031\041\232\234 -\371\206\055\000\321\064\376\340\266\371\125\266\365\046\305\225 -\026\245\174\163\237\012\051\211\254\072\230\367\233\164\147\267 -\220\267\135\011\043\152\152\355\054\020\356\123\012\020\360\026 -\037\127\263\261\015\171\221\031\260\353\315\060\077\240\024\137 -\263\306\375\134\063\247\260\377\230\260\125\214\271\245\362\157 -\107\044\111\041\151\314\102\242\121\000\100\205\214\202\202\253 -\062\245\313\232\334\320\331\030\015\337\031\364\257\203\015\301 -\076\061\333\044\110\266\165\200\241\341\311\167\144\036\247\345 -\213\177\025\115\113\247\302\320\355\171\225\136\221\061\354\030 -\377\116\237\110\024\352\165\272\041\316\051\166\351\037\116\121 -\207\056\263\314\004\140\272\043\037\037\145\262\012\270\325\156 -\217\113\102\211\107\251\201\220\133\053\262\266\256\346\240\160 -\173\170\220\012\172\305\345\347\305\373\012\366\057\151\214\214 -\037\127\340\006\231\377\021\325\122\062\040\227\047\230\356\145 -\002\003\001\000\001\243\202\001\324\060\202\001\320\060\037\006 -\003\125\035\043\004\030\060\026\200\024\241\162\137\046\033\050 -\230\103\225\135\007\067\325\205\226\235\113\322\303\105\060\035 -\006\003\125\035\016\004\026\004\024\267\303\336\032\103\355\101 -\227\251\217\051\170\234\003\271\254\100\102\000\254\060\016\006 -\003\125\035\017\001\001\377\004\004\003\002\005\240\060\014\006 -\003\125\035\023\001\001\377\004\002\060\000\060\035\006\003\125 -\035\045\004\026\060\024\006\010\053\006\001\005\005\007\003\001 -\006\010\053\006\001\005\005\007\003\002\060\106\006\003\125\035 -\040\004\077\060\075\060\073\006\014\053\006\001\004\001\262\061 -\001\002\001\003\004\060\053\060\051\006\010\053\006\001\005\005 -\007\002\001\026\035\150\164\164\160\163\072\057\057\163\145\143 -\165\162\145\056\143\157\155\157\144\157\056\143\157\155\057\103 -\120\123\060\173\006\003\125\035\037\004\164\060\162\060\070\240 -\066\240\064\206\062\150\164\164\160\072\057\057\143\162\154\056 -\143\157\155\157\144\157\143\141\056\143\157\155\057\125\124\116 -\055\125\123\105\122\106\151\162\163\164\055\110\141\162\144\167 -\141\162\145\056\143\162\154\060\066\240\064\240\062\206\060\150 -\164\164\160\072\057\057\143\162\154\056\143\157\155\157\144\157 -\056\156\145\164\057\125\124\116\055\125\123\105\122\106\151\162 -\163\164\055\110\141\162\144\167\141\162\145\056\143\162\154\060 -\161\006\010\053\006\001\005\005\007\001\001\004\145\060\143\060 -\073\006\010\053\006\001\005\005\007\060\002\206\057\150\164\164 -\160\072\057\057\143\162\164\056\143\157\155\157\144\157\143\141 -\056\143\157\155\057\125\124\116\101\144\144\124\162\165\163\164 -\123\145\162\166\145\162\103\101\056\143\162\164\060\044\006\010 -\053\006\001\005\005\007\060\001\206\030\150\164\164\160\072\057 -\057\157\143\163\160\056\143\157\155\157\144\157\143\141\056\143 -\157\155\060\031\006\003\125\035\021\004\022\060\020\202\016\147 -\154\157\142\141\154\040\164\162\165\163\164\145\145\060\015\006 -\011\052\206\110\206\367\015\001\001\005\005\000\003\202\001\001 -\000\217\272\165\272\071\324\046\323\160\017\304\263\002\247\305 -\022\043\161\311\376\143\351\243\142\170\044\104\117\324\271\021 -\076\037\307\050\347\125\153\356\364\341\000\221\206\212\311\011 -\153\237\056\244\105\071\321\141\142\136\223\245\005\105\170\237 -\140\022\054\364\154\145\145\015\314\106\064\213\050\272\240\306 -\364\231\161\144\363\042\166\254\117\363\142\311\247\063\132\007 -\037\075\311\206\200\334\333\004\057\207\047\350\277\110\104\201 -\300\360\111\043\156\037\345\344\003\206\044\023\242\205\142\174 -\130\004\312\346\215\023\162\012\272\126\104\242\017\274\373\240 -\075\015\052\177\373\236\251\011\075\267\132\324\212\215\341\045 -\350\244\011\204\160\255\022\104\271\317\271\063\172\272\134\346 -\113\246\273\005\006\230\377\362\230\122\173\167\200\047\112\331 -\342\372\271\122\324\373\373\346\326\055\236\217\301\025\104\215 -\233\164\057\356\224\132\116\323\304\213\212\254\103\235\163\366 -\256\014\207\211\255\207\311\311\307\335\272\024\140\172\370\265 -\065\235\302\215\306\226\201\015\251\122\212\051\100\004\351\031 -\264 -END - -# Trust for Certificate "Bogus Global Trustee" -# Issuer: CN=UTN-USERFirst-Hardware,OU=http://www.usertrust.com,O=The USERTRUST Network,L=Salt Lake City,ST=UT,C=US -# Serial Number:00:d8:f3:5f:4e:b7:87:2b:2d:ab:06:92:e3:15:38:2f:b0 -# Subject: CN=global trustee,OU=PlatinumSSL,OU=Hosted by GTI Group Corporation,OU=Global Trustee,O=Global Trustee,STREET=Sea Village 10,L=Tampa,ST=Florida,postalCode=38477,C=US -# Not Valid Before: Tue Mar 15 00:00:00 2011 -# Not Valid After : Fri Mar 14 23:59:59 2014 -# Fingerprint (MD5): FE:0D:01:6E:71:CB:8C:D8:3F:0E:0C:CD:49:35:B8:57 -# Fingerprint (SHA1): 61:79:3F:CB:FA:4F:90:08:30:9B:BA:5F:F1:2D:2C:B2:9C:D4:15:1A -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 "Bogus Global Trustee" -CKA_CERT_SHA1_HASH MULTILINE_OCTAL -\141\171\077\313\372\117\220\010\060\233\272\137\361\055\054\262 -\234\324\025\032 -END -CKA_CERT_MD5_HASH MULTILINE_OCTAL -\376\015\001\156\161\313\214\330\077\016\014\315\111\065\270\127 -END -CKA_ISSUER MULTILINE_OCTAL -\060\201\227\061\013\060\011\006\003\125\004\006\023\002\125\123 -\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060 -\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153 -\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023 -\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116 -\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023 -\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162 -\164\162\165\163\164\056\143\157\155\061\037\060\035\006\003\125 -\004\003\023\026\125\124\116\055\125\123\105\122\106\151\162\163 -\164\055\110\141\162\144\167\141\162\145 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\021\000\330\363\137\116\267\207\053\055\253\006\222\343\025 -\070\057\260 -END -CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED -CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED -CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED -CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE - -# -# Certificate "Bogus GMail" -# -# Issuer: CN=UTN-USERFirst-Hardware,OU=http://www.usertrust.com,O=The USERTRUST Network,L=Salt Lake City,ST=UT,C=US -# Serial Number:04:7e:cb:e9:fc:a5:5f:7b:d0:9e:ae:36:e1:0c:ae:1e -# Subject: CN=mail.google.com,OU=PlatinumSSL,OU=Hosted by GTI Group Corporation,OU=Tech Dept.,O=Google Ltd.,STREET=Sea Village 10,L=English,ST=Florida,postalCode=38477,C=US -# Not Valid Before: Tue Mar 15 00:00:00 2011 -# Not Valid After : Fri Mar 14 23:59:59 2014 -# Fingerprint (MD5): 4C:77:1F:EB:CA:31:C1:29:98:E9:2C:10:B3:AF:49:1C -# Fingerprint (SHA1): 64:31:72:30:36:FD:26:DE:A5:02:79:2F:A5:95:92:24:93:03:0F:97 -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 "Bogus GMail" -CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 -CKA_SUBJECT MULTILINE_OCTAL -\060\201\337\061\013\060\011\006\003\125\004\006\023\002\125\123 -\061\016\060\014\006\003\125\004\021\023\005\063\070\064\067\067 -\061\020\060\016\006\003\125\004\010\023\007\106\154\157\162\151 -\144\141\061\020\060\016\006\003\125\004\007\023\007\105\156\147 -\154\151\163\150\061\027\060\025\006\003\125\004\011\023\016\123 -\145\141\040\126\151\154\154\141\147\145\040\061\060\061\024\060 -\022\006\003\125\004\012\023\013\107\157\157\147\154\145\040\114 -\164\144\056\061\023\060\021\006\003\125\004\013\023\012\124\145 -\143\150\040\104\145\160\164\056\061\050\060\046\006\003\125\004 -\013\023\037\110\157\163\164\145\144\040\142\171\040\107\124\111 -\040\107\162\157\165\160\040\103\157\162\160\157\162\141\164\151 -\157\156\061\024\060\022\006\003\125\004\013\023\013\120\154\141 -\164\151\156\165\155\123\123\114\061\030\060\026\006\003\125\004 -\003\023\017\155\141\151\154\056\147\157\157\147\154\145\056\143 -\157\155 -END -CKA_ID UTF8 "0" -CKA_ISSUER MULTILINE_OCTAL -\060\201\227\061\013\060\011\006\003\125\004\006\023\002\125\123 -\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060 -\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153 -\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023 -\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116 -\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023 -\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162 -\164\162\165\163\164\056\143\157\155\061\037\060\035\006\003\125 -\004\003\023\026\125\124\116\055\125\123\105\122\106\151\162\163 -\164\055\110\141\162\144\167\141\162\145 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\020\004\176\313\351\374\245\137\173\320\236\256\066\341\014 -\256\036 -END -CKA_VALUE MULTILINE_OCTAL -\060\202\005\356\060\202\004\326\240\003\002\001\002\002\020\004 -\176\313\351\374\245\137\173\320\236\256\066\341\014\256\036\060 -\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060\201 -\227\061\013\060\011\006\003\125\004\006\023\002\125\123\061\013 -\060\011\006\003\125\004\010\023\002\125\124\061\027\060\025\006 -\003\125\004\007\023\016\123\141\154\164\040\114\141\153\145\040 -\103\151\164\171\061\036\060\034\006\003\125\004\012\023\025\124 -\150\145\040\125\123\105\122\124\122\125\123\124\040\116\145\164 -\167\157\162\153\061\041\060\037\006\003\125\004\013\023\030\150 -\164\164\160\072\057\057\167\167\167\056\165\163\145\162\164\162 -\165\163\164\056\143\157\155\061\037\060\035\006\003\125\004\003 -\023\026\125\124\116\055\125\123\105\122\106\151\162\163\164\055 -\110\141\162\144\167\141\162\145\060\036\027\015\061\061\060\063 -\061\065\060\060\060\060\060\060\132\027\015\061\064\060\063\061 -\064\062\063\065\071\065\071\132\060\201\337\061\013\060\011\006 -\003\125\004\006\023\002\125\123\061\016\060\014\006\003\125\004 -\021\023\005\063\070\064\067\067\061\020\060\016\006\003\125\004 -\010\023\007\106\154\157\162\151\144\141\061\020\060\016\006\003 -\125\004\007\023\007\105\156\147\154\151\163\150\061\027\060\025 -\006\003\125\004\011\023\016\123\145\141\040\126\151\154\154\141 -\147\145\040\061\060\061\024\060\022\006\003\125\004\012\023\013 -\107\157\157\147\154\145\040\114\164\144\056\061\023\060\021\006 -\003\125\004\013\023\012\124\145\143\150\040\104\145\160\164\056 -\061\050\060\046\006\003\125\004\013\023\037\110\157\163\164\145 -\144\040\142\171\040\107\124\111\040\107\162\157\165\160\040\103 -\157\162\160\157\162\141\164\151\157\156\061\024\060\022\006\003 -\125\004\013\023\013\120\154\141\164\151\156\165\155\123\123\114 -\061\030\060\026\006\003\125\004\003\023\017\155\141\151\154\056 -\147\157\157\147\154\145\056\143\157\155\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\260\163\360\362\004 -\356\302\242\106\312\064\052\252\273\140\043\321\021\166\037\037 -\072\320\145\203\116\232\105\250\103\160\205\166\360\037\207\000 -\002\037\156\073\027\027\304\265\351\031\106\242\222\045\215\142 -\052\264\143\060\037\271\205\370\065\341\026\132\166\111\314\120 -\110\123\071\131\211\326\204\002\373\232\354\033\307\121\325\166 -\225\220\324\072\052\270\246\336\002\115\006\373\315\355\245\106 -\101\137\125\164\345\354\176\100\334\120\234\265\344\065\135\036 -\150\040\370\351\336\243\152\050\277\101\322\241\263\342\045\215 -\014\033\312\075\223\014\030\256\337\305\274\375\274\202\272\150 -\000\327\026\062\161\237\145\265\021\332\150\131\320\246\127\144 -\033\311\376\230\345\365\245\145\352\341\333\356\364\263\235\263 -\216\352\207\256\026\322\036\240\174\174\151\077\051\026\205\001 -\123\247\154\361\140\253\335\242\374\045\107\324\062\321\022\335 -\367\110\022\340\374\234\242\167\230\351\211\231\270\370\070\361 -\214\006\302\172\043\066\155\233\235\315\060\310\307\064\027\036 -\273\175\102\310\253\347\025\026\366\163\265\002\003\001\000\001 -\243\202\001\352\060\202\001\346\060\037\006\003\125\035\043\004 -\030\060\026\200\024\241\162\137\046\033\050\230\103\225\135\007 -\067\325\205\226\235\113\322\303\105\060\035\006\003\125\035\016 -\004\026\004\024\030\052\242\310\324\172\077\173\255\004\213\275 -\157\236\020\106\023\170\161\235\060\016\006\003\125\035\017\001 -\001\377\004\004\003\002\005\240\060\014\006\003\125\035\023\001 -\001\377\004\002\060\000\060\035\006\003\125\035\045\004\026\060 -\024\006\010\053\006\001\005\005\007\003\001\006\010\053\006\001 -\005\005\007\003\002\060\106\006\003\125\035\040\004\077\060\075 -\060\073\006\014\053\006\001\004\001\262\061\001\002\001\003\004 -\060\053\060\051\006\010\053\006\001\005\005\007\002\001\026\035 -\150\164\164\160\163\072\057\057\163\145\143\165\162\145\056\143 -\157\155\157\144\157\056\143\157\155\057\103\120\123\060\173\006 -\003\125\035\037\004\164\060\162\060\070\240\066\240\064\206\062 -\150\164\164\160\072\057\057\143\162\154\056\143\157\155\157\144 -\157\143\141\056\143\157\155\057\125\124\116\055\125\123\105\122 -\106\151\162\163\164\055\110\141\162\144\167\141\162\145\056\143 -\162\154\060\066\240\064\240\062\206\060\150\164\164\160\072\057 -\057\143\162\154\056\143\157\155\157\144\157\056\156\145\164\057 -\125\124\116\055\125\123\105\122\106\151\162\163\164\055\110\141 -\162\144\167\141\162\145\056\143\162\154\060\161\006\010\053\006 -\001\005\005\007\001\001\004\145\060\143\060\073\006\010\053\006 -\001\005\005\007\060\002\206\057\150\164\164\160\072\057\057\143 -\162\164\056\143\157\155\157\144\157\143\141\056\143\157\155\057 -\125\124\116\101\144\144\124\162\165\163\164\123\145\162\166\145 -\162\103\101\056\143\162\164\060\044\006\010\053\006\001\005\005 -\007\060\001\206\030\150\164\164\160\072\057\057\157\143\163\160 -\056\143\157\155\157\144\157\143\141\056\143\157\155\060\057\006 -\003\125\035\021\004\050\060\046\202\017\155\141\151\154\056\147 -\157\157\147\154\145\056\143\157\155\202\023\167\167\167\056\155 -\141\151\154\056\147\157\157\147\154\145\056\143\157\155\060\015 -\006\011\052\206\110\206\367\015\001\001\005\005\000\003\202\001 -\001\000\147\006\010\012\047\305\223\156\002\362\336\027\077\320 -\323\033\174\377\265\315\172\307\167\307\276\337\022\312\031\336 -\260\023\127\014\003\221\304\171\122\317\177\267\136\125\040\204 -\111\335\365\320\051\057\016\004\332\131\236\016\023\237\364\300 -\062\233\377\241\021\044\052\227\243\362\077\075\052\153\250\255 -\214\031\165\225\016\035\045\375\117\304\172\025\303\035\307\023 -\100\310\015\276\227\140\162\246\376\045\276\217\354\325\246\206 -\303\041\134\131\122\331\152\013\134\237\113\336\265\371\354\342 -\364\305\314\142\123\166\211\145\344\051\332\267\277\226\340\140 -\215\015\267\011\125\326\100\125\035\301\362\226\041\165\257\211 -\206\037\135\201\227\051\050\036\051\327\226\301\040\003\062\173 -\000\073\152\067\027\132\243\263\032\157\062\073\156\361\243\135 -\253\253\314\052\313\060\014\037\065\043\213\151\104\134\352\254 -\050\140\355\253\153\143\236\366\222\274\275\232\132\046\114\305 -\230\270\016\031\076\374\005\061\343\026\331\375\220\005\003\206 -\306\127\001\037\177\170\240\317\063\152\252\146\153\042\320\247 -\111\043 -END - -# Trust for Certificate "Bogus GMail" -# Issuer: CN=UTN-USERFirst-Hardware,OU=http://www.usertrust.com,O=The USERTRUST Network,L=Salt Lake City,ST=UT,C=US -# Serial Number:04:7e:cb:e9:fc:a5:5f:7b:d0:9e:ae:36:e1:0c:ae:1e -# Subject: CN=mail.google.com,OU=PlatinumSSL,OU=Hosted by GTI Group Corporation,OU=Tech Dept.,O=Google Ltd.,STREET=Sea Village 10,L=English,ST=Florida,postalCode=38477,C=US -# Not Valid Before: Tue Mar 15 00:00:00 2011 -# Not Valid After : Fri Mar 14 23:59:59 2014 -# Fingerprint (MD5): 4C:77:1F:EB:CA:31:C1:29:98:E9:2C:10:B3:AF:49:1C -# Fingerprint (SHA1): 64:31:72:30:36:FD:26:DE:A5:02:79:2F:A5:95:92:24:93:03:0F:97 -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 "Bogus GMail" -CKA_CERT_SHA1_HASH MULTILINE_OCTAL -\144\061\162\060\066\375\046\336\245\002\171\057\245\225\222\044 -\223\003\017\227 -END -CKA_CERT_MD5_HASH MULTILINE_OCTAL -\114\167\037\353\312\061\301\051\230\351\054\020\263\257\111\034 -END -CKA_ISSUER MULTILINE_OCTAL -\060\201\227\061\013\060\011\006\003\125\004\006\023\002\125\123 -\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060 -\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153 -\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023 -\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116 -\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023 -\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162 -\164\162\165\163\164\056\143\157\155\061\037\060\035\006\003\125 -\004\003\023\026\125\124\116\055\125\123\105\122\106\151\162\163 -\164\055\110\141\162\144\167\141\162\145 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\020\004\176\313\351\374\245\137\173\320\236\256\066\341\014 -\256\036 -END -CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED -CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED -CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED -CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE - -# -# Certificate "Bogus Google" -# -# Issuer: CN=UTN-USERFirst-Hardware,OU=http://www.usertrust.com,O=The USERTRUST Network,L=Salt Lake City,ST=UT,C=US -# Serial Number:00:f5:c8:6a:f3:61:62:f1:3a:64:f5:4f:6d:c9:58:7c:06 -# Subject: CN=www.google.com,OU=PlatinumSSL,OU=Hosted by GTI Group Corporation,OU=Tech Dept.,O=Google Ltd.,STREET=Sea Village 10,L=English,ST=Florida,postalCode=38477,C=US -# Not Valid Before: Tue Mar 15 00:00:00 2011 -# Not Valid After : Fri Mar 14 23:59:59 2014 -# Fingerprint (MD5): 01:73:A9:58:F0:BC:C9:BE:94:2B:1A:4C:98:24:E3:B8 -# Fingerprint (SHA1): 19:16:A2:AF:34:6D:39:9F:50:31:3C:39:32:00:F1:41:40:45:66:16 -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 "Bogus Google" -CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 -CKA_SUBJECT MULTILINE_OCTAL -\060\201\336\061\013\060\011\006\003\125\004\006\023\002\125\123 -\061\016\060\014\006\003\125\004\021\023\005\063\070\064\067\067 -\061\020\060\016\006\003\125\004\010\023\007\106\154\157\162\151 -\144\141\061\020\060\016\006\003\125\004\007\023\007\105\156\147 -\154\151\163\150\061\027\060\025\006\003\125\004\011\023\016\123 -\145\141\040\126\151\154\154\141\147\145\040\061\060\061\024\060 -\022\006\003\125\004\012\023\013\107\157\157\147\154\145\040\114 -\164\144\056\061\023\060\021\006\003\125\004\013\023\012\124\145 -\143\150\040\104\145\160\164\056\061\050\060\046\006\003\125\004 -\013\023\037\110\157\163\164\145\144\040\142\171\040\107\124\111 -\040\107\162\157\165\160\040\103\157\162\160\157\162\141\164\151 -\157\156\061\024\060\022\006\003\125\004\013\023\013\120\154\141 -\164\151\156\165\155\123\123\114\061\027\060\025\006\003\125\004 -\003\023\016\167\167\167\056\147\157\157\147\154\145\056\143\157 -\155 -END -CKA_ID UTF8 "0" -CKA_ISSUER MULTILINE_OCTAL -\060\201\227\061\013\060\011\006\003\125\004\006\023\002\125\123 -\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060 -\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153 -\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023 -\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116 -\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023 -\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162 -\164\162\165\163\164\056\143\157\155\061\037\060\035\006\003\125 -\004\003\023\026\125\124\116\055\125\123\105\122\106\151\162\163 -\164\055\110\141\162\144\167\141\162\145 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\021\000\365\310\152\363\141\142\361\072\144\365\117\155\311 -\130\174\006 -END -CKA_VALUE MULTILINE_OCTAL -\060\202\005\344\060\202\004\314\240\003\002\001\002\002\021\000 -\365\310\152\363\141\142\361\072\144\365\117\155\311\130\174\006 -\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060 -\201\227\061\013\060\011\006\003\125\004\006\023\002\125\123\061 -\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060\025 -\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153\145 -\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023\025 -\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116\145 -\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023\030 -\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162\164 -\162\165\163\164\056\143\157\155\061\037\060\035\006\003\125\004 -\003\023\026\125\124\116\055\125\123\105\122\106\151\162\163\164 -\055\110\141\162\144\167\141\162\145\060\036\027\015\061\061\060 -\063\061\065\060\060\060\060\060\060\132\027\015\061\064\060\063 -\061\064\062\063\065\071\065\071\132\060\201\336\061\013\060\011 -\006\003\125\004\006\023\002\125\123\061\016\060\014\006\003\125 -\004\021\023\005\063\070\064\067\067\061\020\060\016\006\003\125 -\004\010\023\007\106\154\157\162\151\144\141\061\020\060\016\006 -\003\125\004\007\023\007\105\156\147\154\151\163\150\061\027\060 -\025\006\003\125\004\011\023\016\123\145\141\040\126\151\154\154 -\141\147\145\040\061\060\061\024\060\022\006\003\125\004\012\023 -\013\107\157\157\147\154\145\040\114\164\144\056\061\023\060\021 -\006\003\125\004\013\023\012\124\145\143\150\040\104\145\160\164 -\056\061\050\060\046\006\003\125\004\013\023\037\110\157\163\164 -\145\144\040\142\171\040\107\124\111\040\107\162\157\165\160\040 -\103\157\162\160\157\162\141\164\151\157\156\061\024\060\022\006 -\003\125\004\013\023\013\120\154\141\164\151\156\165\155\123\123 -\114\061\027\060\025\006\003\125\004\003\023\016\167\167\167\056 -\147\157\157\147\154\145\056\143\157\155\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\260\163\360\362\004 -\356\302\242\106\312\064\052\252\273\140\043\321\021\166\037\037 -\072\320\145\203\116\232\105\250\103\160\205\166\360\037\207\000 -\002\037\156\073\027\027\304\265\351\031\106\242\222\045\215\142 -\052\264\143\060\037\271\205\370\065\341\026\132\166\111\314\120 -\110\123\071\131\211\326\204\002\373\232\354\033\307\121\325\166 -\225\220\324\072\052\270\246\336\002\115\006\373\315\355\245\106 -\101\137\125\164\345\354\176\100\334\120\234\265\344\065\135\036 -\150\040\370\351\336\243\152\050\277\101\322\241\263\342\045\215 -\014\033\312\075\223\014\030\256\337\305\274\375\274\202\272\150 -\000\327\026\062\161\237\145\265\021\332\150\131\320\246\127\144 -\033\311\376\230\345\365\245\145\352\341\333\356\364\263\235\263 -\216\352\207\256\026\322\036\240\174\174\151\077\051\026\205\001 -\123\247\154\361\140\253\335\242\374\045\107\324\062\321\022\335 -\367\110\022\340\374\234\242\167\230\351\211\231\270\370\070\361 -\214\006\302\172\043\066\155\233\235\315\060\310\307\064\027\036 -\273\175\102\310\253\347\025\026\366\163\265\002\003\001\000\001 -\243\202\001\340\060\202\001\334\060\037\006\003\125\035\043\004 -\030\060\026\200\024\241\162\137\046\033\050\230\103\225\135\007 -\067\325\205\226\235\113\322\303\105\060\035\006\003\125\035\016 -\004\026\004\024\030\052\242\310\324\172\077\173\255\004\213\275 -\157\236\020\106\023\170\161\235\060\016\006\003\125\035\017\001 -\001\377\004\004\003\002\005\240\060\014\006\003\125\035\023\001 -\001\377\004\002\060\000\060\035\006\003\125\035\045\004\026\060 -\024\006\010\053\006\001\005\005\007\003\001\006\010\053\006\001 -\005\005\007\003\002\060\106\006\003\125\035\040\004\077\060\075 -\060\073\006\014\053\006\001\004\001\262\061\001\002\001\003\004 -\060\053\060\051\006\010\053\006\001\005\005\007\002\001\026\035 -\150\164\164\160\163\072\057\057\163\145\143\165\162\145\056\143 -\157\155\157\144\157\056\143\157\155\057\103\120\123\060\173\006 -\003\125\035\037\004\164\060\162\060\070\240\066\240\064\206\062 -\150\164\164\160\072\057\057\143\162\154\056\143\157\155\157\144 -\157\143\141\056\143\157\155\057\125\124\116\055\125\123\105\122 -\106\151\162\163\164\055\110\141\162\144\167\141\162\145\056\143 -\162\154\060\066\240\064\240\062\206\060\150\164\164\160\072\057 -\057\143\162\154\056\143\157\155\157\144\157\056\156\145\164\057 -\125\124\116\055\125\123\105\122\106\151\162\163\164\055\110\141 -\162\144\167\141\162\145\056\143\162\154\060\161\006\010\053\006 -\001\005\005\007\001\001\004\145\060\143\060\073\006\010\053\006 -\001\005\005\007\060\002\206\057\150\164\164\160\072\057\057\143 -\162\164\056\143\157\155\157\144\157\143\141\056\143\157\155\057 -\125\124\116\101\144\144\124\162\165\163\164\123\145\162\166\145 -\162\103\101\056\143\162\164\060\044\006\010\053\006\001\005\005 -\007\060\001\206\030\150\164\164\160\072\057\057\157\143\163\160 -\056\143\157\155\157\144\157\143\141\056\143\157\155\060\045\006 -\003\125\035\021\004\036\060\034\202\016\167\167\167\056\147\157 -\157\147\154\145\056\143\157\155\202\012\147\157\157\147\154\145 -\056\143\157\155\060\015\006\011\052\206\110\206\367\015\001\001 -\005\005\000\003\202\001\001\000\161\300\231\077\136\366\275\063 -\377\236\026\313\250\277\335\160\371\322\123\073\066\256\311\027 -\310\256\136\115\335\142\367\267\323\076\167\243\376\300\173\062 -\265\311\224\005\122\120\362\137\075\171\204\111\117\135\154\260 -\327\131\275\324\154\210\372\374\305\145\206\353\050\122\242\102 -\366\174\274\152\307\007\056\045\321\220\142\040\306\215\121\302 -\054\105\071\116\003\332\367\030\350\314\012\072\331\105\330\154 -\156\064\213\142\234\116\025\371\103\356\345\227\300\077\255\065 -\023\305\053\006\307\101\375\342\367\176\105\255\233\321\341\146 -\355\370\172\113\224\071\172\057\353\350\077\103\330\065\326\126 -\372\164\347\155\346\355\254\145\204\376\320\115\006\022\336\332 -\131\000\074\011\134\317\210\113\350\075\264\025\041\222\314\155 -\246\121\342\216\227\361\364\202\106\313\304\123\136\332\134\235 -\145\222\001\145\211\000\345\266\231\377\046\100\361\057\031\061 -\010\032\261\147\125\206\015\256\065\063\206\274\227\110\222\327 -\226\140\370\316\374\226\353\207\304\163\314\224\233\130\133\363 -\172\244\047\023\326\117\364\151 -END - -# Trust for Certificate "Bogus Google" -# Issuer: CN=UTN-USERFirst-Hardware,OU=http://www.usertrust.com,O=The USERTRUST Network,L=Salt Lake City,ST=UT,C=US -# Serial Number:00:f5:c8:6a:f3:61:62:f1:3a:64:f5:4f:6d:c9:58:7c:06 -# Subject: CN=www.google.com,OU=PlatinumSSL,OU=Hosted by GTI Group Corporation,OU=Tech Dept.,O=Google Ltd.,STREET=Sea Village 10,L=English,ST=Florida,postalCode=38477,C=US -# Not Valid Before: Tue Mar 15 00:00:00 2011 -# Not Valid After : Fri Mar 14 23:59:59 2014 -# Fingerprint (MD5): 01:73:A9:58:F0:BC:C9:BE:94:2B:1A:4C:98:24:E3:B8 -# Fingerprint (SHA1): 19:16:A2:AF:34:6D:39:9F:50:31:3C:39:32:00:F1:41:40:45:66:16 -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 "Bogus Google" -CKA_CERT_SHA1_HASH MULTILINE_OCTAL -\031\026\242\257\064\155\071\237\120\061\074\071\062\000\361\101 -\100\105\146\026 -END -CKA_CERT_MD5_HASH MULTILINE_OCTAL -\001\163\251\130\360\274\311\276\224\053\032\114\230\044\343\270 -END -CKA_ISSUER MULTILINE_OCTAL -\060\201\227\061\013\060\011\006\003\125\004\006\023\002\125\123 -\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060 -\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153 -\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023 -\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116 -\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023 -\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162 -\164\162\165\163\164\056\143\157\155\061\037\060\035\006\003\125 -\004\003\023\026\125\124\116\055\125\123\105\122\106\151\162\163 -\164\055\110\141\162\144\167\141\162\145 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\021\000\365\310\152\363\141\142\361\072\144\365\117\155\311 -\130\174\006 -END -CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED -CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED -CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED -CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE - -# -# Certificate "Bogus Skype" -# -# Issuer: CN=UTN-USERFirst-Hardware,OU=http://www.usertrust.com,O=The USERTRUST Network,L=Salt Lake City,ST=UT,C=US -# Serial Number:00:e9:02:8b:95:78:e4:15:dc:1a:71:0a:2b:88:15:44:47 -# Subject: CN=login.skype.com,OU=PlatinumSSL,OU=Hosted by GTI Group Corporation,OU=Tech Dept.,O=Google Ltd.,STREET=Sea Village 10,L=English,ST=Florida,postalCode=38477,C=US -# Not Valid Before: Tue Mar 15 00:00:00 2011 -# Not Valid After : Fri Mar 14 23:59:59 2014 -# Fingerprint (MD5): 85:A4:B4:C4:69:21:DF:A1:6A:0D:58:56:58:4B:33:44 -# Fingerprint (SHA1): 47:1C:94:9A:81:43:DB:5A:D5:CD:F1:C9:72:86:4A:25:04:FA:23:C9 -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 "Bogus Skype" -CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 -CKA_SUBJECT MULTILINE_OCTAL -\060\201\337\061\013\060\011\006\003\125\004\006\023\002\125\123 -\061\016\060\014\006\003\125\004\021\023\005\063\070\064\067\067 -\061\020\060\016\006\003\125\004\010\023\007\106\154\157\162\151 -\144\141\061\020\060\016\006\003\125\004\007\023\007\105\156\147 -\154\151\163\150\061\027\060\025\006\003\125\004\011\023\016\123 -\145\141\040\126\151\154\154\141\147\145\040\061\060\061\024\060 -\022\006\003\125\004\012\023\013\107\157\157\147\154\145\040\114 -\164\144\056\061\023\060\021\006\003\125\004\013\023\012\124\145 -\143\150\040\104\145\160\164\056\061\050\060\046\006\003\125\004 -\013\023\037\110\157\163\164\145\144\040\142\171\040\107\124\111 -\040\107\162\157\165\160\040\103\157\162\160\157\162\141\164\151 -\157\156\061\024\060\022\006\003\125\004\013\023\013\120\154\141 -\164\151\156\165\155\123\123\114\061\030\060\026\006\003\125\004 -\003\023\017\154\157\147\151\156\056\163\153\171\160\145\056\143 -\157\155 -END -CKA_ID UTF8 "0" -CKA_ISSUER MULTILINE_OCTAL -\060\201\227\061\013\060\011\006\003\125\004\006\023\002\125\123 -\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060 -\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153 -\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023 -\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116 -\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023 -\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162 -\164\162\165\163\164\056\143\157\155\061\037\060\035\006\003\125 -\004\003\023\026\125\124\116\055\125\123\105\122\106\151\162\163 -\164\055\110\141\162\144\167\141\162\145 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\021\000\351\002\213\225\170\344\025\334\032\161\012\053\210 -\025\104\107 -END -CKA_VALUE MULTILINE_OCTAL -\060\202\005\357\060\202\004\327\240\003\002\001\002\002\021\000 -\351\002\213\225\170\344\025\334\032\161\012\053\210\025\104\107 -\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060 -\201\227\061\013\060\011\006\003\125\004\006\023\002\125\123\061 -\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060\025 -\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153\145 -\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023\025 -\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116\145 -\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023\030 -\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162\164 -\162\165\163\164\056\143\157\155\061\037\060\035\006\003\125\004 -\003\023\026\125\124\116\055\125\123\105\122\106\151\162\163\164 -\055\110\141\162\144\167\141\162\145\060\036\027\015\061\061\060 -\063\061\065\060\060\060\060\060\060\132\027\015\061\064\060\063 -\061\064\062\063\065\071\065\071\132\060\201\337\061\013\060\011 -\006\003\125\004\006\023\002\125\123\061\016\060\014\006\003\125 -\004\021\023\005\063\070\064\067\067\061\020\060\016\006\003\125 -\004\010\023\007\106\154\157\162\151\144\141\061\020\060\016\006 -\003\125\004\007\023\007\105\156\147\154\151\163\150\061\027\060 -\025\006\003\125\004\011\023\016\123\145\141\040\126\151\154\154 -\141\147\145\040\061\060\061\024\060\022\006\003\125\004\012\023 -\013\107\157\157\147\154\145\040\114\164\144\056\061\023\060\021 -\006\003\125\004\013\023\012\124\145\143\150\040\104\145\160\164 -\056\061\050\060\046\006\003\125\004\013\023\037\110\157\163\164 -\145\144\040\142\171\040\107\124\111\040\107\162\157\165\160\040 -\103\157\162\160\157\162\141\164\151\157\156\061\024\060\022\006 -\003\125\004\013\023\013\120\154\141\164\151\156\165\155\123\123 -\114\061\030\060\026\006\003\125\004\003\023\017\154\157\147\151 -\156\056\163\153\171\160\145\056\143\157\155\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\260\170\231\206 -\016\242\163\043\324\132\303\111\353\261\066\214\174\312\204\256 -\074\257\070\210\050\231\215\055\130\023\261\227\170\076\122\040 -\147\254\133\163\230\154\062\125\311\160\321\331\252\025\350\056 -\046\205\201\274\126\344\274\200\143\333\116\327\365\002\276\121 -\143\036\074\333\337\327\000\135\132\271\345\173\152\352\070\040 -\262\073\266\356\165\124\204\371\246\312\070\160\335\277\260\377 -\245\205\135\264\101\376\335\075\331\052\341\060\103\032\230\171 -\223\240\137\340\147\154\225\372\076\172\256\161\173\343\155\210 -\102\077\045\324\356\276\150\150\254\255\254\140\340\040\243\071 -\203\271\133\050\243\223\155\241\275\166\012\343\353\256\207\047 -\016\124\217\264\110\014\232\124\364\135\216\067\120\334\136\244 -\213\153\113\334\246\363\064\276\167\131\042\210\377\031\053\155 -\166\144\163\332\014\207\007\053\232\067\072\320\342\214\366\066 -\062\153\232\171\314\322\073\223\157\032\115\154\346\301\235\100 -\254\055\164\303\276\352\134\163\145\001\051\261\052\277\160\131 -\301\316\306\303\242\310\105\137\272\147\075\017\002\003\001\000 -\001\243\202\001\352\060\202\001\346\060\037\006\003\125\035\043 -\004\030\060\026\200\024\241\162\137\046\033\050\230\103\225\135 -\007\067\325\205\226\235\113\322\303\105\060\035\006\003\125\035 -\016\004\026\004\024\325\216\132\121\023\264\051\015\061\266\034 -\215\076\121\121\061\012\063\252\201\060\016\006\003\125\035\017 -\001\001\377\004\004\003\002\005\240\060\014\006\003\125\035\023 -\001\001\377\004\002\060\000\060\035\006\003\125\035\045\004\026 -\060\024\006\010\053\006\001\005\005\007\003\001\006\010\053\006 -\001\005\005\007\003\002\060\106\006\003\125\035\040\004\077\060 -\075\060\073\006\014\053\006\001\004\001\262\061\001\002\001\003 -\004\060\053\060\051\006\010\053\006\001\005\005\007\002\001\026 -\035\150\164\164\160\163\072\057\057\163\145\143\165\162\145\056 -\143\157\155\157\144\157\056\143\157\155\057\103\120\123\060\173 -\006\003\125\035\037\004\164\060\162\060\070\240\066\240\064\206 -\062\150\164\164\160\072\057\057\143\162\154\056\143\157\155\157 -\144\157\143\141\056\143\157\155\057\125\124\116\055\125\123\105 -\122\106\151\162\163\164\055\110\141\162\144\167\141\162\145\056 -\143\162\154\060\066\240\064\240\062\206\060\150\164\164\160\072 -\057\057\143\162\154\056\143\157\155\157\144\157\056\156\145\164 -\057\125\124\116\055\125\123\105\122\106\151\162\163\164\055\110 -\141\162\144\167\141\162\145\056\143\162\154\060\161\006\010\053 -\006\001\005\005\007\001\001\004\145\060\143\060\073\006\010\053 -\006\001\005\005\007\060\002\206\057\150\164\164\160\072\057\057 -\143\162\164\056\143\157\155\157\144\157\143\141\056\143\157\155 -\057\125\124\116\101\144\144\124\162\165\163\164\123\145\162\166 -\145\162\103\101\056\143\162\164\060\044\006\010\053\006\001\005 -\005\007\060\001\206\030\150\164\164\160\072\057\057\157\143\163 -\160\056\143\157\155\157\144\157\143\141\056\143\157\155\060\057 -\006\003\125\035\021\004\050\060\046\202\017\154\157\147\151\156 -\056\163\153\171\160\145\056\143\157\155\202\023\167\167\167\056 -\154\157\147\151\156\056\163\153\171\160\145\056\143\157\155\060 -\015\006\011\052\206\110\206\367\015\001\001\005\005\000\003\202 -\001\001\000\010\362\201\165\221\273\316\022\004\030\302\115\132 -\373\106\220\012\124\104\364\362\335\007\201\360\037\246\172\157 -\237\317\270\016\054\117\234\304\232\365\250\366\272\244\311\172 -\135\261\342\132\312\074\372\140\250\150\076\313\272\055\342\315 -\326\266\344\222\074\151\255\127\352\250\057\070\020\204\162\345 -\150\161\355\276\353\156\030\357\143\172\276\347\044\377\300\143 -\375\130\073\114\201\222\330\051\253\216\065\135\327\323\011\153 -\205\323\325\163\005\104\342\345\273\203\123\020\313\362\317\267 -\156\341\151\267\241\222\144\305\317\315\202\273\066\240\070\255 -\327\044\337\123\374\077\142\267\267\325\307\127\343\223\061\160 -\216\044\211\206\312\143\053\071\272\135\331\152\140\354\241\116 -\212\376\123\370\136\222\337\057\134\046\027\155\003\175\002\017 -\017\252\103\147\155\260\142\277\176\123\335\314\354\170\163\225 -\345\245\366\000\243\004\375\077\004\052\263\230\305\267\003\034 -\333\311\120\253\260\005\035\036\276\126\264\317\076\102\023\224 -\236\371\347\001\201\245\170\157\014\172\166\254\005\206\354\254 -\302\021\254 -END - -# Trust for Certificate "Bogus Skype" -# Issuer: CN=UTN-USERFirst-Hardware,OU=http://www.usertrust.com,O=The USERTRUST Network,L=Salt Lake City,ST=UT,C=US -# Serial Number:00:e9:02:8b:95:78:e4:15:dc:1a:71:0a:2b:88:15:44:47 -# Subject: CN=login.skype.com,OU=PlatinumSSL,OU=Hosted by GTI Group Corporation,OU=Tech Dept.,O=Google Ltd.,STREET=Sea Village 10,L=English,ST=Florida,postalCode=38477,C=US -# Not Valid Before: Tue Mar 15 00:00:00 2011 -# Not Valid After : Fri Mar 14 23:59:59 2014 -# Fingerprint (MD5): 85:A4:B4:C4:69:21:DF:A1:6A:0D:58:56:58:4B:33:44 -# Fingerprint (SHA1): 47:1C:94:9A:81:43:DB:5A:D5:CD:F1:C9:72:86:4A:25:04:FA:23:C9 -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 "Bogus Skype" -CKA_CERT_SHA1_HASH MULTILINE_OCTAL -\107\034\224\232\201\103\333\132\325\315\361\311\162\206\112\045 -\004\372\043\311 -END -CKA_CERT_MD5_HASH MULTILINE_OCTAL -\205\244\264\304\151\041\337\241\152\015\130\126\130\113\063\104 -END -CKA_ISSUER MULTILINE_OCTAL -\060\201\227\061\013\060\011\006\003\125\004\006\023\002\125\123 -\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060 -\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153 -\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023 -\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116 -\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023 -\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162 -\164\162\165\163\164\056\143\157\155\061\037\060\035\006\003\125 -\004\003\023\026\125\124\116\055\125\123\105\122\106\151\162\163 -\164\055\110\141\162\144\167\141\162\145 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\021\000\351\002\213\225\170\344\025\334\032\161\012\053\210 -\025\104\107 -END -CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED -CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED -CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED -CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE - -# -# Certificate "Bogus Yahoo 1" -# -# Issuer: CN=UTN-USERFirst-Hardware,OU=http://www.usertrust.com,O=The USERTRUST Network,L=Salt Lake City,ST=UT,C=US -# Serial Number:00:d7:55:8f:da:f5:f1:10:5b:b2:13:28:2b:70:77:29:a3 -# Subject: CN=login.yahoo.com,OU=PlatinumSSL,OU=Hosted by GTI Group Corporation,OU=Tech Dept.,O=Google Ltd.,STREET=Sea Village 10,L=English,ST=Florida,postalCode=38477,C=US -# Not Valid Before: Tue Mar 15 00:00:00 2011 -# Not Valid After : Fri Mar 14 23:59:59 2014 -# Fingerprint (MD5): 0C:1F:BE:D3:FC:09:6E:E6:6E:C2:66:39:75:86:6B:EB -# Fingerprint (SHA1): 63:FE:AE:96:0B:AA:91:E3:43:CE:2B:D8:B7:17:98:C7:6B:DB:77:D0 -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 "Bogus Yahoo 1" -CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 -CKA_SUBJECT MULTILINE_OCTAL -\060\201\337\061\013\060\011\006\003\125\004\006\023\002\125\123 -\061\016\060\014\006\003\125\004\021\023\005\063\070\064\067\067 -\061\020\060\016\006\003\125\004\010\023\007\106\154\157\162\151 -\144\141\061\020\060\016\006\003\125\004\007\023\007\105\156\147 -\154\151\163\150\061\027\060\025\006\003\125\004\011\023\016\123 -\145\141\040\126\151\154\154\141\147\145\040\061\060\061\024\060 -\022\006\003\125\004\012\023\013\107\157\157\147\154\145\040\114 -\164\144\056\061\023\060\021\006\003\125\004\013\023\012\124\145 -\143\150\040\104\145\160\164\056\061\050\060\046\006\003\125\004 -\013\023\037\110\157\163\164\145\144\040\142\171\040\107\124\111 -\040\107\162\157\165\160\040\103\157\162\160\157\162\141\164\151 -\157\156\061\024\060\022\006\003\125\004\013\023\013\120\154\141 -\164\151\156\165\155\123\123\114\061\030\060\026\006\003\125\004 -\003\023\017\154\157\147\151\156\056\171\141\150\157\157\056\143 -\157\155 -END -CKA_ID UTF8 "0" -CKA_ISSUER MULTILINE_OCTAL -\060\201\227\061\013\060\011\006\003\125\004\006\023\002\125\123 -\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060 -\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153 -\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023 -\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116 -\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023 -\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162 -\164\162\165\163\164\056\143\157\155\061\037\060\035\006\003\125 -\004\003\023\026\125\124\116\055\125\123\105\122\106\151\162\163 -\164\055\110\141\162\144\167\141\162\145 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\021\000\327\125\217\332\365\361\020\133\262\023\050\053\160 -\167\051\243 -END -CKA_VALUE MULTILINE_OCTAL -\060\202\005\357\060\202\004\327\240\003\002\001\002\002\021\000 -\327\125\217\332\365\361\020\133\262\023\050\053\160\167\051\243 -\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060 -\201\227\061\013\060\011\006\003\125\004\006\023\002\125\123\061 -\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060\025 -\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153\145 -\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023\025 -\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116\145 -\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023\030 -\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162\164 -\162\165\163\164\056\143\157\155\061\037\060\035\006\003\125\004 -\003\023\026\125\124\116\055\125\123\105\122\106\151\162\163\164 -\055\110\141\162\144\167\141\162\145\060\036\027\015\061\061\060 -\063\061\065\060\060\060\060\060\060\132\027\015\061\064\060\063 -\061\064\062\063\065\071\065\071\132\060\201\337\061\013\060\011 -\006\003\125\004\006\023\002\125\123\061\016\060\014\006\003\125 -\004\021\023\005\063\070\064\067\067\061\020\060\016\006\003\125 -\004\010\023\007\106\154\157\162\151\144\141\061\020\060\016\006 -\003\125\004\007\023\007\105\156\147\154\151\163\150\061\027\060 -\025\006\003\125\004\011\023\016\123\145\141\040\126\151\154\154 -\141\147\145\040\061\060\061\024\060\022\006\003\125\004\012\023 -\013\107\157\157\147\154\145\040\114\164\144\056\061\023\060\021 -\006\003\125\004\013\023\012\124\145\143\150\040\104\145\160\164 -\056\061\050\060\046\006\003\125\004\013\023\037\110\157\163\164 -\145\144\040\142\171\040\107\124\111\040\107\162\157\165\160\040 -\103\157\162\160\157\162\141\164\151\157\156\061\024\060\022\006 -\003\125\004\013\023\013\120\154\141\164\151\156\165\155\123\123 -\114\061\030\060\026\006\003\125\004\003\023\017\154\157\147\151 -\156\056\171\141\150\157\157\056\143\157\155\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\241\244\005\075 -\355\205\105\223\212\030\115\306\003\000\127\342\100\167\360\034 -\353\320\031\337\042\135\010\177\321\007\074\101\211\106\027\243 -\011\372\374\370\251\004\321\226\217\253\327\117\074\371\255\030 -\251\164\201\304\127\012\072\046\026\316\142\076\274\077\154\041 -\356\223\215\313\015\240\037\232\226\320\217\255\365\223\223\202 -\356\162\014\241\165\025\243\173\204\126\270\255\377\122\021\161 -\204\274\072\060\013\176\230\250\341\250\077\067\122\320\361\174 -\157\220\330\105\012\254\071\162\152\141\325\273\303\214\371\302 -\314\337\375\072\161\271\257\274\334\072\334\014\266\261\322\321 -\211\273\101\266\362\336\127\325\025\337\374\375\342\061\305\337 -\312\301\330\217\054\277\360\016\133\161\340\064\161\303\305\115 -\175\172\324\372\355\060\113\057\352\266\056\236\223\074\342\072 -\370\102\242\032\356\334\337\315\017\251\366\171\204\032\216\154 -\002\266\206\345\277\121\152\146\370\363\234\323\131\014\173\245 -\231\170\315\174\231\372\306\226\107\330\062\324\164\166\016\167 -\113\040\164\244\267\211\165\222\112\264\133\125\002\003\001\000 -\001\243\202\001\352\060\202\001\346\060\037\006\003\125\035\043 -\004\030\060\026\200\024\241\162\137\046\033\050\230\103\225\135 -\007\067\325\205\226\235\113\322\303\105\060\035\006\003\125\035 -\016\004\026\004\024\206\111\105\374\063\031\063\324\004\355\047 -\141\356\350\001\311\014\177\057\176\060\016\006\003\125\035\017 -\001\001\377\004\004\003\002\005\240\060\014\006\003\125\035\023 -\001\001\377\004\002\060\000\060\035\006\003\125\035\045\004\026 -\060\024\006\010\053\006\001\005\005\007\003\001\006\010\053\006 -\001\005\005\007\003\002\060\106\006\003\125\035\040\004\077\060 -\075\060\073\006\014\053\006\001\004\001\262\061\001\002\001\003 -\004\060\053\060\051\006\010\053\006\001\005\005\007\002\001\026 -\035\150\164\164\160\163\072\057\057\163\145\143\165\162\145\056 -\143\157\155\157\144\157\056\143\157\155\057\103\120\123\060\173 -\006\003\125\035\037\004\164\060\162\060\070\240\066\240\064\206 -\062\150\164\164\160\072\057\057\143\162\154\056\143\157\155\157 -\144\157\143\141\056\143\157\155\057\125\124\116\055\125\123\105 -\122\106\151\162\163\164\055\110\141\162\144\167\141\162\145\056 -\143\162\154\060\066\240\064\240\062\206\060\150\164\164\160\072 -\057\057\143\162\154\056\143\157\155\157\144\157\056\156\145\164 -\057\125\124\116\055\125\123\105\122\106\151\162\163\164\055\110 -\141\162\144\167\141\162\145\056\143\162\154\060\161\006\010\053 -\006\001\005\005\007\001\001\004\145\060\143\060\073\006\010\053 -\006\001\005\005\007\060\002\206\057\150\164\164\160\072\057\057 -\143\162\164\056\143\157\155\157\144\157\143\141\056\143\157\155 -\057\125\124\116\101\144\144\124\162\165\163\164\123\145\162\166 -\145\162\103\101\056\143\162\164\060\044\006\010\053\006\001\005 -\005\007\060\001\206\030\150\164\164\160\072\057\057\157\143\163 -\160\056\143\157\155\157\144\157\143\141\056\143\157\155\060\057 -\006\003\125\035\021\004\050\060\046\202\017\154\157\147\151\156 -\056\171\141\150\157\157\056\143\157\155\202\023\167\167\167\056 -\154\157\147\151\156\056\171\141\150\157\157\056\143\157\155\060 -\015\006\011\052\206\110\206\367\015\001\001\005\005\000\003\202 -\001\001\000\075\127\311\110\044\134\356\144\201\365\256\276\125 -\051\026\377\052\057\204\355\331\370\243\003\310\060\146\273\310 -\324\201\055\041\367\010\367\254\226\102\232\101\165\172\272\135 -\020\043\313\222\102\141\372\212\332\155\145\064\031\345\251\326 -\055\023\170\327\201\104\222\251\156\200\143\025\313\376\065\037 -\002\321\212\024\260\250\314\224\040\073\250\032\360\135\066\120 -\333\015\256\351\144\344\366\215\151\175\060\310\024\027\000\112 -\345\246\065\373\175\015\042\235\171\166\122\054\274\227\006\210 -\232\025\364\163\346\361\365\230\245\315\007\104\221\270\247\150 -\147\105\322\162\021\140\342\161\267\120\125\342\212\251\015\326 -\222\356\004\052\213\060\240\242\005\106\064\155\222\306\073\252 -\115\240\320\253\001\031\012\062\267\350\343\317\361\322\227\111 -\173\254\244\227\367\360\127\256\143\167\232\177\226\332\115\375 -\276\334\007\066\343\045\275\211\171\216\051\022\023\213\210\007 -\373\153\333\244\315\263\055\047\351\324\312\140\327\205\123\373 -\164\306\134\065\214\160\037\371\262\267\222\047\040\307\224\325 -\147\024\060 -END - -# Trust for Certificate "Bogus Yahoo 1" -# Issuer: CN=UTN-USERFirst-Hardware,OU=http://www.usertrust.com,O=The USERTRUST Network,L=Salt Lake City,ST=UT,C=US -# Serial Number:00:d7:55:8f:da:f5:f1:10:5b:b2:13:28:2b:70:77:29:a3 -# Subject: CN=login.yahoo.com,OU=PlatinumSSL,OU=Hosted by GTI Group Corporation,OU=Tech Dept.,O=Google Ltd.,STREET=Sea Village 10,L=English,ST=Florida,postalCode=38477,C=US -# Not Valid Before: Tue Mar 15 00:00:00 2011 -# Not Valid After : Fri Mar 14 23:59:59 2014 -# Fingerprint (MD5): 0C:1F:BE:D3:FC:09:6E:E6:6E:C2:66:39:75:86:6B:EB -# Fingerprint (SHA1): 63:FE:AE:96:0B:AA:91:E3:43:CE:2B:D8:B7:17:98:C7:6B:DB:77:D0 -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 "Bogus Yahoo 1" -CKA_CERT_SHA1_HASH MULTILINE_OCTAL -\143\376\256\226\013\252\221\343\103\316\053\330\267\027\230\307 -\153\333\167\320 -END -CKA_CERT_MD5_HASH MULTILINE_OCTAL -\014\037\276\323\374\011\156\346\156\302\146\071\165\206\153\353 -END -CKA_ISSUER MULTILINE_OCTAL -\060\201\227\061\013\060\011\006\003\125\004\006\023\002\125\123 -\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060 -\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153 -\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023 -\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116 -\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023 -\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162 -\164\162\165\163\164\056\143\157\155\061\037\060\035\006\003\125 -\004\003\023\026\125\124\116\055\125\123\105\122\106\151\162\163 -\164\055\110\141\162\144\167\141\162\145 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\021\000\327\125\217\332\365\361\020\133\262\023\050\053\160 -\167\051\243 -END -CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED -CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED -CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED -CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE - -# -# Certificate "Bogus Yahoo 2" -# -# Issuer: CN=UTN-USERFirst-Hardware,OU=http://www.usertrust.com,O=The USERTRUST Network,L=Salt Lake City,ST=UT,C=US -# Serial Number:39:2a:43:4f:0e:07:df:1f:8a:a3:05:de:34:e0:c2:29 -# Subject: CN=login.yahoo.com,OU=PlatinumSSL,OU=Hosted by GTI Group Corporation,OU=Tech Dept.,O=Google Ltd.,STREET=Sea Village 10,L=English,ST=Florida,postalCode=38477,C=US -# Not Valid Before: Tue Mar 15 00:00:00 2011 -# Not Valid After : Fri Mar 14 23:59:59 2014 -# Fingerprint (MD5): 72:DC:C8:72:6C:53:3B:B2:FD:CC:5D:19:BD:AF:A6:31 -# Fingerprint (SHA1): D0:18:B6:2D:C5:18:90:72:47:DF:50:92:5B:B0:9A:CF:4A:5C:B3:AD -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 "Bogus Yahoo 2" -CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 -CKA_SUBJECT MULTILINE_OCTAL -\060\201\337\061\013\060\011\006\003\125\004\006\023\002\125\123 -\061\016\060\014\006\003\125\004\021\023\005\063\070\064\067\067 -\061\020\060\016\006\003\125\004\010\023\007\106\154\157\162\151 -\144\141\061\020\060\016\006\003\125\004\007\023\007\105\156\147 -\154\151\163\150\061\027\060\025\006\003\125\004\011\023\016\123 -\145\141\040\126\151\154\154\141\147\145\040\061\060\061\024\060 -\022\006\003\125\004\012\023\013\107\157\157\147\154\145\040\114 -\164\144\056\061\023\060\021\006\003\125\004\013\023\012\124\145 -\143\150\040\104\145\160\164\056\061\050\060\046\006\003\125\004 -\013\023\037\110\157\163\164\145\144\040\142\171\040\107\124\111 -\040\107\162\157\165\160\040\103\157\162\160\157\162\141\164\151 -\157\156\061\024\060\022\006\003\125\004\013\023\013\120\154\141 -\164\151\156\165\155\123\123\114\061\030\060\026\006\003\125\004 -\003\023\017\154\157\147\151\156\056\171\141\150\157\157\056\143 -\157\155 -END -CKA_ID UTF8 "0" -CKA_ISSUER MULTILINE_OCTAL -\060\201\227\061\013\060\011\006\003\125\004\006\023\002\125\123 -\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060 -\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153 -\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023 -\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116 -\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023 -\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162 -\164\162\165\163\164\056\143\157\155\061\037\060\035\006\003\125 -\004\003\023\026\125\124\116\055\125\123\105\122\106\151\162\163 -\164\055\110\141\162\144\167\141\162\145 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\020\071\052\103\117\016\007\337\037\212\243\005\336\064\340 -\302\051 -END -CKA_VALUE MULTILINE_OCTAL -\060\202\005\331\060\202\004\301\240\003\002\001\002\002\020\071 -\052\103\117\016\007\337\037\212\243\005\336\064\340\302\051\060 -\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060\201 -\227\061\013\060\011\006\003\125\004\006\023\002\125\123\061\013 -\060\011\006\003\125\004\010\023\002\125\124\061\027\060\025\006 -\003\125\004\007\023\016\123\141\154\164\040\114\141\153\145\040 -\103\151\164\171\061\036\060\034\006\003\125\004\012\023\025\124 -\150\145\040\125\123\105\122\124\122\125\123\124\040\116\145\164 -\167\157\162\153\061\041\060\037\006\003\125\004\013\023\030\150 -\164\164\160\072\057\057\167\167\167\056\165\163\145\162\164\162 -\165\163\164\056\143\157\155\061\037\060\035\006\003\125\004\003 -\023\026\125\124\116\055\125\123\105\122\106\151\162\163\164\055 -\110\141\162\144\167\141\162\145\060\036\027\015\061\061\060\063 -\061\065\060\060\060\060\060\060\132\027\015\061\064\060\063\061 -\064\062\063\065\071\065\071\132\060\201\337\061\013\060\011\006 -\003\125\004\006\023\002\125\123\061\016\060\014\006\003\125\004 -\021\023\005\063\070\064\067\067\061\020\060\016\006\003\125\004 -\010\023\007\106\154\157\162\151\144\141\061\020\060\016\006\003 -\125\004\007\023\007\105\156\147\154\151\163\150\061\027\060\025 -\006\003\125\004\011\023\016\123\145\141\040\126\151\154\154\141 -\147\145\040\061\060\061\024\060\022\006\003\125\004\012\023\013 -\107\157\157\147\154\145\040\114\164\144\056\061\023\060\021\006 -\003\125\004\013\023\012\124\145\143\150\040\104\145\160\164\056 -\061\050\060\046\006\003\125\004\013\023\037\110\157\163\164\145 -\144\040\142\171\040\107\124\111\040\107\162\157\165\160\040\103 -\157\162\160\157\162\141\164\151\157\156\061\024\060\022\006\003 -\125\004\013\023\013\120\154\141\164\151\156\165\155\123\123\114 -\061\030\060\026\006\003\125\004\003\023\017\154\157\147\151\156 -\056\171\141\150\157\157\056\143\157\155\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\241\244\005\075\355 -\205\105\223\212\030\115\306\003\000\127\342\100\167\360\034\353 -\320\031\337\042\135\010\177\321\007\074\101\211\106\027\243\011 -\372\374\370\251\004\321\226\217\253\327\117\074\371\255\030\251 -\164\201\304\127\012\072\046\026\316\142\076\274\077\154\041\356 -\223\215\313\015\240\037\232\226\320\217\255\365\223\223\202\356 -\162\014\241\165\025\243\173\204\126\270\255\377\122\021\161\204 -\274\072\060\013\176\230\250\341\250\077\067\122\320\361\174\157 -\220\330\105\012\254\071\162\152\141\325\273\303\214\371\302\314 -\337\375\072\161\271\257\274\334\072\334\014\266\261\322\321\211 -\273\101\266\362\336\127\325\025\337\374\375\342\061\305\337\312 -\301\330\217\054\277\360\016\133\161\340\064\161\303\305\115\175 -\172\324\372\355\060\113\057\352\266\056\236\223\074\342\072\370 -\102\242\032\356\334\337\315\017\251\366\171\204\032\216\154\002 -\266\206\345\277\121\152\146\370\363\234\323\131\014\173\245\231 -\170\315\174\231\372\306\226\107\330\062\324\164\166\016\167\113 -\040\164\244\267\211\165\222\112\264\133\125\002\003\001\000\001 -\243\202\001\325\060\202\001\321\060\037\006\003\125\035\043\004 -\030\060\026\200\024\241\162\137\046\033\050\230\103\225\135\007 -\067\325\205\226\235\113\322\303\105\060\035\006\003\125\035\016 -\004\026\004\024\206\111\105\374\063\031\063\324\004\355\047\141 -\356\350\001\311\014\177\057\176\060\016\006\003\125\035\017\001 -\001\377\004\004\003\002\005\240\060\014\006\003\125\035\023\001 -\001\377\004\002\060\000\060\035\006\003\125\035\045\004\026\060 -\024\006\010\053\006\001\005\005\007\003\001\006\010\053\006\001 -\005\005\007\003\002\060\106\006\003\125\035\040\004\077\060\075 -\060\073\006\014\053\006\001\004\001\262\061\001\002\001\003\004 -\060\053\060\051\006\010\053\006\001\005\005\007\002\001\026\035 -\150\164\164\160\163\072\057\057\163\145\143\165\162\145\056\143 -\157\155\157\144\157\056\143\157\155\057\103\120\123\060\173\006 -\003\125\035\037\004\164\060\162\060\070\240\066\240\064\206\062 -\150\164\164\160\072\057\057\143\162\154\056\143\157\155\157\144 -\157\143\141\056\143\157\155\057\125\124\116\055\125\123\105\122 -\106\151\162\163\164\055\110\141\162\144\167\141\162\145\056\143 -\162\154\060\066\240\064\240\062\206\060\150\164\164\160\072\057 -\057\143\162\154\056\143\157\155\157\144\157\056\156\145\164\057 -\125\124\116\055\125\123\105\122\106\151\162\163\164\055\110\141 -\162\144\167\141\162\145\056\143\162\154\060\161\006\010\053\006 -\001\005\005\007\001\001\004\145\060\143\060\073\006\010\053\006 -\001\005\005\007\060\002\206\057\150\164\164\160\072\057\057\143 -\162\164\056\143\157\155\157\144\157\143\141\056\143\157\155\057 -\125\124\116\101\144\144\124\162\165\163\164\123\145\162\166\145 -\162\103\101\056\143\162\164\060\044\006\010\053\006\001\005\005 -\007\060\001\206\030\150\164\164\160\072\057\057\157\143\163\160 -\056\143\157\155\157\144\157\143\141\056\143\157\155\060\032\006 -\003\125\035\021\004\023\060\021\202\017\154\157\147\151\156\056 -\171\141\150\157\157\056\143\157\155\060\015\006\011\052\206\110 -\206\367\015\001\001\005\005\000\003\202\001\001\000\127\142\341 -\167\353\374\037\277\210\123\257\130\323\324\326\155\147\060\027 -\100\276\340\037\144\336\207\025\314\340\244\126\251\321\237\371 -\001\376\002\261\261\352\342\137\356\161\026\061\371\010\325\302 -\327\232\233\262\132\070\327\251\177\351\207\153\061\371\013\254 -\331\375\120\161\340\333\202\222\017\201\234\215\167\351\353\056 -\352\324\043\101\207\354\055\262\170\263\216\261\147\322\356\161 -\003\010\022\231\263\002\051\157\336\213\336\301\251\003\012\132 -\063\034\075\021\003\306\110\014\230\234\025\056\331\246\205\122 -\347\005\212\256\060\043\353\355\050\154\140\351\055\177\217\107 -\213\057\320\334\346\273\017\176\137\362\110\201\216\120\004\143 -\261\121\200\165\232\251\266\020\034\020\137\157\030\157\340\016 -\226\105\316\356\361\265\040\333\357\332\156\310\225\343\366\105 -\375\312\374\245\137\111\155\006\036\322\336\141\075\025\175\067 -\345\034\065\216\006\302\153\367\264\250\050\054\061\313\252\264 -\247\227\117\235\212\366\257\176\067\271\173\075\337\222\146\213 -\217\116\235\306\066\347\134\246\253\022\017\326\317 -END - -# Trust for Certificate "Bogus Yahoo 2" -# Issuer: CN=UTN-USERFirst-Hardware,OU=http://www.usertrust.com,O=The USERTRUST Network,L=Salt Lake City,ST=UT,C=US -# Serial Number:39:2a:43:4f:0e:07:df:1f:8a:a3:05:de:34:e0:c2:29 -# Subject: CN=login.yahoo.com,OU=PlatinumSSL,OU=Hosted by GTI Group Corporation,OU=Tech Dept.,O=Google Ltd.,STREET=Sea Village 10,L=English,ST=Florida,postalCode=38477,C=US -# Not Valid Before: Tue Mar 15 00:00:00 2011 -# Not Valid After : Fri Mar 14 23:59:59 2014 -# Fingerprint (MD5): 72:DC:C8:72:6C:53:3B:B2:FD:CC:5D:19:BD:AF:A6:31 -# Fingerprint (SHA1): D0:18:B6:2D:C5:18:90:72:47:DF:50:92:5B:B0:9A:CF:4A:5C:B3:AD -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 "Bogus Yahoo 2" -CKA_CERT_SHA1_HASH MULTILINE_OCTAL -\320\030\266\055\305\030\220\162\107\337\120\222\133\260\232\317 -\112\134\263\255 -END -CKA_CERT_MD5_HASH MULTILINE_OCTAL -\162\334\310\162\154\123\073\262\375\314\135\031\275\257\246\061 -END -CKA_ISSUER MULTILINE_OCTAL -\060\201\227\061\013\060\011\006\003\125\004\006\023\002\125\123 -\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060 -\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153 -\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023 -\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116 -\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023 -\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162 -\164\162\165\163\164\056\143\157\155\061\037\060\035\006\003\125 -\004\003\023\026\125\124\116\055\125\123\105\122\106\151\162\163 -\164\055\110\141\162\144\167\141\162\145 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\020\071\052\103\117\016\007\337\037\212\243\005\336\064\340 -\302\051 -END -CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED -CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED -CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED -CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE - -# -# Certificate "Bogus Yahoo 3" -# -# Issuer: CN=UTN-USERFirst-Hardware,OU=http://www.usertrust.com,O=The USERTRUST Network,L=Salt Lake City,ST=UT,C=US -# Serial Number:3e:75:ce:d4:6b:69:30:21:21:88:30:ae:86:a8:2a:71 -# Subject: CN=login.yahoo.com,OU=PlatinumSSL,OU=Hosted by GTI Group Corporation,OU=Tech Dept.,O=Google Ltd.,STREET=Sea Village 10,L=English,ST=Florida,postalCode=38477,C=US -# Not Valid Before: Tue Mar 15 00:00:00 2011 -# Not Valid After : Fri Mar 14 23:59:59 2014 -# Fingerprint (MD5): 4A:DC:3C:67:ED:21:CD:5B:CE:5D:C8:11:E4:9E:CF:3D -# Fingerprint (SHA1): 80:96:2A:E4:D6:C5:B4:42:89:4E:95:A1:3E:4A:69:9E:07:D6:94:CF -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 "Bogus Yahoo 3" -CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 -CKA_SUBJECT MULTILINE_OCTAL -\060\201\337\061\013\060\011\006\003\125\004\006\023\002\125\123 -\061\016\060\014\006\003\125\004\021\023\005\063\070\064\067\067 -\061\020\060\016\006\003\125\004\010\023\007\106\154\157\162\151 -\144\141\061\020\060\016\006\003\125\004\007\023\007\105\156\147 -\154\151\163\150\061\027\060\025\006\003\125\004\011\023\016\123 -\145\141\040\126\151\154\154\141\147\145\040\061\060\061\024\060 -\022\006\003\125\004\012\023\013\107\157\157\147\154\145\040\114 -\164\144\056\061\023\060\021\006\003\125\004\013\023\012\124\145 -\143\150\040\104\145\160\164\056\061\050\060\046\006\003\125\004 -\013\023\037\110\157\163\164\145\144\040\142\171\040\107\124\111 -\040\107\162\157\165\160\040\103\157\162\160\157\162\141\164\151 -\157\156\061\024\060\022\006\003\125\004\013\023\013\120\154\141 -\164\151\156\165\155\123\123\114\061\030\060\026\006\003\125\004 -\003\023\017\154\157\147\151\156\056\171\141\150\157\157\056\143 -\157\155 -END -CKA_ID UTF8 "0" -CKA_ISSUER MULTILINE_OCTAL -\060\201\227\061\013\060\011\006\003\125\004\006\023\002\125\123 -\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060 -\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153 -\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023 -\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116 -\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023 -\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162 -\164\162\165\163\164\056\143\157\155\061\037\060\035\006\003\125 -\004\003\023\026\125\124\116\055\125\123\105\122\106\151\162\163 -\164\055\110\141\162\144\167\141\162\145 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\020\076\165\316\324\153\151\060\041\041\210\060\256\206\250 -\052\161 -END -CKA_VALUE MULTILINE_OCTAL -\060\202\005\331\060\202\004\301\240\003\002\001\002\002\020\076 -\165\316\324\153\151\060\041\041\210\060\256\206\250\052\161\060 -\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060\201 -\227\061\013\060\011\006\003\125\004\006\023\002\125\123\061\013 -\060\011\006\003\125\004\010\023\002\125\124\061\027\060\025\006 -\003\125\004\007\023\016\123\141\154\164\040\114\141\153\145\040 -\103\151\164\171\061\036\060\034\006\003\125\004\012\023\025\124 -\150\145\040\125\123\105\122\124\122\125\123\124\040\116\145\164 -\167\157\162\153\061\041\060\037\006\003\125\004\013\023\030\150 -\164\164\160\072\057\057\167\167\167\056\165\163\145\162\164\162 -\165\163\164\056\143\157\155\061\037\060\035\006\003\125\004\003 -\023\026\125\124\116\055\125\123\105\122\106\151\162\163\164\055 -\110\141\162\144\167\141\162\145\060\036\027\015\061\061\060\063 -\061\065\060\060\060\060\060\060\132\027\015\061\064\060\063\061 -\064\062\063\065\071\065\071\132\060\201\337\061\013\060\011\006 -\003\125\004\006\023\002\125\123\061\016\060\014\006\003\125\004 -\021\023\005\063\070\064\067\067\061\020\060\016\006\003\125\004 -\010\023\007\106\154\157\162\151\144\141\061\020\060\016\006\003 -\125\004\007\023\007\105\156\147\154\151\163\150\061\027\060\025 -\006\003\125\004\011\023\016\123\145\141\040\126\151\154\154\141 -\147\145\040\061\060\061\024\060\022\006\003\125\004\012\023\013 -\107\157\157\147\154\145\040\114\164\144\056\061\023\060\021\006 -\003\125\004\013\023\012\124\145\143\150\040\104\145\160\164\056 -\061\050\060\046\006\003\125\004\013\023\037\110\157\163\164\145 -\144\040\142\171\040\107\124\111\040\107\162\157\165\160\040\103 -\157\162\160\157\162\141\164\151\157\156\061\024\060\022\006\003 -\125\004\013\023\013\120\154\141\164\151\156\165\155\123\123\114 -\061\030\060\026\006\003\125\004\003\023\017\154\157\147\151\156 -\056\171\141\150\157\157\056\143\157\155\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\241\244\005\075\355 -\205\105\223\212\030\115\306\003\000\127\342\100\167\360\034\353 -\320\031\337\042\135\010\177\321\007\074\101\211\106\027\243\011 -\372\374\370\251\004\321\226\217\253\327\117\074\371\255\030\251 -\164\201\304\127\012\072\046\026\316\142\076\274\077\154\041\356 -\223\215\313\015\240\037\232\226\320\217\255\365\223\223\202\356 -\162\014\241\165\025\243\173\204\126\270\255\377\122\021\161\204 -\274\072\060\013\176\230\250\341\250\077\067\122\320\361\174\157 -\220\330\105\012\254\071\162\152\141\325\273\303\214\371\302\314 -\337\375\072\161\271\257\274\334\072\334\014\266\261\322\321\211 -\273\101\266\362\336\127\325\025\337\374\375\342\061\305\337\312 -\301\330\217\054\277\360\016\133\161\340\064\161\303\305\115\175 -\172\324\372\355\060\113\057\352\266\056\236\223\074\342\072\370 -\102\242\032\356\334\337\315\017\251\366\171\204\032\216\154\002 -\266\206\345\277\121\152\146\370\363\234\323\131\014\173\245\231 -\170\315\174\231\372\306\226\107\330\062\324\164\166\016\167\113 -\040\164\244\267\211\165\222\112\264\133\125\002\003\001\000\001 -\243\202\001\325\060\202\001\321\060\037\006\003\125\035\043\004 -\030\060\026\200\024\241\162\137\046\033\050\230\103\225\135\007 -\067\325\205\226\235\113\322\303\105\060\035\006\003\125\035\016 -\004\026\004\024\206\111\105\374\063\031\063\324\004\355\047\141 -\356\350\001\311\014\177\057\176\060\016\006\003\125\035\017\001 -\001\377\004\004\003\002\005\240\060\014\006\003\125\035\023\001 -\001\377\004\002\060\000\060\035\006\003\125\035\045\004\026\060 -\024\006\010\053\006\001\005\005\007\003\001\006\010\053\006\001 -\005\005\007\003\002\060\106\006\003\125\035\040\004\077\060\075 -\060\073\006\014\053\006\001\004\001\262\061\001\002\001\003\004 -\060\053\060\051\006\010\053\006\001\005\005\007\002\001\026\035 -\150\164\164\160\163\072\057\057\163\145\143\165\162\145\056\143 -\157\155\157\144\157\056\143\157\155\057\103\120\123\060\173\006 -\003\125\035\037\004\164\060\162\060\070\240\066\240\064\206\062 -\150\164\164\160\072\057\057\143\162\154\056\143\157\155\157\144 -\157\143\141\056\143\157\155\057\125\124\116\055\125\123\105\122 -\106\151\162\163\164\055\110\141\162\144\167\141\162\145\056\143 -\162\154\060\066\240\064\240\062\206\060\150\164\164\160\072\057 -\057\143\162\154\056\143\157\155\157\144\157\056\156\145\164\057 -\125\124\116\055\125\123\105\122\106\151\162\163\164\055\110\141 -\162\144\167\141\162\145\056\143\162\154\060\161\006\010\053\006 -\001\005\005\007\001\001\004\145\060\143\060\073\006\010\053\006 -\001\005\005\007\060\002\206\057\150\164\164\160\072\057\057\143 -\162\164\056\143\157\155\157\144\157\143\141\056\143\157\155\057 -\125\124\116\101\144\144\124\162\165\163\164\123\145\162\166\145 -\162\103\101\056\143\162\164\060\044\006\010\053\006\001\005\005 -\007\060\001\206\030\150\164\164\160\072\057\057\157\143\163\160 -\056\143\157\155\157\144\157\143\141\056\143\157\155\060\032\006 -\003\125\035\021\004\023\060\021\202\017\154\157\147\151\156\056 -\171\141\150\157\157\056\143\157\155\060\015\006\011\052\206\110 -\206\367\015\001\001\005\005\000\003\202\001\001\000\123\151\230 -\216\050\116\234\053\133\035\314\153\167\050\075\273\372\245\116 -\176\126\051\244\352\020\342\364\346\055\006\321\204\333\043\316 -\227\363\150\266\017\072\336\025\013\044\035\221\343\154\056\060 -\267\351\160\260\303\106\200\360\323\261\121\277\117\326\170\240 -\374\254\306\317\061\004\143\342\064\125\005\112\075\366\060\272 -\363\063\345\272\322\226\363\325\261\266\223\211\032\244\150\276 -\176\355\143\264\032\110\300\123\344\243\360\071\014\062\222\307 -\103\015\032\161\355\320\106\223\277\223\142\154\063\113\315\066 -\015\151\136\273\154\226\231\041\151\304\113\147\162\333\154\152 -\270\367\150\355\305\217\255\143\145\225\012\114\340\371\017\176 -\067\075\252\324\223\272\147\011\303\245\244\015\003\132\155\325 -\013\376\360\100\024\264\366\270\151\174\155\302\062\113\237\265 -\032\347\106\256\114\132\053\252\172\136\220\127\225\372\333\146 -\002\040\036\152\151\146\025\234\302\266\365\274\120\265\375\105 -\307\037\150\264\107\131\254\304\033\050\223\116\122\123\022\003 -\130\113\161\203\237\146\346\254\171\110\376\376\107 -END - -# Trust for Certificate "Bogus Yahoo 3" -# Issuer: CN=UTN-USERFirst-Hardware,OU=http://www.usertrust.com,O=The USERTRUST Network,L=Salt Lake City,ST=UT,C=US -# Serial Number:3e:75:ce:d4:6b:69:30:21:21:88:30:ae:86:a8:2a:71 -# Subject: CN=login.yahoo.com,OU=PlatinumSSL,OU=Hosted by GTI Group Corporation,OU=Tech Dept.,O=Google Ltd.,STREET=Sea Village 10,L=English,ST=Florida,postalCode=38477,C=US -# Not Valid Before: Tue Mar 15 00:00:00 2011 -# Not Valid After : Fri Mar 14 23:59:59 2014 -# Fingerprint (MD5): 4A:DC:3C:67:ED:21:CD:5B:CE:5D:C8:11:E4:9E:CF:3D -# Fingerprint (SHA1): 80:96:2A:E4:D6:C5:B4:42:89:4E:95:A1:3E:4A:69:9E:07:D6:94:CF -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 "Bogus Yahoo 3" -CKA_CERT_SHA1_HASH MULTILINE_OCTAL -\200\226\052\344\326\305\264\102\211\116\225\241\076\112\151\236 -\007\326\224\317 -END -CKA_CERT_MD5_HASH MULTILINE_OCTAL -\112\334\074\147\355\041\315\133\316\135\310\021\344\236\317\075 -END -CKA_ISSUER MULTILINE_OCTAL -\060\201\227\061\013\060\011\006\003\125\004\006\023\002\125\123 -\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060 -\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153 -\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023 -\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116 -\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023 -\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162 -\164\162\165\163\164\056\143\157\155\061\037\060\035\006\003\125 -\004\003\023\026\125\124\116\055\125\123\105\122\106\151\162\163 -\164\055\110\141\162\144\167\141\162\145 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\020\076\165\316\324\153\151\060\041\041\210\060\256\206\250 -\052\161 -END -CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED -CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED -CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED -CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE - -# -# Certificate "Bogus live.com" -# -# Issuer: CN=UTN-USERFirst-Hardware,OU=http://www.usertrust.com,O=The USERTRUST Network,L=Salt Lake City,ST=UT,C=US -# Serial Number:00:b0:b7:13:3e:d0:96:f9:b5:6f:ae:91:c8:74:bd:3a:c0 -# Subject: CN=login.live.com,OU=PlatinumSSL,OU=Hosted by GTI Group Corporation,OU=Tech Dept.,O=Google Ltd.,STREET=Sea Village 10,L=English,ST=Florida,postalCode=38477,C=US -# Not Valid Before: Tue Mar 15 00:00:00 2011 -# Not Valid After : Fri Mar 14 23:59:59 2014 -# Fingerprint (MD5): D0:D4:39:E3:CC:5C:52:DD:08:CD:E9:AB:E8:11:59:D4 -# Fingerprint (SHA1): CE:A5:86:B2:CE:59:3E:C7:D9:39:89:83:37:C5:78:14:70:8A:B2:BE -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 "Bogus live.com" -CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 -CKA_SUBJECT MULTILINE_OCTAL -\060\201\336\061\013\060\011\006\003\125\004\006\023\002\125\123 -\061\016\060\014\006\003\125\004\021\023\005\063\070\064\067\067 -\061\020\060\016\006\003\125\004\010\023\007\106\154\157\162\151 -\144\141\061\020\060\016\006\003\125\004\007\023\007\105\156\147 -\154\151\163\150\061\027\060\025\006\003\125\004\011\023\016\123 -\145\141\040\126\151\154\154\141\147\145\040\061\060\061\024\060 -\022\006\003\125\004\012\023\013\107\157\157\147\154\145\040\114 -\164\144\056\061\023\060\021\006\003\125\004\013\023\012\124\145 -\143\150\040\104\145\160\164\056\061\050\060\046\006\003\125\004 -\013\023\037\110\157\163\164\145\144\040\142\171\040\107\124\111 -\040\107\162\157\165\160\040\103\157\162\160\157\162\141\164\151 -\157\156\061\024\060\022\006\003\125\004\013\023\013\120\154\141 -\164\151\156\165\155\123\123\114\061\027\060\025\006\003\125\004 -\003\023\016\154\157\147\151\156\056\154\151\166\145\056\143\157 -\155 -END -CKA_ID UTF8 "0" -CKA_ISSUER MULTILINE_OCTAL -\060\201\227\061\013\060\011\006\003\125\004\006\023\002\125\123 -\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060 -\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153 -\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023 -\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116 -\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023 -\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162 -\164\162\165\163\164\056\143\157\155\061\037\060\035\006\003\125 -\004\003\023\026\125\124\116\055\125\123\105\122\106\151\162\163 -\164\055\110\141\162\144\167\141\162\145 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\021\000\260\267\023\076\320\226\371\265\157\256\221\310\164 -\275\072\300 -END -CKA_VALUE MULTILINE_OCTAL -\060\202\005\354\060\202\004\324\240\003\002\001\002\002\021\000 -\260\267\023\076\320\226\371\265\157\256\221\310\164\275\072\300 -\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060 -\201\227\061\013\060\011\006\003\125\004\006\023\002\125\123\061 -\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060\025 -\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153\145 -\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023\025 -\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116\145 -\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023\030 -\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162\164 -\162\165\163\164\056\143\157\155\061\037\060\035\006\003\125\004 -\003\023\026\125\124\116\055\125\123\105\122\106\151\162\163\164 -\055\110\141\162\144\167\141\162\145\060\036\027\015\061\061\060 -\063\061\065\060\060\060\060\060\060\132\027\015\061\064\060\063 -\061\064\062\063\065\071\065\071\132\060\201\336\061\013\060\011 -\006\003\125\004\006\023\002\125\123\061\016\060\014\006\003\125 -\004\021\023\005\063\070\064\067\067\061\020\060\016\006\003\125 -\004\010\023\007\106\154\157\162\151\144\141\061\020\060\016\006 -\003\125\004\007\023\007\105\156\147\154\151\163\150\061\027\060 -\025\006\003\125\004\011\023\016\123\145\141\040\126\151\154\154 -\141\147\145\040\061\060\061\024\060\022\006\003\125\004\012\023 -\013\107\157\157\147\154\145\040\114\164\144\056\061\023\060\021 -\006\003\125\004\013\023\012\124\145\143\150\040\104\145\160\164 -\056\061\050\060\046\006\003\125\004\013\023\037\110\157\163\164 -\145\144\040\142\171\040\107\124\111\040\107\162\157\165\160\040 -\103\157\162\160\157\162\141\164\151\157\156\061\024\060\022\006 -\003\125\004\013\023\013\120\154\141\164\151\156\165\155\123\123 -\114\061\027\060\025\006\003\125\004\003\023\016\154\157\147\151 -\156\056\154\151\166\145\056\143\157\155\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\363\374\053\057\357 -\341\255\131\360\102\074\302\361\202\277\054\101\223\321\366\230 -\063\225\114\274\142\361\225\130\010\266\351\173\167\110\260\323 -\334\027\077\274\156\346\354\036\354\215\027\376\034\044\306\076 -\147\075\222\225\242\060\300\247\127\040\317\160\210\227\112\005 -\223\171\223\102\227\057\076\377\304\024\024\050\242\023\066\264 -\370\356\276\035\274\170\135\141\223\137\353\210\327\321\344\053 -\232\315\130\342\007\105\237\117\270\271\100\152\063\054\133\041 -\003\132\112\224\362\172\227\131\033\250\265\102\330\203\000\252 -\064\314\247\166\320\107\003\137\005\257\073\341\271\241\064\045 -\267\154\137\232\060\204\230\302\302\327\362\270\102\112\020\125 -\275\372\123\201\135\215\150\146\105\054\122\176\345\304\004\303 -\124\347\303\071\332\172\112\305\271\230\202\040\341\054\140\127 -\277\272\362\106\000\274\137\072\334\343\063\227\370\112\230\271 -\354\063\117\055\140\154\025\222\246\201\112\013\351\354\166\160 -\064\061\027\160\346\160\113\216\213\323\165\313\170\111\253\146 -\233\206\237\217\251\304\001\350\312\033\347\002\003\001\000\001 -\243\202\001\350\060\202\001\344\060\037\006\003\125\035\043\004 -\030\060\026\200\024\241\162\137\046\033\050\230\103\225\135\007 -\067\325\205\226\235\113\322\303\105\060\035\006\003\125\035\016 -\004\026\004\024\324\144\366\251\350\245\176\327\277\143\122\003 -\203\123\333\305\101\215\352\200\060\016\006\003\125\035\017\001 -\001\377\004\004\003\002\005\240\060\014\006\003\125\035\023\001 -\001\377\004\002\060\000\060\035\006\003\125\035\045\004\026\060 -\024\006\010\053\006\001\005\005\007\003\001\006\010\053\006\001 -\005\005\007\003\002\060\106\006\003\125\035\040\004\077\060\075 -\060\073\006\014\053\006\001\004\001\262\061\001\002\001\003\004 -\060\053\060\051\006\010\053\006\001\005\005\007\002\001\026\035 -\150\164\164\160\163\072\057\057\163\145\143\165\162\145\056\143 -\157\155\157\144\157\056\143\157\155\057\103\120\123\060\173\006 -\003\125\035\037\004\164\060\162\060\070\240\066\240\064\206\062 -\150\164\164\160\072\057\057\143\162\154\056\143\157\155\157\144 -\157\143\141\056\143\157\155\057\125\124\116\055\125\123\105\122 -\106\151\162\163\164\055\110\141\162\144\167\141\162\145\056\143 -\162\154\060\066\240\064\240\062\206\060\150\164\164\160\072\057 -\057\143\162\154\056\143\157\155\157\144\157\056\156\145\164\057 -\125\124\116\055\125\123\105\122\106\151\162\163\164\055\110\141 -\162\144\167\141\162\145\056\143\162\154\060\161\006\010\053\006 -\001\005\005\007\001\001\004\145\060\143\060\073\006\010\053\006 -\001\005\005\007\060\002\206\057\150\164\164\160\072\057\057\143 -\162\164\056\143\157\155\157\144\157\143\141\056\143\157\155\057 -\125\124\116\101\144\144\124\162\165\163\164\123\145\162\166\145 -\162\103\101\056\143\162\164\060\044\006\010\053\006\001\005\005 -\007\060\001\206\030\150\164\164\160\072\057\057\157\143\163\160 -\056\143\157\155\157\144\157\143\141\056\143\157\155\060\055\006 -\003\125\035\021\004\046\060\044\202\016\154\157\147\151\156\056 -\154\151\166\145\056\143\157\155\202\022\167\167\167\056\154\157 -\147\151\156\056\154\151\166\145\056\143\157\155\060\015\006\011 -\052\206\110\206\367\015\001\001\005\005\000\003\202\001\001\000 -\124\343\244\232\044\322\363\035\102\255\033\360\036\253\373\332 -\325\252\351\317\132\263\036\127\173\061\362\156\127\113\061\257 -\063\273\266\015\025\307\136\131\001\316\104\265\267\277\011\311 -\325\334\151\204\351\305\032\267\360\076\324\300\044\275\051\137 -\264\351\326\130\353\105\021\211\064\064\323\021\353\064\316\052 -\117\000\075\366\162\357\151\146\300\237\232\254\176\160\120\254 -\125\107\332\276\103\133\354\213\310\305\043\204\311\237\266\122 -\010\317\221\033\057\200\151\346\064\063\346\263\237\244\345\015 -\232\025\371\127\374\013\251\101\013\365\377\130\101\222\042\047 -\146\022\006\307\052\330\131\247\306\337\104\022\117\300\250\177 -\247\101\310\310\151\377\272\005\056\227\255\073\320\353\363\025 -\155\176\033\345\272\335\064\276\042\021\354\150\230\063\201\002 -\152\013\023\125\171\061\165\116\072\310\266\023\275\227\157\067 -\012\013\055\210\016\336\147\220\302\263\312\040\312\232\121\364 -\144\076\333\364\056\105\362\307\107\027\250\364\372\220\132\177 -\200\246\202\254\344\154\201\106\273\122\205\040\044\370\200\352 -END - -# Trust for Certificate "Bogus live.com" -# Issuer: CN=UTN-USERFirst-Hardware,OU=http://www.usertrust.com,O=The USERTRUST Network,L=Salt Lake City,ST=UT,C=US -# Serial Number:00:b0:b7:13:3e:d0:96:f9:b5:6f:ae:91:c8:74:bd:3a:c0 -# Subject: CN=login.live.com,OU=PlatinumSSL,OU=Hosted by GTI Group Corporation,OU=Tech Dept.,O=Google Ltd.,STREET=Sea Village 10,L=English,ST=Florida,postalCode=38477,C=US -# Not Valid Before: Tue Mar 15 00:00:00 2011 -# Not Valid After : Fri Mar 14 23:59:59 2014 -# Fingerprint (MD5): D0:D4:39:E3:CC:5C:52:DD:08:CD:E9:AB:E8:11:59:D4 -# Fingerprint (SHA1): CE:A5:86:B2:CE:59:3E:C7:D9:39:89:83:37:C5:78:14:70:8A:B2:BE -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 "Bogus live.com" -CKA_CERT_SHA1_HASH MULTILINE_OCTAL -\316\245\206\262\316\131\076\307\331\071\211\203\067\305\170\024 -\160\212\262\276 -END -CKA_CERT_MD5_HASH MULTILINE_OCTAL -\320\324\071\343\314\134\122\335\010\315\351\253\350\021\131\324 -END -CKA_ISSUER MULTILINE_OCTAL -\060\201\227\061\013\060\011\006\003\125\004\006\023\002\125\123 -\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060 -\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153 -\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023 -\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116 -\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023 -\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162 -\164\162\165\163\164\056\143\157\155\061\037\060\035\006\003\125 -\004\003\023\026\125\124\116\055\125\123\105\122\106\151\162\163 -\164\055\110\141\162\144\167\141\162\145 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\021\000\260\267\023\076\320\226\371\265\157\256\221\310\164 -\275\072\300 -END -CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED -CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED -CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED -CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE - -# # Certificate "Go Daddy Root Certificate Authority - G2" # # Issuer: CN=Go Daddy Root Certificate Authority - G2,O="GoDaddy.com, Inc.",L=Scottsdale,ST=Arizona,C=US @@ -14493,175 +11728,6 @@ CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE # -# Certificate "Certinomis - Autorité Racine" -# -# Issuer: CN=Certinomis - Autorit.. Racine,OU=0002 433998903,O=Certinomis,C=FR -# Serial Number: 1 (0x1) -# Subject: CN=Certinomis - Autorit.. Racine,OU=0002 433998903,O=Certinomis,C=FR -# Not Valid Before: Wed Sep 17 08:28:59 2008 -# Not Valid After : Sun Sep 17 08:28:59 2028 -# Fingerprint (MD5): 7F:30:78:8C:03:E3:CA:C9:0A:E2:C9:EA:1E:AA:55:1A -# Fingerprint (SHA1): 2E:14:DA:EC:28:F0:FA:1E:8E:38:9A:4E:AB:EB:26:C0:0A:D3:83:C3 -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 "Certinomis - Autorité Racine" -CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 -CKA_SUBJECT MULTILINE_OCTAL -\060\143\061\013\060\011\006\003\125\004\006\023\002\106\122\061 -\023\060\021\006\003\125\004\012\023\012\103\145\162\164\151\156 -\157\155\151\163\061\027\060\025\006\003\125\004\013\023\016\060 -\060\060\062\040\064\063\063\071\071\070\071\060\063\061\046\060 -\044\006\003\125\004\003\014\035\103\145\162\164\151\156\157\155 -\151\163\040\055\040\101\165\164\157\162\151\164\303\251\040\122 -\141\143\151\156\145 -END -CKA_ID UTF8 "0" -CKA_ISSUER MULTILINE_OCTAL -\060\143\061\013\060\011\006\003\125\004\006\023\002\106\122\061 -\023\060\021\006\003\125\004\012\023\012\103\145\162\164\151\156 -\157\155\151\163\061\027\060\025\006\003\125\004\013\023\016\060 -\060\060\062\040\064\063\063\071\071\070\071\060\063\061\046\060 -\044\006\003\125\004\003\014\035\103\145\162\164\151\156\157\155 -\151\163\040\055\040\101\165\164\157\162\151\164\303\251\040\122 -\141\143\151\156\145 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\001\001 -END -CKA_VALUE MULTILINE_OCTAL -\060\202\005\234\060\202\003\204\240\003\002\001\002\002\001\001 -\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060 -\143\061\013\060\011\006\003\125\004\006\023\002\106\122\061\023 -\060\021\006\003\125\004\012\023\012\103\145\162\164\151\156\157 -\155\151\163\061\027\060\025\006\003\125\004\013\023\016\060\060 -\060\062\040\064\063\063\071\071\070\071\060\063\061\046\060\044 -\006\003\125\004\003\014\035\103\145\162\164\151\156\157\155\151 -\163\040\055\040\101\165\164\157\162\151\164\303\251\040\122\141 -\143\151\156\145\060\036\027\015\060\070\060\071\061\067\060\070 -\062\070\065\071\132\027\015\062\070\060\071\061\067\060\070\062 -\070\065\071\132\060\143\061\013\060\011\006\003\125\004\006\023 -\002\106\122\061\023\060\021\006\003\125\004\012\023\012\103\145 -\162\164\151\156\157\155\151\163\061\027\060\025\006\003\125\004 -\013\023\016\060\060\060\062\040\064\063\063\071\071\070\071\060 -\063\061\046\060\044\006\003\125\004\003\014\035\103\145\162\164 -\151\156\157\155\151\163\040\055\040\101\165\164\157\162\151\164 -\303\251\040\122\141\143\151\156\145\060\202\002\042\060\015\006 -\011\052\206\110\206\367\015\001\001\001\005\000\003\202\002\017 -\000\060\202\002\012\002\202\002\001\000\235\205\237\206\323\343 -\257\307\262\153\156\063\340\236\267\102\064\125\235\371\201\276 -\143\330\043\166\016\227\124\315\231\114\032\361\071\307\210\330 -\027\120\014\236\141\332\300\116\125\336\347\132\270\172\116\167 -\207\015\345\270\353\372\236\136\173\036\304\317\050\164\307\223 -\365\024\306\042\050\004\371\221\303\253\047\163\152\016\056\115 -\363\056\050\037\160\337\125\057\116\355\307\161\157\011\162\056 -\355\325\062\227\320\361\130\167\321\140\274\116\136\333\232\204 -\366\107\141\105\053\366\120\246\177\152\161\047\110\204\065\236 -\254\376\151\251\236\172\136\065\045\372\264\247\111\065\167\226 -\247\066\133\341\315\337\043\160\330\135\114\245\010\203\361\246 -\044\070\023\250\354\057\250\241\147\307\246\055\206\107\356\212 -\374\354\233\016\164\364\053\111\002\173\220\165\214\374\231\071 -\001\071\326\112\211\345\236\166\253\076\226\050\070\046\213\335 -\215\214\300\366\001\036\157\245\061\022\070\175\225\302\161\356 -\355\164\256\344\066\242\103\165\325\361\000\233\342\344\327\314 -\102\003\113\170\172\345\175\273\270\256\056\040\223\323\344\141 -\337\161\341\166\147\227\077\266\337\152\163\132\144\042\345\102 -\333\317\201\003\223\330\364\343\020\340\162\366\000\160\254\360 -\301\172\017\005\177\317\064\151\105\265\223\344\031\333\122\026 -\043\005\211\016\215\110\344\045\157\263\170\277\142\365\007\372 -\225\044\302\226\262\350\243\043\302\135\003\374\303\323\345\174 -\311\165\043\327\364\365\274\336\344\337\315\200\277\221\210\175 -\247\023\264\071\272\054\272\275\321\153\314\363\245\050\355\104 -\236\175\122\243\157\226\056\031\176\034\363\133\307\026\216\273 -\140\175\167\146\107\124\202\000\021\140\154\062\301\250\070\033 -\353\156\230\023\326\356\070\365\360\237\016\357\376\061\201\301 -\322\044\225\057\123\172\151\242\360\017\206\105\216\130\202\053 -\114\042\324\136\240\347\175\046\047\110\337\045\106\215\112\050 -\174\206\236\371\233\032\131\271\145\277\005\335\266\102\135\075 -\346\000\110\202\136\040\367\021\202\336\312\330\237\346\067\107 -\046\036\353\170\367\141\303\101\144\130\002\101\371\332\340\321 -\370\371\350\375\122\070\266\365\211\337\002\003\001\000\001\243 -\133\060\131\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\015 -\214\266\141\332\104\270\321\024\175\303\276\175\136\110\360\316 -\312\152\260\060\027\006\003\125\035\040\004\020\060\016\060\014 -\006\012\052\201\172\001\126\002\002\000\001\001\060\015\006\011 -\052\206\110\206\367\015\001\001\005\005\000\003\202\002\001\000 -\044\076\140\006\176\035\357\072\076\333\352\257\034\232\054\001 -\013\364\305\265\331\111\061\364\135\101\215\211\014\116\377\154 -\242\375\377\342\006\310\071\237\361\132\251\335\042\130\025\250 -\212\323\261\346\062\011\202\003\154\327\077\010\307\370\271\272 -\000\155\271\326\374\122\062\135\244\177\244\061\224\273\266\114 -\070\177\050\060\065\377\237\043\123\267\266\356\024\160\000\100 -\053\332\107\253\064\176\136\247\126\060\141\053\213\103\254\375 -\266\210\050\365\153\266\076\140\112\272\102\220\064\147\215\352 -\353\137\105\124\073\027\254\213\344\306\145\017\356\320\214\135 -\146\071\316\062\247\330\020\227\300\176\064\234\237\224\363\366 -\206\037\317\033\163\255\224\171\207\150\160\303\063\245\160\347 -\330\325\070\224\157\143\171\353\277\012\016\010\347\305\057\017 -\102\240\053\024\100\377\041\340\005\305\047\341\204\021\023\272 -\326\206\035\101\013\023\043\211\323\311\013\350\212\272\172\243 -\243\163\067\065\200\175\022\270\063\167\100\070\300\372\136\060 -\322\362\266\243\261\326\242\225\227\201\233\122\355\151\114\377 -\200\344\123\333\124\133\003\155\124\137\261\270\357\044\275\157 -\237\021\303\307\144\302\017\050\142\205\146\136\032\173\262\267 -\357\256\065\311\031\063\250\270\047\333\063\125\277\150\341\165 -\110\104\126\373\315\323\110\273\107\211\072\254\151\365\200\306 -\344\104\120\057\124\304\252\103\305\061\061\130\275\226\305\352 -\165\154\232\165\261\115\370\367\227\377\226\026\362\227\115\350 -\366\363\021\371\072\175\212\070\156\004\313\341\323\105\025\252 -\245\321\035\235\135\143\350\044\346\066\024\342\207\255\033\131 -\365\104\233\373\327\167\174\037\001\160\142\241\040\032\242\305 -\032\050\364\041\003\356\056\331\301\200\352\271\331\202\326\133 -\166\302\313\073\265\322\000\360\243\016\341\255\156\100\367\333 -\240\264\320\106\256\025\327\104\302\115\065\371\322\013\362\027 -\366\254\146\325\044\262\117\321\034\231\300\156\365\175\353\164 -\004\270\371\115\167\011\327\264\317\007\060\011\361\270\000\126 -\331\027\026\026\012\053\206\337\217\001\031\032\345\273\202\143 -\377\276\013\166\026\136\067\067\346\330\164\227\242\231\105\171 -END -CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE - -# Trust for Certificate "Certinomis - Autorité Racine" -# Issuer: CN=Certinomis - Autorit.. Racine,OU=0002 433998903,O=Certinomis,C=FR -# Serial Number: 1 (0x1) -# Subject: CN=Certinomis - Autorit.. Racine,OU=0002 433998903,O=Certinomis,C=FR -# Not Valid Before: Wed Sep 17 08:28:59 2008 -# Not Valid After : Sun Sep 17 08:28:59 2028 -# Fingerprint (MD5): 7F:30:78:8C:03:E3:CA:C9:0A:E2:C9:EA:1E:AA:55:1A -# Fingerprint (SHA1): 2E:14:DA:EC:28:F0:FA:1E:8E:38:9A:4E:AB:EB:26:C0:0A:D3:83:C3 -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 "Certinomis - Autorité Racine" -CKA_CERT_SHA1_HASH MULTILINE_OCTAL -\056\024\332\354\050\360\372\036\216\070\232\116\253\353\046\300 -\012\323\203\303 -END -CKA_CERT_MD5_HASH MULTILINE_OCTAL -\177\060\170\214\003\343\312\311\012\342\311\352\036\252\125\032 -END -CKA_ISSUER MULTILINE_OCTAL -\060\143\061\013\060\011\006\003\125\004\006\023\002\106\122\061 -\023\060\021\006\003\125\004\012\023\012\103\145\162\164\151\156 -\157\155\151\163\061\027\060\025\006\003\125\004\013\023\016\060 -\060\060\062\040\064\063\063\071\071\070\071\060\063\061\046\060 -\044\006\003\125\004\003\014\035\103\145\162\164\151\156\157\155 -\151\163\040\055\040\101\165\164\157\162\151\164\303\251\040\122 -\141\143\151\156\145 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\001\001 -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 "TWCA Root Certification Authority" # # Issuer: CN=TWCA Root Certification Authority,OU=Root CA,O=TAIWAN-CA,C=TW @@ -14966,605 +12032,6 @@ CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE # -# Certificate "Explicitly Distrust DigiNotar Services 1024 CA" -# -# Issuer: E=info@diginotar.nl,CN=DigiNotar Services 1024 CA,O=DigiNotar,C=NL -# Serial Number: 268435455 (0xfffffff) -# Subject: E=info@diginotar.nl,CN=DigiNotar Services 1024 CA,O=DigiNotar,C=NL -# Not Valid Before: Thu Jul 26 15:59:01 2007 -# Not Valid After : Mon Aug 26 16:29:01 2013 -# Fingerprint (MD5): 2F:16:68:97:4C:68:4F:CE:52:8A:EC:53:8F:93:49:F8 -# Fingerprint (SHA1): 12:3B:EA:CA:66:67:77:61:E0:EB:68:F2:FE:ED:A2:0F:20:05:55:70 -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 "Explicitly Distrust DigiNotar Services 1024 CA" -CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 -CKA_SUBJECT MULTILINE_OCTAL -\060\150\061\013\060\011\006\003\125\004\006\023\002\116\114\061 -\022\060\020\006\003\125\004\012\023\011\104\151\147\151\116\157 -\164\141\162\061\043\060\041\006\003\125\004\003\023\032\104\151 -\147\151\116\157\164\141\162\040\123\145\162\166\151\143\145\163 -\040\061\060\062\064\040\103\101\061\040\060\036\006\011\052\206 -\110\206\367\015\001\011\001\026\021\151\156\146\157\100\144\151 -\147\151\156\157\164\141\162\056\156\154 -END -CKA_ID UTF8 "0" -CKA_ISSUER MULTILINE_OCTAL -\060\150\061\013\060\011\006\003\125\004\006\023\002\116\114\061 -\022\060\020\006\003\125\004\012\023\011\104\151\147\151\116\157 -\164\141\162\061\043\060\041\006\003\125\004\003\023\032\104\151 -\147\151\116\157\164\141\162\040\123\145\162\166\151\143\145\163 -\040\061\060\062\064\040\103\101\061\040\060\036\006\011\052\206 -\110\206\367\015\001\011\001\026\021\151\156\146\157\100\144\151 -\147\151\156\157\164\141\162\056\156\154 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\004\017\377\377\377 -END -CKA_VALUE MULTILINE_OCTAL -\060\202\003\161\060\202\002\332\240\003\002\001\002\002\004\017 -\377\377\377\060\015\006\011\052\206\110\206\367\015\001\001\005 -\005\000\060\150\061\013\060\011\006\003\125\004\006\023\002\116 -\114\061\022\060\020\006\003\125\004\012\023\011\104\151\147\151 -\116\157\164\141\162\061\043\060\041\006\003\125\004\003\023\032 -\104\151\147\151\116\157\164\141\162\040\123\145\162\166\151\143 -\145\163\040\061\060\062\064\040\103\101\061\040\060\036\006\011 -\052\206\110\206\367\015\001\011\001\026\021\151\156\146\157\100 -\144\151\147\151\156\157\164\141\162\056\156\154\060\036\027\015 -\060\067\060\067\062\066\061\065\065\071\060\061\132\027\015\061 -\063\060\070\062\066\061\066\062\071\060\061\132\060\150\061\013 -\060\011\006\003\125\004\006\023\002\116\114\061\022\060\020\006 -\003\125\004\012\023\011\104\151\147\151\116\157\164\141\162\061 -\043\060\041\006\003\125\004\003\023\032\104\151\147\151\116\157 -\164\141\162\040\123\145\162\166\151\143\145\163\040\061\060\062 -\064\040\103\101\061\040\060\036\006\011\052\206\110\206\367\015 -\001\011\001\026\021\151\156\146\157\100\144\151\147\151\156\157 -\164\141\162\056\156\154\060\201\237\060\015\006\011\052\206\110 -\206\367\015\001\001\001\005\000\003\201\215\000\060\201\211\002 -\201\201\000\332\233\115\135\074\371\321\342\213\306\306\010\040 -\305\331\036\110\354\146\130\147\171\142\053\101\143\364\211\215 -\150\332\257\270\224\066\213\031\044\244\240\223\322\231\017\262 -\255\055\065\115\315\057\152\341\371\233\031\053\274\004\032\176 -\055\075\122\144\315\361\076\147\017\211\056\350\362\117\256\246 -\010\241\205\376\241\251\011\346\306\253\076\103\374\257\172\003 -\221\332\246\071\246\141\356\230\117\030\250\323\263\257\146\202 -\351\237\274\335\162\371\006\004\275\022\331\030\044\347\253\223 -\123\213\131\002\003\001\000\001\243\202\001\046\060\202\001\042 -\060\022\006\003\125\035\023\001\001\377\004\010\060\006\001\001 -\377\002\001\000\060\047\006\003\125\035\045\004\040\060\036\006 -\010\053\006\001\005\005\007\003\001\006\010\053\006\001\005\005 -\007\003\002\006\010\053\006\001\005\005\007\003\004\060\021\006 -\003\125\035\040\004\012\060\010\060\006\006\004\125\035\040\000 -\060\063\006\010\053\006\001\005\005\007\001\001\004\047\060\045 -\060\043\006\010\053\006\001\005\005\007\060\001\206\027\150\164 -\164\160\072\057\057\157\143\163\160\056\145\156\164\162\165\163 -\164\056\156\145\164\060\063\006\003\125\035\037\004\054\060\052 -\060\050\240\046\240\044\206\042\150\164\164\160\072\057\057\143 -\162\154\056\145\156\164\162\165\163\164\056\156\145\164\057\163 -\145\162\166\145\162\061\056\143\162\154\060\035\006\003\125\035 -\016\004\026\004\024\376\334\224\111\014\157\357\134\177\306\361 -\022\231\117\026\111\255\373\202\145\060\013\006\003\125\035\017 -\004\004\003\002\001\006\060\037\006\003\125\035\043\004\030\060 -\026\200\024\360\027\142\023\125\075\263\377\012\000\153\373\120 -\204\227\363\355\142\320\032\060\031\006\011\052\206\110\206\366 -\175\007\101\000\004\014\060\012\033\004\126\067\056\061\003\002 -\000\201\060\015\006\011\052\206\110\206\367\015\001\001\005\005 -\000\003\201\201\000\143\164\152\067\251\077\226\234\146\310\130 -\254\011\311\357\365\145\224\177\243\002\304\070\061\275\135\043 -\207\354\324\126\262\311\262\156\344\005\006\374\354\365\372\210 -\160\131\324\356\346\335\265\172\240\243\140\057\002\014\253\336 -\022\135\257\360\065\113\252\212\107\221\032\365\205\054\102\307 -\035\357\225\103\263\136\270\225\223\245\332\305\050\252\255\162 -\055\061\255\231\153\154\377\214\041\047\257\255\232\221\053\307 -\335\130\303\156\007\305\237\171\322\307\214\125\277\114\307\047 -\136\121\026\053\076 -END - -# Trust for Certificate "Explicitly Distrust DigiNotar Services 1024 CA" -# Issuer: E=info@diginotar.nl,CN=DigiNotar Services 1024 CA,O=DigiNotar,C=NL -# Serial Number: 268435455 (0xfffffff) -# Subject: E=info@diginotar.nl,CN=DigiNotar Services 1024 CA,O=DigiNotar,C=NL -# Not Valid Before: Thu Jul 26 15:59:01 2007 -# Not Valid After : Mon Aug 26 16:29:01 2013 -# Fingerprint (MD5): 2F:16:68:97:4C:68:4F:CE:52:8A:EC:53:8F:93:49:F8 -# Fingerprint (SHA1): 12:3B:EA:CA:66:67:77:61:E0:EB:68:F2:FE:ED:A2:0F:20:05:55:70 -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 "Explicitly Distrust DigiNotar Services 1024 CA" -CKA_CERT_SHA1_HASH MULTILINE_OCTAL -\022\073\352\312\146\147\167\141\340\353\150\362\376\355\242\017 -\040\005\125\160 -END -CKA_CERT_MD5_HASH MULTILINE_OCTAL -\057\026\150\227\114\150\117\316\122\212\354\123\217\223\111\370 -END -CKA_ISSUER MULTILINE_OCTAL -\060\150\061\013\060\011\006\003\125\004\006\023\002\116\114\061 -\022\060\020\006\003\125\004\012\023\011\104\151\147\151\116\157 -\164\141\162\061\043\060\041\006\003\125\004\003\023\032\104\151 -\147\151\116\157\164\141\162\040\123\145\162\166\151\143\145\163 -\040\061\060\062\064\040\103\101\061\040\060\036\006\011\052\206 -\110\206\367\015\001\011\001\026\021\151\156\146\157\100\144\151 -\147\151\156\157\164\141\162\056\156\154 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\004\017\377\377\377 -END -CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED -CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED -CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED -CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE - -# -# Certificate "Explicitly Distrust DigiNotar Cyber CA" -# -# Issuer: E=info@diginotar.nl,CN=DigiNotar Cyber CA,O=DigiNotar,C=NL -# Serial Number: 268435455 (0xfffffff) -# Subject: E=info@diginotar.nl,CN=DigiNotar Cyber CA,O=DigiNotar,C=NL -# Not Valid Before: Wed Oct 04 10:54:12 2006 -# Not Valid After : Tue Oct 04 10:53:12 2011 -# Fingerprint (MD5): BC:BD:89:12:B4:FF:E5:F9:26:47:C8:60:36:5B:D9:54 -# Fingerprint (SHA1): A5:8E:A0:EC:F6:44:56:35:19:1D:68:5B:C7:A0:E4:1C:B0:4D:79:2E -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 "Explicitly Distrust DigiNotar Cyber CA" -CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 -CKA_SUBJECT MULTILINE_OCTAL -\060\140\061\013\060\011\006\003\125\004\006\023\002\116\114\061 -\022\060\020\006\003\125\004\012\023\011\104\151\147\151\116\157 -\164\141\162\061\033\060\031\006\003\125\004\003\023\022\104\151 -\147\151\116\157\164\141\162\040\103\171\142\145\162\040\103\101 -\061\040\060\036\006\011\052\206\110\206\367\015\001\011\001\026 -\021\151\156\146\157\100\144\151\147\151\156\157\164\141\162\056 -\156\154 -END -CKA_ID UTF8 "0" -CKA_ISSUER MULTILINE_OCTAL -\060\140\061\013\060\011\006\003\125\004\006\023\002\116\114\061 -\022\060\020\006\003\125\004\012\023\011\104\151\147\151\116\157 -\164\141\162\061\033\060\031\006\003\125\004\003\023\022\104\151 -\147\151\116\157\164\141\162\040\103\171\142\145\162\040\103\101 -\061\040\060\036\006\011\052\206\110\206\367\015\001\011\001\026 -\021\151\156\146\157\100\144\151\147\151\156\157\164\141\162\056 -\156\154 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\004\017\377\377\377 -END -CKA_VALUE MULTILINE_OCTAL -\060\202\005\105\060\202\004\256\240\003\002\001\002\002\004\017 -\377\377\377\060\015\006\011\052\206\110\206\367\015\001\001\005 -\005\000\060\140\061\013\060\011\006\003\125\004\006\023\002\116 -\114\061\022\060\020\006\003\125\004\012\023\011\104\151\147\151 -\116\157\164\141\162\061\033\060\031\006\003\125\004\003\023\022 -\104\151\147\151\116\157\164\141\162\040\103\171\142\145\162\040 -\103\101\061\040\060\036\006\011\052\206\110\206\367\015\001\011 -\001\026\021\151\156\146\157\100\144\151\147\151\156\157\164\141 -\162\056\156\154\060\036\027\015\060\066\061\060\060\064\061\060 -\065\064\061\062\132\027\015\061\061\061\060\060\064\061\060\065 -\063\061\062\132\060\140\061\013\060\011\006\003\125\004\006\023 -\002\116\114\061\022\060\020\006\003\125\004\012\023\011\104\151 -\147\151\116\157\164\141\162\061\033\060\031\006\003\125\004\003 -\023\022\104\151\147\151\116\157\164\141\162\040\103\171\142\145 -\162\040\103\101\061\040\060\036\006\011\052\206\110\206\367\015 -\001\011\001\026\021\151\156\146\157\100\144\151\147\151\156\157 -\164\141\162\056\156\154\060\202\002\042\060\015\006\011\052\206 -\110\206\367\015\001\001\001\005\000\003\202\002\017\000\060\202 -\002\012\002\202\002\001\000\322\316\025\012\055\250\136\204\147 -\255\375\276\357\106\307\310\271\317\163\374\364\064\271\371\054 -\103\347\140\023\075\172\343\262\317\073\147\154\220\255\300\271 -\077\204\122\360\065\102\334\164\334\050\073\275\122\264\247\254 -\162\105\027\306\360\211\353\264\252\045\362\135\113\136\321\331 -\207\272\326\175\174\365\316\062\237\020\063\305\261\112\273\136 -\221\061\302\320\351\101\302\221\144\176\011\101\073\333\213\010 -\067\152\252\312\122\336\265\071\036\300\210\003\245\077\213\231 -\023\141\103\265\233\202\263\356\040\157\317\241\104\242\352\057 -\153\100\237\217\053\127\255\241\123\302\205\042\151\235\240\077 -\121\337\013\101\221\015\245\341\250\252\134\111\010\135\275\336 -\160\101\261\017\311\143\153\323\177\064\164\002\057\064\132\170 -\165\034\150\172\201\147\212\363\332\100\360\140\143\364\222\040 -\327\003\246\075\243\036\147\304\204\033\101\245\311\214\346\275 -\352\110\266\005\026\010\263\067\022\132\367\141\074\367\070\157 -\056\227\340\157\126\070\124\323\050\265\255\024\156\056\113\144 -\265\047\145\267\165\045\011\266\007\075\225\126\002\012\202\140 -\262\163\105\340\063\046\121\164\232\271\324\120\034\366\115\133 -\133\122\122\023\132\246\177\247\016\341\350\101\124\147\230\214 -\207\325\311\323\154\313\323\124\222\006\011\064\101\367\201\157 -\077\236\311\174\165\125\260\347\301\263\167\350\303\304\000\065 -\225\100\160\020\112\005\336\045\273\237\131\245\144\274\107\140 -\277\140\343\166\213\023\125\335\341\164\172\271\317\044\246\152 -\177\336\144\042\104\130\150\202\152\020\371\075\345\076\033\271 -\275\374\042\364\140\004\211\273\125\155\050\125\372\336\216\215 -\033\041\024\327\067\213\064\173\115\366\262\262\020\317\063\261 -\175\034\142\231\110\313\053\154\166\226\125\277\031\015\035\037 -\273\145\252\033\216\231\265\306\050\220\345\202\055\170\120\040 -\232\375\171\057\044\177\360\211\051\151\364\175\315\163\276\263 -\355\116\301\321\355\122\136\217\367\270\327\215\207\255\262\331 -\033\121\022\377\126\263\341\257\064\175\134\244\170\210\020\236 -\235\003\306\245\252\242\044\121\367\111\024\305\261\356\131\103 -\225\337\253\150\050\060\077\002\003\001\000\001\243\202\001\206 -\060\202\001\202\060\022\006\003\125\035\023\001\001\377\004\010 -\060\006\001\001\377\002\001\001\060\123\006\003\125\035\040\004 -\114\060\112\060\110\006\011\053\006\001\004\001\261\076\001\000 -\060\073\060\071\006\010\053\006\001\005\005\007\002\001\026\055 -\150\164\164\160\072\057\057\167\167\167\056\160\165\142\154\151 -\143\055\164\162\165\163\164\056\143\157\155\057\103\120\123\057 -\117\155\156\151\122\157\157\164\056\150\164\155\154\060\016\006 -\003\125\035\017\001\001\377\004\004\003\002\001\006\060\201\240 -\006\003\125\035\043\004\201\230\060\201\225\200\024\246\014\035 -\237\141\377\007\027\265\277\070\106\333\103\060\325\216\260\122 -\006\241\171\244\167\060\165\061\013\060\011\006\003\125\004\006 -\023\002\125\123\061\030\060\026\006\003\125\004\012\023\017\107 -\124\105\040\103\157\162\160\157\162\141\164\151\157\156\061\047 -\060\045\006\003\125\004\013\023\036\107\124\105\040\103\171\142 -\145\162\124\162\165\163\164\040\123\157\154\165\164\151\157\156 -\163\054\040\111\156\143\056\061\043\060\041\006\003\125\004\003 -\023\032\107\124\105\040\103\171\142\145\162\124\162\165\163\164 -\040\107\154\157\142\141\154\040\122\157\157\164\202\002\001\245 -\060\105\006\003\125\035\037\004\076\060\074\060\072\240\070\240 -\066\206\064\150\164\164\160\072\057\057\167\167\167\056\160\165 -\142\154\151\143\055\164\162\165\163\164\056\143\157\155\057\143 -\147\151\055\142\151\156\057\103\122\114\057\062\060\061\070\057 -\143\144\160\056\143\162\154\060\035\006\003\125\035\016\004\026 -\004\024\253\371\150\337\317\112\067\327\173\105\214\137\162\336 -\100\104\303\145\273\302\060\015\006\011\052\206\110\206\367\015 -\001\001\005\005\000\003\201\201\000\217\150\153\245\133\007\272 -\104\146\016\034\250\134\060\173\063\344\012\046\004\374\357\236 -\032\070\326\056\241\037\320\231\107\302\165\144\044\375\236\073 -\050\166\271\046\050\141\221\014\155\054\370\004\237\174\120\001 -\325\343\151\257\357\025\322\105\233\044\011\052\146\005\117\045 -\201\312\135\276\252\301\131\047\256\063\216\202\367\337\164\260 -\125\263\216\370\347\067\310\156\252\126\104\366\275\123\201\043 -\226\075\264\372\062\212\123\146\104\045\242\045\306\246\074\045 -\214\360\340\050\006\042\267\046\101 -END - -# Trust for Certificate "Explicitly Distrust DigiNotar Cyber CA" -# Issuer: E=info@diginotar.nl,CN=DigiNotar Cyber CA,O=DigiNotar,C=NL -# Serial Number: 268435455 (0xfffffff) -# Subject: E=info@diginotar.nl,CN=DigiNotar Cyber CA,O=DigiNotar,C=NL -# Not Valid Before: Wed Oct 04 10:54:12 2006 -# Not Valid After : Tue Oct 04 10:53:12 2011 -# Fingerprint (MD5): BC:BD:89:12:B4:FF:E5:F9:26:47:C8:60:36:5B:D9:54 -# Fingerprint (SHA1): A5:8E:A0:EC:F6:44:56:35:19:1D:68:5B:C7:A0:E4:1C:B0:4D:79:2E -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 "Explicitly Distrust DigiNotar Cyber CA" -CKA_CERT_SHA1_HASH MULTILINE_OCTAL -\245\216\240\354\366\104\126\065\031\035\150\133\307\240\344\034 -\260\115\171\056 -END -CKA_CERT_MD5_HASH MULTILINE_OCTAL -\274\275\211\022\264\377\345\371\046\107\310\140\066\133\331\124 -END -CKA_ISSUER MULTILINE_OCTAL -\060\140\061\013\060\011\006\003\125\004\006\023\002\116\114\061 -\022\060\020\006\003\125\004\012\023\011\104\151\147\151\116\157 -\164\141\162\061\033\060\031\006\003\125\004\003\023\022\104\151 -\147\151\116\157\164\141\162\040\103\171\142\145\162\040\103\101 -\061\040\060\036\006\011\052\206\110\206\367\015\001\011\001\026 -\021\151\156\146\157\100\144\151\147\151\156\157\164\141\162\056 -\156\154 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\004\017\377\377\377 -END -CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED -CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED -CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED -CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE - -# -# Certificate "Explicitly Distrust DigiNotar Cyber CA 2nd" -# -# Issuer: CN=DigiNotar Cyber CA,O=DigiNotar,C=NL -# Serial Number: 268435455 (0xfffffff) -# Subject: CN=DigiNotar Cyber CA,O=DigiNotar,C=NL -# Not Valid Before: Wed Sep 27 10:53:53 2006 -# Not Valid After : Fri Sep 20 09:44:07 2013 -# Fingerprint (MD5): F0:AE:A9:3D:F2:2C:88:DC:7C:85:1B:96:7D:5A:1C:11 -# Fingerprint (SHA1): 88:1E:45:05:0F:98:D9:59:FB:0A:35:F9:4C:0E:28:97:55:16:29:B3 -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 "Explicitly Distrust DigiNotar Cyber CA 2nd" -CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 -CKA_SUBJECT MULTILINE_OCTAL -\060\076\061\013\060\011\006\003\125\004\006\023\002\116\114\061 -\022\060\020\006\003\125\004\012\023\011\104\151\147\151\116\157 -\164\141\162\061\033\060\031\006\003\125\004\003\023\022\104\151 -\147\151\116\157\164\141\162\040\103\171\142\145\162\040\103\101 -END -CKA_ID UTF8 "0" -CKA_ISSUER MULTILINE_OCTAL -\060\076\061\013\060\011\006\003\125\004\006\023\002\116\114\061 -\022\060\020\006\003\125\004\012\023\011\104\151\147\151\116\157 -\164\141\162\061\033\060\031\006\003\125\004\003\023\022\104\151 -\147\151\116\157\164\141\162\040\103\171\142\145\162\040\103\101 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\004\017\377\377\377 -END -CKA_VALUE MULTILINE_OCTAL -\060\202\005\001\060\202\004\152\240\003\002\001\002\002\004\017 -\377\377\377\060\015\006\011\052\206\110\206\367\015\001\001\005 -\005\000\060\076\061\013\060\011\006\003\125\004\006\023\002\116 -\114\061\022\060\020\006\003\125\004\012\023\011\104\151\147\151 -\116\157\164\141\162\061\033\060\031\006\003\125\004\003\023\022 -\104\151\147\151\116\157\164\141\162\040\103\171\142\145\162\040 -\103\101\060\036\027\015\060\066\060\071\062\067\061\060\065\063 -\065\063\132\027\015\061\063\060\071\062\060\060\071\064\064\060 -\067\132\060\076\061\013\060\011\006\003\125\004\006\023\002\116 -\114\061\022\060\020\006\003\125\004\012\023\011\104\151\147\151 -\116\157\164\141\162\061\033\060\031\006\003\125\004\003\023\022 -\104\151\147\151\116\157\164\141\162\040\103\171\142\145\162\040 -\103\101\060\202\002\042\060\015\006\011\052\206\110\206\367\015 -\001\001\001\005\000\003\202\002\017\000\060\202\002\012\002\202 -\002\001\000\322\316\025\012\055\250\136\204\147\255\375\276\357 -\106\307\310\271\317\163\374\364\064\271\371\054\103\347\140\023 -\075\172\343\262\317\073\147\154\220\255\300\271\077\204\122\360 -\065\102\334\164\334\050\073\275\122\264\247\254\162\105\027\306 -\360\211\353\264\252\045\362\135\113\136\321\331\207\272\326\175 -\174\365\316\062\237\020\063\305\261\112\273\136\221\061\302\320 -\351\101\302\221\144\176\011\101\073\333\213\010\067\152\252\312 -\122\336\265\071\036\300\210\003\245\077\213\231\023\141\103\265 -\233\202\263\356\040\157\317\241\104\242\352\057\153\100\237\217 -\053\127\255\241\123\302\205\042\151\235\240\077\121\337\013\101 -\221\015\245\341\250\252\134\111\010\135\275\336\160\101\261\017 -\311\143\153\323\177\064\164\002\057\064\132\170\165\034\150\172 -\201\147\212\363\332\100\360\140\143\364\222\040\327\003\246\075 -\243\036\147\304\204\033\101\245\311\214\346\275\352\110\266\005 -\026\010\263\067\022\132\367\141\074\367\070\157\056\227\340\157 -\126\070\124\323\050\265\255\024\156\056\113\144\265\047\145\267 -\165\045\011\266\007\075\225\126\002\012\202\140\262\163\105\340 -\063\046\121\164\232\271\324\120\034\366\115\133\133\122\122\023 -\132\246\177\247\016\341\350\101\124\147\230\214\207\325\311\323 -\154\313\323\124\222\006\011\064\101\367\201\157\077\236\311\174 -\165\125\260\347\301\263\167\350\303\304\000\065\225\100\160\020 -\112\005\336\045\273\237\131\245\144\274\107\140\277\140\343\166 -\213\023\125\335\341\164\172\271\317\044\246\152\177\336\144\042 -\104\130\150\202\152\020\371\075\345\076\033\271\275\374\042\364 -\140\004\211\273\125\155\050\125\372\336\216\215\033\041\024\327 -\067\213\064\173\115\366\262\262\020\317\063\261\175\034\142\231 -\110\313\053\154\166\226\125\277\031\015\035\037\273\145\252\033 -\216\231\265\306\050\220\345\202\055\170\120\040\232\375\171\057 -\044\177\360\211\051\151\364\175\315\163\276\263\355\116\301\321 -\355\122\136\217\367\270\327\215\207\255\262\331\033\121\022\377 -\126\263\341\257\064\175\134\244\170\210\020\236\235\003\306\245 -\252\242\044\121\367\111\024\305\261\356\131\103\225\337\253\150 -\050\060\077\002\003\001\000\001\243\202\001\206\060\202\001\202 -\060\022\006\003\125\035\023\001\001\377\004\010\060\006\001\001 -\377\002\001\001\060\123\006\003\125\035\040\004\114\060\112\060 -\110\006\011\053\006\001\004\001\261\076\001\000\060\073\060\071 -\006\010\053\006\001\005\005\007\002\001\026\055\150\164\164\160 -\072\057\057\167\167\167\056\160\165\142\154\151\143\055\164\162 -\165\163\164\056\143\157\155\057\103\120\123\057\117\155\156\151 -\122\157\157\164\056\150\164\155\154\060\016\006\003\125\035\017 -\001\001\377\004\004\003\002\001\006\060\201\240\006\003\125\035 -\043\004\201\230\060\201\225\200\024\246\014\035\237\141\377\007 -\027\265\277\070\106\333\103\060\325\216\260\122\006\241\171\244 -\167\060\165\061\013\060\011\006\003\125\004\006\023\002\125\123 -\061\030\060\026\006\003\125\004\012\023\017\107\124\105\040\103 -\157\162\160\157\162\141\164\151\157\156\061\047\060\045\006\003 -\125\004\013\023\036\107\124\105\040\103\171\142\145\162\124\162 -\165\163\164\040\123\157\154\165\164\151\157\156\163\054\040\111 -\156\143\056\061\043\060\041\006\003\125\004\003\023\032\107\124 -\105\040\103\171\142\145\162\124\162\165\163\164\040\107\154\157 -\142\141\154\040\122\157\157\164\202\002\001\245\060\105\006\003 -\125\035\037\004\076\060\074\060\072\240\070\240\066\206\064\150 -\164\164\160\072\057\057\167\167\167\056\160\165\142\154\151\143 -\055\164\162\165\163\164\056\143\157\155\057\143\147\151\055\142 -\151\156\057\103\122\114\057\062\060\061\070\057\143\144\160\056 -\143\162\154\060\035\006\003\125\035\016\004\026\004\024\253\371 -\150\337\317\112\067\327\173\105\214\137\162\336\100\104\303\145 -\273\302\060\015\006\011\052\206\110\206\367\015\001\001\005\005 -\000\003\201\201\000\011\312\142\017\215\273\112\340\324\172\065 -\053\006\055\321\050\141\266\254\001\373\203\111\274\256\324\057 -\055\206\256\031\203\245\326\035\023\342\027\276\376\062\164\351 -\172\024\070\312\224\136\367\051\001\151\161\033\221\032\375\243 -\273\252\035\312\173\342\026\375\241\243\016\363\014\137\262\341 -\040\061\224\053\136\222\166\355\372\351\265\043\246\277\012\073 -\003\251\157\122\140\124\315\137\351\267\057\174\242\047\375\101 -\203\165\266\015\373\170\046\363\261\105\351\062\225\052\032\065 -\041\225\305\242\165 -END - -# Trust for Certificate "Explicitly Distrust DigiNotar Cyber CA 2nd" -# Issuer: CN=DigiNotar Cyber CA,O=DigiNotar,C=NL -# Serial Number: 268435455 (0xfffffff) -# Subject: CN=DigiNotar Cyber CA,O=DigiNotar,C=NL -# Not Valid Before: Wed Sep 27 10:53:53 2006 -# Not Valid After : Fri Sep 20 09:44:07 2013 -# Fingerprint (MD5): F0:AE:A9:3D:F2:2C:88:DC:7C:85:1B:96:7D:5A:1C:11 -# Fingerprint (SHA1): 88:1E:45:05:0F:98:D9:59:FB:0A:35:F9:4C:0E:28:97:55:16:29:B3 -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 "Explicitly Distrust DigiNotar Cyber CA 2nd" -CKA_CERT_SHA1_HASH MULTILINE_OCTAL -\210\036\105\005\017\230\331\131\373\012\065\371\114\016\050\227 -\125\026\051\263 -END -CKA_CERT_MD5_HASH MULTILINE_OCTAL -\360\256\251\075\362\054\210\334\174\205\033\226\175\132\034\021 -END -CKA_ISSUER MULTILINE_OCTAL -\060\076\061\013\060\011\006\003\125\004\006\023\002\116\114\061 -\022\060\020\006\003\125\004\012\023\011\104\151\147\151\116\157 -\164\141\162\061\033\060\031\006\003\125\004\003\023\022\104\151 -\147\151\116\157\164\141\162\040\103\171\142\145\162\040\103\101 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\004\017\377\377\377 -END -CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED -CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED -CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED -CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE - -# -# Certificate "Explicitly Distrusted DigiNotar PKIoverheid" -# -# Issuer: CN=DigiNotar PKIoverheid CA Overheid en Bedrijven,O=DigiNotar B.V.,C=NL -# Serial Number: 268435455 (0xfffffff) -# Subject: CN=DigiNotar PKIoverheid CA Overheid en Bedrijven,O=DigiNotar B.V.,C=NL -# Not Valid Before: Thu Jul 05 08:42:08 2007 -# Not Valid After : Mon Jul 27 08:39:47 2015 -# Fingerprint (MD5): A3:CF:B3:FF:F9:4F:A7:B1:EB:3A:75:58:4E:2E:9F:EA -# Fingerprint (SHA1): A7:A8:C9:AC:F4:5F:90:92:76:86:B8:C0:A2:0E:93:58:7D:DE:30:E4 -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 "Explicitly Distrusted DigiNotar PKIoverheid" -CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 -CKA_SUBJECT MULTILINE_OCTAL -\060\137\061\013\060\011\006\003\125\004\006\023\002\116\114\061 -\027\060\025\006\003\125\004\012\023\016\104\151\147\151\116\157 -\164\141\162\040\102\056\126\056\061\067\060\065\006\003\125\004 -\003\023\056\104\151\147\151\116\157\164\141\162\040\120\113\111 -\157\166\145\162\150\145\151\144\040\103\101\040\117\166\145\162 -\150\145\151\144\040\145\156\040\102\145\144\162\151\152\166\145 -\156 -END -CKA_ID UTF8 "0" -CKA_ISSUER MULTILINE_OCTAL -\060\137\061\013\060\011\006\003\125\004\006\023\002\116\114\061 -\027\060\025\006\003\125\004\012\023\016\104\151\147\151\116\157 -\164\141\162\040\102\056\126\056\061\067\060\065\006\003\125\004 -\003\023\056\104\151\147\151\116\157\164\141\162\040\120\113\111 -\157\166\145\162\150\145\151\144\040\103\101\040\117\166\145\162 -\150\145\151\144\040\145\156\040\102\145\144\162\151\152\166\145 -\156 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\004\017\377\377\377 -END -CKA_VALUE MULTILINE_OCTAL -\060\202\004\216\060\202\003\166\240\003\002\001\002\002\004\017 -\377\377\377\060\015\006\011\052\206\110\206\367\015\001\001\005 -\005\000\060\137\061\013\060\011\006\003\125\004\006\023\002\116 -\114\061\027\060\025\006\003\125\004\012\023\016\104\151\147\151 -\116\157\164\141\162\040\102\056\126\056\061\067\060\065\006\003 -\125\004\003\023\056\104\151\147\151\116\157\164\141\162\040\120 -\113\111\157\166\145\162\150\145\151\144\040\103\101\040\117\166 -\145\162\150\145\151\144\040\145\156\040\102\145\144\162\151\152 -\166\145\156\060\036\027\015\060\067\060\067\060\065\060\070\064 -\062\060\070\132\027\015\061\065\060\067\062\067\060\070\063\071 -\064\067\132\060\137\061\013\060\011\006\003\125\004\006\023\002 -\116\114\061\027\060\025\006\003\125\004\012\023\016\104\151\147 -\151\116\157\164\141\162\040\102\056\126\056\061\067\060\065\006 -\003\125\004\003\023\056\104\151\147\151\116\157\164\141\162\040 -\120\113\111\157\166\145\162\150\145\151\144\040\103\101\040\117 -\166\145\162\150\145\151\144\040\145\156\040\102\145\144\162\151 -\152\166\145\156\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\334\275\322\247\116\152\012\273\073\242\205 -\341\177\000\255\276\264\060\150\230\007\315\240\172\304\224\317 -\161\371\212\067\344\123\353\127\166\314\213\346\154\376\356\207 -\125\310\076\273\004\071\000\247\200\170\254\133\117\176\364\275 -\270\124\270\161\073\007\061\111\071\223\124\174\040\073\171\053 -\217\273\141\220\175\261\254\346\037\220\056\235\105\001\251\144 -\055\115\303\057\271\347\120\325\116\052\134\253\166\166\067\106 -\327\171\354\102\231\367\242\354\244\211\160\334\070\053\207\246 -\252\044\346\235\222\044\033\276\366\375\324\057\031\027\172\346 -\062\007\224\124\005\123\103\351\154\274\257\107\313\274\313\375 -\275\073\104\022\201\361\153\113\273\355\264\317\253\045\117\030 -\322\314\002\374\243\117\265\102\063\313\131\315\011\334\323\120 -\375\240\166\214\254\176\146\212\102\366\255\034\222\363\266\373 -\024\106\353\115\327\057\060\340\155\356\133\066\276\104\164\267 -\040\005\127\205\115\350\000\031\242\366\014\346\256\241\300\102 -\337\247\254\202\135\307\150\267\030\346\211\113\232\153\372\316 -\171\371\363\054\247\002\003\001\000\001\243\202\001\120\060\202 -\001\114\060\110\006\003\125\035\040\004\101\060\077\060\075\006 -\004\125\035\040\000\060\065\060\063\006\010\053\006\001\005\005 -\007\002\001\026\047\150\164\164\160\072\057\057\167\167\167\056 -\144\151\147\151\156\157\164\141\162\056\156\154\057\143\160\163 -\057\160\153\151\157\166\145\162\150\145\151\144\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\201\200 -\006\003\125\035\043\004\171\060\167\200\024\013\206\326\017\167 -\243\150\261\373\144\011\303\210\156\134\004\034\127\351\075\241 -\131\244\127\060\125\061\013\060\011\006\003\125\004\006\023\002 -\116\114\061\036\060\034\006\003\125\004\012\023\025\123\164\141 -\141\164\040\144\145\162\040\116\145\144\145\162\154\141\156\144 -\145\156\061\046\060\044\006\003\125\004\003\023\035\123\164\141 -\141\164\040\144\145\162\040\116\145\144\145\162\154\141\156\144 -\145\156\040\122\157\157\164\040\103\101\202\004\000\230\232\171 -\060\075\006\003\125\035\037\004\066\060\064\060\062\240\060\240 -\056\206\054\150\164\164\160\072\057\057\143\162\154\056\160\153 -\151\157\166\145\162\150\145\151\144\056\156\154\057\104\157\155 -\117\166\114\141\164\145\163\164\103\122\114\056\143\162\154\060 -\035\006\003\125\035\016\004\026\004\024\114\010\311\215\166\361 -\230\307\076\337\074\327\057\165\015\261\166\171\227\314\060\015 -\006\011\052\206\110\206\367\015\001\001\005\005\000\003\202\001 -\001\000\014\224\207\032\277\115\343\205\342\356\327\330\143\171 -\016\120\337\306\204\133\322\273\331\365\061\012\032\065\227\164 -\337\024\372\052\017\076\355\240\343\010\366\325\116\133\257\246 -\256\045\342\105\153\042\017\267\124\050\176\222\336\215\024\154 -\321\034\345\156\164\004\234\267\357\064\104\105\337\311\203\035 -\031\037\300\051\151\337\211\325\077\302\260\123\155\345\116\027 -\344\163\141\043\023\046\161\103\375\114\131\313\303\337\042\252 -\041\053\331\277\225\021\032\212\244\342\253\247\135\113\157\051 -\365\122\321\344\322\025\261\213\376\360\003\317\247\175\351\231 -\207\070\263\015\163\024\344\162\054\341\316\365\255\006\110\144 -\372\323\051\271\242\330\273\364\325\013\245\100\104\103\216\240 -\277\316\132\245\122\114\144\323\027\061\141\314\350\244\212\350 -\344\210\373\351\345\057\006\063\063\233\224\146\146\261\253\120 -\072\241\011\201\164\123\132\047\271\246\322\045\317\323\303\247 -\377\226\320\057\352\340\036\215\122\351\030\034\040\012\107\240 -\226\126\016\100\220\121\104\254\032\375\361\356\205\037\367\102 -\132\145 -END - -# Trust for Certificate "Explicitly Distrusted DigiNotar PKIoverheid" -# Issuer: CN=DigiNotar PKIoverheid CA Overheid en Bedrijven,O=DigiNotar B.V.,C=NL -# Serial Number: 268435455 (0xfffffff) -# Subject: CN=DigiNotar PKIoverheid CA Overheid en Bedrijven,O=DigiNotar B.V.,C=NL -# Not Valid Before: Thu Jul 05 08:42:08 2007 -# Not Valid After : Mon Jul 27 08:39:47 2015 -# Fingerprint (MD5): A3:CF:B3:FF:F9:4F:A7:B1:EB:3A:75:58:4E:2E:9F:EA -# Fingerprint (SHA1): A7:A8:C9:AC:F4:5F:90:92:76:86:B8:C0:A2:0E:93:58:7D:DE:30:E4 -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 "Explicitly Distrusted DigiNotar PKIoverheid" -CKA_CERT_SHA1_HASH MULTILINE_OCTAL -\247\250\311\254\364\137\220\222\166\206\270\300\242\016\223\130 -\175\336\060\344 -END -CKA_CERT_MD5_HASH MULTILINE_OCTAL -\243\317\263\377\371\117\247\261\353\072\165\130\116\056\237\352 -END -CKA_ISSUER MULTILINE_OCTAL -\060\137\061\013\060\011\006\003\125\004\006\023\002\116\114\061 -\027\060\025\006\003\125\004\012\023\016\104\151\147\151\116\157 -\164\141\162\040\102\056\126\056\061\067\060\065\006\003\125\004 -\003\023\056\104\151\147\151\116\157\164\141\162\040\120\113\111 -\157\166\145\162\150\145\151\144\040\103\101\040\117\166\145\162 -\150\145\151\144\040\145\156\040\102\145\144\162\151\152\166\145 -\156 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\004\017\377\377\377 -END -CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED -CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED -CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED -CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE - -# # Certificate "Explicitly Distrusted DigiNotar PKIoverheid G2" # # Issuer: CN=DigiNotar PKIoverheid CA Organisatie - G2,O=DigiNotar B.V.,C=NL @@ -15746,315 +12213,6 @@ CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE # -# Certificate "Explicitly Distrusted Malaysian Digicert Sdn. Bhd. (cyb)" -# -# Issuer: CN=GTE CyberTrust Global Root,OU="GTE CyberTrust Solutions, Inc.",O=GTE Corporation,C=US -# Serial Number:07:ff:ff:ff:ff:ff -# Subject: CN=Digisign Server ID (Enrich),OU=457608-K,O=Digicert Sdn. Bhd.,C=MY -# Not Valid Before: Tue Jul 17 15:17:49 2007 -# Not Valid After : Tue Jul 17 15:16:55 2012 -# Fingerprint (MD5): D2:DE:AE:50:A4:98:2D:6F:37:B7:86:52:C8:2D:4B:6A -# Fingerprint (SHA1): 55:50:AF:EC:BF:E8:C3:AD:C4:0B:E3:AD:0C:A7:E4:15:8C:39:59:4F -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 "Explicitly Distrusted Malaysian Digicert Sdn. Bhd. (cyb)" -CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 -CKA_SUBJECT MULTILINE_OCTAL -\060\143\061\013\060\011\006\003\125\004\006\023\002\115\131\061 -\033\060\031\006\003\125\004\012\023\022\104\151\147\151\143\145 -\162\164\040\123\144\156\056\040\102\150\144\056\061\021\060\017 -\006\003\125\004\013\023\010\064\065\067\066\060\070\055\113\061 -\044\060\042\006\003\125\004\003\023\033\104\151\147\151\163\151 -\147\156\040\123\145\162\166\145\162\040\111\104\040\050\105\156 -\162\151\143\150\051 -END -CKA_ID UTF8 "0" -CKA_ISSUER MULTILINE_OCTAL -\060\165\061\013\060\011\006\003\125\004\006\023\002\125\123\061 -\030\060\026\006\003\125\004\012\023\017\107\124\105\040\103\157 -\162\160\157\162\141\164\151\157\156\061\047\060\045\006\003\125 -\004\013\023\036\107\124\105\040\103\171\142\145\162\124\162\165 -\163\164\040\123\157\154\165\164\151\157\156\163\054\040\111\156 -\143\056\061\043\060\041\006\003\125\004\003\023\032\107\124\105 -\040\103\171\142\145\162\124\162\165\163\164\040\107\154\157\142 -\141\154\040\122\157\157\164 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\006\007\377\377\377\377\377 -END -CKA_VALUE MULTILINE_OCTAL -\060\202\003\315\060\202\003\066\240\003\002\001\002\002\006\007 -\377\377\377\377\377\060\015\006\011\052\206\110\206\367\015\001 -\001\005\005\000\060\165\061\013\060\011\006\003\125\004\006\023 -\002\125\123\061\030\060\026\006\003\125\004\012\023\017\107\124 -\105\040\103\157\162\160\157\162\141\164\151\157\156\061\047\060 -\045\006\003\125\004\013\023\036\107\124\105\040\103\171\142\145 -\162\124\162\165\163\164\040\123\157\154\165\164\151\157\156\163 -\054\040\111\156\143\056\061\043\060\041\006\003\125\004\003\023 -\032\107\124\105\040\103\171\142\145\162\124\162\165\163\164\040 -\107\154\157\142\141\154\040\122\157\157\164\060\036\027\015\060 -\067\060\067\061\067\061\065\061\067\064\071\132\027\015\061\062 -\060\067\061\067\061\065\061\066\065\065\132\060\143\061\013\060 -\011\006\003\125\004\006\023\002\115\131\061\033\060\031\006\003 -\125\004\012\023\022\104\151\147\151\143\145\162\164\040\123\144 -\156\056\040\102\150\144\056\061\021\060\017\006\003\125\004\013 -\023\010\064\065\067\066\060\070\055\113\061\044\060\042\006\003 -\125\004\003\023\033\104\151\147\151\163\151\147\156\040\123\145 -\162\166\145\162\040\111\104\040\050\105\156\162\151\143\150\051 -\060\201\237\060\015\006\011\052\206\110\206\367\015\001\001\001 -\005\000\003\201\215\000\060\201\211\002\201\201\000\255\250\144 -\113\115\207\307\204\131\271\373\220\106\240\246\211\300\361\376 -\325\332\124\202\067\015\231\053\105\046\012\350\126\260\177\312 -\250\364\216\107\204\001\202\051\343\263\152\265\221\363\373\225 -\205\274\162\250\144\350\012\100\234\305\364\161\256\173\173\152 -\007\352\220\024\117\215\211\257\224\253\262\006\324\002\152\173 -\230\037\131\271\072\315\124\372\040\337\262\052\012\351\270\335 -\151\220\300\051\323\116\320\227\355\146\314\305\031\111\006\177 -\372\136\054\174\173\205\033\062\102\337\173\225\045\002\003\001 -\000\001\243\202\001\170\060\202\001\164\060\022\006\003\125\035 -\023\001\001\377\004\010\060\006\001\001\377\002\001\000\060\134 -\006\003\125\035\040\004\125\060\123\060\110\006\011\053\006\001 -\004\001\261\076\001\000\060\073\060\071\006\010\053\006\001\005 -\005\007\002\001\026\055\150\164\164\160\072\057\057\143\171\142 -\145\162\164\162\165\163\164\056\157\155\156\151\162\157\157\164 -\056\143\157\155\057\162\145\160\157\163\151\164\157\162\171\056 -\143\146\155\060\007\006\005\140\203\112\001\001\060\016\006\003 -\125\035\017\001\001\377\004\004\003\002\001\346\060\201\211\006 -\003\125\035\043\004\201\201\060\177\241\171\244\167\060\165\061 -\013\060\011\006\003\125\004\006\023\002\125\123\061\030\060\026 -\006\003\125\004\012\023\017\107\124\105\040\103\157\162\160\157 -\162\141\164\151\157\156\061\047\060\045\006\003\125\004\013\023 -\036\107\124\105\040\103\171\142\145\162\124\162\165\163\164\040 -\123\157\154\165\164\151\157\156\163\054\040\111\156\143\056\061 -\043\060\041\006\003\125\004\003\023\032\107\124\105\040\103\171 -\142\145\162\124\162\165\163\164\040\107\154\157\142\141\154\040 -\122\157\157\164\202\002\001\245\060\105\006\003\125\035\037\004 -\076\060\074\060\072\240\070\240\066\206\064\150\164\164\160\072 -\057\057\167\167\167\056\160\165\142\154\151\143\055\164\162\165 -\163\164\056\143\157\155\057\143\147\151\055\142\151\156\057\103 -\122\114\057\062\060\061\070\057\143\144\160\056\143\162\154\060 -\035\006\003\125\035\016\004\026\004\024\306\026\223\116\026\027 -\354\026\256\214\224\166\363\206\155\305\164\156\204\167\060\015 -\006\011\052\206\110\206\367\015\001\001\005\005\000\003\201\201 -\000\166\000\173\246\170\053\146\035\216\136\066\306\244\216\005 -\362\043\222\174\223\147\323\364\300\012\175\213\055\331\352\325 -\157\032\363\341\112\051\132\042\204\115\120\057\113\014\362\377 -\205\302\173\125\324\104\202\276\155\254\147\216\274\264\037\222 -\234\121\200\032\024\366\156\253\141\210\013\255\034\177\367\113 -\120\121\326\145\033\246\107\161\025\136\260\161\363\065\024\362 -\067\275\143\310\325\360\223\132\064\137\330\075\350\135\367\305 -\036\300\345\317\037\206\044\251\074\007\146\315\301\322\066\143 -\131 -END - -# Trust for Certificate "Explicitly Distrusted Malaysian Digicert Sdn. Bhd. (cyb)" -# Issuer: CN=GTE CyberTrust Global Root,OU="GTE CyberTrust Solutions, Inc.",O=GTE Corporation,C=US -# Serial Number:07:ff:ff:ff:ff:ff -# Subject: CN=Digisign Server ID (Enrich),OU=457608-K,O=Digicert Sdn. Bhd.,C=MY -# Not Valid Before: Tue Jul 17 15:17:49 2007 -# Not Valid After : Tue Jul 17 15:16:55 2012 -# Fingerprint (MD5): D2:DE:AE:50:A4:98:2D:6F:37:B7:86:52:C8:2D:4B:6A -# Fingerprint (SHA1): 55:50:AF:EC:BF:E8:C3:AD:C4:0B:E3:AD:0C:A7:E4:15:8C:39:59:4F -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 "Explicitly Distrusted Malaysian Digicert Sdn. Bhd. (cyb)" -CKA_CERT_SHA1_HASH MULTILINE_OCTAL -\125\120\257\354\277\350\303\255\304\013\343\255\014\247\344\025 -\214\071\131\117 -END -CKA_CERT_MD5_HASH MULTILINE_OCTAL -\322\336\256\120\244\230\055\157\067\267\206\122\310\055\113\152 -END -CKA_ISSUER MULTILINE_OCTAL -\060\165\061\013\060\011\006\003\125\004\006\023\002\125\123\061 -\030\060\026\006\003\125\004\012\023\017\107\124\105\040\103\157 -\162\160\157\162\141\164\151\157\156\061\047\060\045\006\003\125 -\004\013\023\036\107\124\105\040\103\171\142\145\162\124\162\165 -\163\164\040\123\157\154\165\164\151\157\156\163\054\040\111\156 -\143\056\061\043\060\041\006\003\125\004\003\023\032\107\124\105 -\040\103\171\142\145\162\124\162\165\163\164\040\107\154\157\142 -\141\154\040\122\157\157\164 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\006\007\377\377\377\377\377 -END -CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED -CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED -CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED -CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE - -# -# Certificate "Explicitly Distrusted Malaysian Digicert Sdn. Bhd. (en)" -# -# Issuer: CN=Entrust.net Certification Authority (2048),OU=(c) 1999 Entrust.net Limited,OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.),O=Entrust.net -# Serial Number:07:ff:ff:ff:ff:ff -# Subject: CN=Digisign Server ID - (Enrich),OU=457608-K,O=Digicert Sdn. Bhd.,C=MY -# Not Valid Before: Fri Jul 16 17:23:38 2010 -# Not Valid After : Thu Jul 16 17:53:38 2015 -# Fingerprint (MD5): D7:69:61:7F:35:0F:9C:46:A3:AA:EB:F8:55:FC:84:F2 -# Fingerprint (SHA1): 6B:3C:3B:80:AD:CA:A6:BA:8A:9F:54:A6:7A:ED:12:69:05:6D:31:26 -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 "Explicitly Distrusted Malaysian Digicert Sdn. Bhd. (en)" -CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 -CKA_SUBJECT MULTILINE_OCTAL -\060\145\061\013\060\011\006\003\125\004\006\023\002\115\131\061 -\033\060\031\006\003\125\004\012\023\022\104\151\147\151\143\145 -\162\164\040\123\144\156\056\040\102\150\144\056\061\021\060\017 -\006\003\125\004\013\023\010\064\065\067\066\060\070\055\113\061 -\046\060\044\006\003\125\004\003\023\035\104\151\147\151\163\151 -\147\156\040\123\145\162\166\145\162\040\111\104\040\055\040\050 -\105\156\162\151\143\150\051 -END -CKA_ID UTF8 "0" -CKA_ISSUER MULTILINE_OCTAL -\060\201\264\061\024\060\022\006\003\125\004\012\023\013\105\156 -\164\162\165\163\164\056\156\145\164\061\100\060\076\006\003\125 -\004\013\024\067\167\167\167\056\145\156\164\162\165\163\164\056 -\156\145\164\057\103\120\123\137\062\060\064\070\040\151\156\143 -\157\162\160\056\040\142\171\040\162\145\146\056\040\050\154\151 -\155\151\164\163\040\154\151\141\142\056\051\061\045\060\043\006 -\003\125\004\013\023\034\050\143\051\040\061\071\071\071\040\105 -\156\164\162\165\163\164\056\156\145\164\040\114\151\155\151\164 -\145\144\061\063\060\061\006\003\125\004\003\023\052\105\156\164 -\162\165\163\164\056\156\145\164\040\103\145\162\164\151\146\151 -\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171 -\040\050\062\060\064\070\051 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\006\007\377\377\377\377\377 -END -CKA_VALUE MULTILINE_OCTAL -\060\202\004\320\060\202\003\270\240\003\002\001\002\002\006\007 -\377\377\377\377\377\060\015\006\011\052\206\110\206\367\015\001 -\001\005\005\000\060\201\264\061\024\060\022\006\003\125\004\012 -\023\013\105\156\164\162\165\163\164\056\156\145\164\061\100\060 -\076\006\003\125\004\013\024\067\167\167\167\056\145\156\164\162 -\165\163\164\056\156\145\164\057\103\120\123\137\062\060\064\070 -\040\151\156\143\157\162\160\056\040\142\171\040\162\145\146\056 -\040\050\154\151\155\151\164\163\040\154\151\141\142\056\051\061 -\045\060\043\006\003\125\004\013\023\034\050\143\051\040\061\071 -\071\071\040\105\156\164\162\165\163\164\056\156\145\164\040\114 -\151\155\151\164\145\144\061\063\060\061\006\003\125\004\003\023 -\052\105\156\164\162\165\163\164\056\156\145\164\040\103\145\162 -\164\151\146\151\143\141\164\151\157\156\040\101\165\164\150\157 -\162\151\164\171\040\050\062\060\064\070\051\060\036\027\015\061 -\060\060\067\061\066\061\067\062\063\063\070\132\027\015\061\065 -\060\067\061\066\061\067\065\063\063\070\132\060\145\061\013\060 -\011\006\003\125\004\006\023\002\115\131\061\033\060\031\006\003 -\125\004\012\023\022\104\151\147\151\143\145\162\164\040\123\144 -\156\056\040\102\150\144\056\061\021\060\017\006\003\125\004\013 -\023\010\064\065\067\066\060\070\055\113\061\046\060\044\006\003 -\125\004\003\023\035\104\151\147\151\163\151\147\156\040\123\145 -\162\166\145\162\040\111\104\040\055\040\050\105\156\162\151\143 -\150\051\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\305\211\344\364\015\006\100\222\131\307\032\263\065 -\321\016\114\052\063\371\370\257\312\236\177\356\271\247\155\140 -\364\124\350\157\325\233\363\033\143\061\004\150\162\321\064\026 -\214\264\027\054\227\336\163\305\330\220\025\240\032\053\365\313 -\263\110\206\104\360\035\210\114\316\101\102\032\357\365\014\336 -\376\100\332\071\040\367\006\125\072\152\235\106\301\322\157\245 -\262\310\127\076\051\243\234\340\351\205\167\146\350\230\247\044 -\176\276\300\131\040\345\104\157\266\127\330\276\316\302\145\167 -\130\306\141\101\321\164\004\310\177\111\102\305\162\251\162\026 -\356\214\335\022\135\264\112\324\321\257\120\267\330\252\165\166 -\150\255\076\135\252\060\155\141\250\253\020\133\076\023\277\063 -\340\257\104\235\070\042\133\357\114\057\246\161\046\025\046\312 -\050\214\331\372\216\216\251\242\024\065\342\233\044\210\264\364 -\177\205\235\203\117\007\241\266\024\220\066\304\064\034\215\046 -\141\155\023\157\170\276\350\217\047\307\113\204\226\243\206\150 -\014\043\276\013\354\214\224\000\251\004\212\023\220\367\337\205 -\154\014\261\002\003\001\000\001\243\202\001\064\060\202\001\060 -\060\016\006\003\125\035\017\001\001\377\004\004\003\002\001\006 -\060\022\006\003\125\035\023\001\001\377\004\010\060\006\001\001 -\377\002\001\000\060\047\006\003\125\035\045\004\040\060\036\006 -\010\053\006\001\005\005\007\003\001\006\010\053\006\001\005\005 -\007\003\002\006\010\053\006\001\005\005\007\003\004\060\063\006 -\010\053\006\001\005\005\007\001\001\004\047\060\045\060\043\006 -\010\053\006\001\005\005\007\060\001\206\027\150\164\164\160\072 -\057\057\157\143\163\160\056\145\156\164\162\165\163\164\056\156 -\145\164\060\104\006\003\125\035\040\004\075\060\073\060\071\006 -\005\140\203\112\001\001\060\060\060\056\006\010\053\006\001\005 -\005\007\002\001\026\042\150\164\164\160\072\057\057\167\167\167 -\056\144\151\147\151\143\145\162\164\056\143\157\155\056\155\171 -\057\143\160\163\056\150\164\155\060\062\006\003\125\035\037\004 -\053\060\051\060\047\240\045\240\043\206\041\150\164\164\160\072 -\057\057\143\162\154\056\145\156\164\162\165\163\164\056\156\145 -\164\057\062\060\064\070\143\141\056\143\162\154\060\021\006\003 -\125\035\016\004\012\004\010\114\116\314\045\050\003\051\201\060 -\037\006\003\125\035\043\004\030\060\026\200\024\125\344\201\321 -\021\200\276\330\211\271\010\243\061\371\241\044\011\026\271\160 -\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\003 -\202\001\001\000\227\114\357\112\072\111\254\162\374\060\040\153 -\264\051\133\247\305\225\004\220\371\062\325\302\205\152\336\003 -\241\067\371\211\000\260\132\254\125\176\333\103\065\377\311\001 -\370\121\276\314\046\312\310\152\244\304\124\076\046\036\347\014 -\243\315\227\147\224\335\246\102\353\134\315\217\071\171\153\063 -\171\041\006\171\372\202\104\025\231\314\301\267\071\323\106\142 -\174\262\160\353\157\316\040\252\076\031\267\351\164\202\234\264 -\245\113\115\141\000\067\344\207\322\362\024\072\144\174\270\251 -\173\141\340\223\042\347\325\237\076\107\346\066\166\240\123\330 -\000\003\072\017\265\063\376\226\312\323\322\202\072\056\335\327 -\110\341\344\247\151\314\034\351\231\112\347\312\160\105\327\013 -\007\016\232\165\033\320\057\222\157\366\244\007\303\275\034\113 -\246\204\266\175\250\232\251\322\247\051\361\013\127\151\036\227 -\127\046\354\053\103\254\324\105\203\005\000\351\343\360\106\100 -\007\372\352\261\121\163\223\034\245\335\123\021\067\310\052\247 -\025\047\035\264\252\314\177\252\061\060\374\270\105\237\110\011 -\355\020\342\305 -END - -# Trust for Certificate "Explicitly Distrusted Malaysian Digicert Sdn. Bhd. (en)" -# Issuer: CN=Entrust.net Certification Authority (2048),OU=(c) 1999 Entrust.net Limited,OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.),O=Entrust.net -# Serial Number:07:ff:ff:ff:ff:ff -# Subject: CN=Digisign Server ID - (Enrich),OU=457608-K,O=Digicert Sdn. Bhd.,C=MY -# Not Valid Before: Fri Jul 16 17:23:38 2010 -# Not Valid After : Thu Jul 16 17:53:38 2015 -# Fingerprint (MD5): D7:69:61:7F:35:0F:9C:46:A3:AA:EB:F8:55:FC:84:F2 -# Fingerprint (SHA1): 6B:3C:3B:80:AD:CA:A6:BA:8A:9F:54:A6:7A:ED:12:69:05:6D:31:26 -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 "Explicitly Distrusted Malaysian Digicert Sdn. Bhd. (en)" -CKA_CERT_SHA1_HASH MULTILINE_OCTAL -\153\074\073\200\255\312\246\272\212\237\124\246\172\355\022\151 -\005\155\061\046 -END -CKA_CERT_MD5_HASH MULTILINE_OCTAL -\327\151\141\177\065\017\234\106\243\252\353\370\125\374\204\362 -END -CKA_ISSUER MULTILINE_OCTAL -\060\201\264\061\024\060\022\006\003\125\004\012\023\013\105\156 -\164\162\165\163\164\056\156\145\164\061\100\060\076\006\003\125 -\004\013\024\067\167\167\167\056\145\156\164\162\165\163\164\056 -\156\145\164\057\103\120\123\137\062\060\064\070\040\151\156\143 -\157\162\160\056\040\142\171\040\162\145\146\056\040\050\154\151 -\155\151\164\163\040\154\151\141\142\056\051\061\045\060\043\006 -\003\125\004\013\023\034\050\143\051\040\061\071\071\071\040\105 -\156\164\162\165\163\164\056\156\145\164\040\114\151\155\151\164 -\145\144\061\063\060\061\006\003\125\004\003\023\052\105\156\164 -\162\165\163\164\056\156\145\164\040\103\145\162\164\151\146\151 -\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171 -\040\050\062\060\064\070\051 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\006\007\377\377\377\377\377 -END -CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED -CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED -CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED -CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE - - -# # Certificate "Security Communication RootCA2" # # Issuer: OU=Security Communication RootCA2,O="SECOM Trust Systems CO.,LTD.",C=JP @@ -16900,372 +13058,6 @@ CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE # -# Certificate "StartCom Certification Authority" -# -# Issuer: CN=StartCom Certification Authority,OU=Secure Digital Certificate Signing,O=StartCom Ltd.,C=IL -# Serial Number: 45 (0x2d) -# Subject: CN=StartCom Certification Authority,OU=Secure Digital Certificate Signing,O=StartCom Ltd.,C=IL -# Not Valid Before: Sun Sep 17 19:46:37 2006 -# Not Valid After : Wed Sep 17 19:46:36 2036 -# Fingerprint (MD5): C9:3B:0D:84:41:FC:A4:76:79:23:08:57:DE:10:19:16 -# Fingerprint (SHA1): A3:F1:33:3F:E2:42:BF:CF:C5:D1:4E:8F:39:42:98:40:68:10:D1:A0 -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 "StartCom Certification Authority" -CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 -CKA_SUBJECT MULTILINE_OCTAL -\060\175\061\013\060\011\006\003\125\004\006\023\002\111\114\061 -\026\060\024\006\003\125\004\012\023\015\123\164\141\162\164\103 -\157\155\040\114\164\144\056\061\053\060\051\006\003\125\004\013 -\023\042\123\145\143\165\162\145\040\104\151\147\151\164\141\154 -\040\103\145\162\164\151\146\151\143\141\164\145\040\123\151\147 -\156\151\156\147\061\051\060\047\006\003\125\004\003\023\040\123 -\164\141\162\164\103\157\155\040\103\145\162\164\151\146\151\143 -\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171 -END -CKA_ID UTF8 "0" -CKA_ISSUER MULTILINE_OCTAL -\060\175\061\013\060\011\006\003\125\004\006\023\002\111\114\061 -\026\060\024\006\003\125\004\012\023\015\123\164\141\162\164\103 -\157\155\040\114\164\144\056\061\053\060\051\006\003\125\004\013 -\023\042\123\145\143\165\162\145\040\104\151\147\151\164\141\154 -\040\103\145\162\164\151\146\151\143\141\164\145\040\123\151\147 -\156\151\156\147\061\051\060\047\006\003\125\004\003\023\040\123 -\164\141\162\164\103\157\155\040\103\145\162\164\151\146\151\143 -\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\001\055 -END -CKA_VALUE MULTILINE_OCTAL -\060\202\007\207\060\202\005\157\240\003\002\001\002\002\001\055 -\060\015\006\011\052\206\110\206\367\015\001\001\013\005\000\060 -\175\061\013\060\011\006\003\125\004\006\023\002\111\114\061\026 -\060\024\006\003\125\004\012\023\015\123\164\141\162\164\103\157 -\155\040\114\164\144\056\061\053\060\051\006\003\125\004\013\023 -\042\123\145\143\165\162\145\040\104\151\147\151\164\141\154\040 -\103\145\162\164\151\146\151\143\141\164\145\040\123\151\147\156 -\151\156\147\061\051\060\047\006\003\125\004\003\023\040\123\164 -\141\162\164\103\157\155\040\103\145\162\164\151\146\151\143\141 -\164\151\157\156\040\101\165\164\150\157\162\151\164\171\060\036 -\027\015\060\066\060\071\061\067\061\071\064\066\063\067\132\027 -\015\063\066\060\071\061\067\061\071\064\066\063\066\132\060\175 -\061\013\060\011\006\003\125\004\006\023\002\111\114\061\026\060 -\024\006\003\125\004\012\023\015\123\164\141\162\164\103\157\155 -\040\114\164\144\056\061\053\060\051\006\003\125\004\013\023\042 -\123\145\143\165\162\145\040\104\151\147\151\164\141\154\040\103 -\145\162\164\151\146\151\143\141\164\145\040\123\151\147\156\151 -\156\147\061\051\060\047\006\003\125\004\003\023\040\123\164\141 -\162\164\103\157\155\040\103\145\162\164\151\146\151\143\141\164 -\151\157\156\040\101\165\164\150\157\162\151\164\171\060\202\002 -\042\060\015\006\011\052\206\110\206\367\015\001\001\001\005\000 -\003\202\002\017\000\060\202\002\012\002\202\002\001\000\301\210 -\333\011\274\154\106\174\170\237\225\173\265\063\220\362\162\142 -\326\301\066\040\042\044\136\316\351\167\362\103\012\242\006\144 -\244\314\216\066\370\070\346\043\360\156\155\261\074\335\162\243 -\205\034\241\323\075\264\063\053\323\057\257\376\352\260\101\131 -\147\266\304\006\175\012\236\164\205\326\171\114\200\067\172\337 -\071\005\122\131\367\364\033\106\103\244\322\205\205\322\303\161 -\363\165\142\064\272\054\212\177\036\217\356\355\064\320\021\307 -\226\315\122\075\272\063\326\335\115\336\013\073\112\113\237\302 -\046\057\372\265\026\034\162\065\167\312\074\135\346\312\341\046 -\213\032\066\166\134\001\333\164\024\045\376\355\265\240\210\017 -\335\170\312\055\037\007\227\060\001\055\162\171\372\106\326\023 -\052\250\271\246\253\203\111\035\345\362\357\335\344\001\216\030 -\012\217\143\123\026\205\142\251\016\031\072\314\265\146\246\302 -\153\164\007\344\053\341\166\076\264\155\330\366\104\341\163\142 -\037\073\304\276\240\123\126\045\154\121\011\367\252\253\312\277 -\166\375\155\233\363\235\333\277\075\146\274\014\126\252\257\230 -\110\225\072\113\337\247\130\120\331\070\165\251\133\352\103\014 -\002\377\231\353\350\154\115\160\133\051\145\234\335\252\135\314 -\257\001\061\354\014\353\322\215\350\352\234\173\346\156\367\047 -\146\014\032\110\327\156\102\343\077\336\041\076\173\341\015\160 -\373\143\252\250\154\032\124\264\134\045\172\311\242\311\213\026 -\246\273\054\176\027\136\005\115\130\156\022\035\001\356\022\020 -\015\306\062\177\030\377\374\364\372\315\156\221\350\066\111\276 -\032\110\151\213\302\226\115\032\022\262\151\027\301\012\220\326 -\372\171\042\110\277\272\173\151\370\160\307\372\172\067\330\330 -\015\322\166\117\127\377\220\267\343\221\322\335\357\302\140\267 -\147\072\335\376\252\234\360\324\213\177\162\042\316\306\237\227 -\266\370\257\212\240\020\250\331\373\030\306\266\265\134\122\074 -\211\266\031\052\163\001\012\017\003\263\022\140\362\172\057\201 -\333\243\156\377\046\060\227\365\213\335\211\127\266\255\075\263 -\257\053\305\267\166\002\360\245\326\053\232\206\024\052\162\366 -\343\063\214\135\011\113\023\337\273\214\164\023\122\113\002\003 -\001\000\001\243\202\002\020\060\202\002\014\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\116\013\357\032\244\100\133\245\027 -\151\207\060\312\064\150\103\320\101\256\362\060\037\006\003\125 -\035\043\004\030\060\026\200\024\116\013\357\032\244\100\133\245 -\027\151\207\060\312\064\150\103\320\101\256\362\060\202\001\132 -\006\003\125\035\040\004\202\001\121\060\202\001\115\060\202\001 -\111\006\013\053\006\001\004\001\201\265\067\001\001\001\060\202 -\001\070\060\056\006\010\053\006\001\005\005\007\002\001\026\042 -\150\164\164\160\072\057\057\167\167\167\056\163\164\141\162\164 -\163\163\154\056\143\157\155\057\160\157\154\151\143\171\056\160 -\144\146\060\064\006\010\053\006\001\005\005\007\002\001\026\050 -\150\164\164\160\072\057\057\167\167\167\056\163\164\141\162\164 -\163\163\154\056\143\157\155\057\151\156\164\145\162\155\145\144 -\151\141\164\145\056\160\144\146\060\201\317\006\010\053\006\001 -\005\005\007\002\002\060\201\302\060\047\026\040\123\164\141\162 -\164\040\103\157\155\155\145\162\143\151\141\154\040\050\123\164 -\141\162\164\103\157\155\051\040\114\164\144\056\060\003\002\001 -\001\032\201\226\114\151\155\151\164\145\144\040\114\151\141\142 -\151\154\151\164\171\054\040\162\145\141\144\040\164\150\145\040 -\163\145\143\164\151\157\156\040\052\114\145\147\141\154\040\114 -\151\155\151\164\141\164\151\157\156\163\052\040\157\146\040\164 -\150\145\040\123\164\141\162\164\103\157\155\040\103\145\162\164 -\151\146\151\143\141\164\151\157\156\040\101\165\164\150\157\162 -\151\164\171\040\120\157\154\151\143\171\040\141\166\141\151\154 -\141\142\154\145\040\141\164\040\150\164\164\160\072\057\057\167 -\167\167\056\163\164\141\162\164\163\163\154\056\143\157\155\057 -\160\157\154\151\143\171\056\160\144\146\060\021\006\011\140\206 -\110\001\206\370\102\001\001\004\004\003\002\000\007\060\070\006 -\011\140\206\110\001\206\370\102\001\015\004\053\026\051\123\164 -\141\162\164\103\157\155\040\106\162\145\145\040\123\123\114\040 -\103\145\162\164\151\146\151\143\141\164\151\157\156\040\101\165 -\164\150\157\162\151\164\171\060\015\006\011\052\206\110\206\367 -\015\001\001\013\005\000\003\202\002\001\000\216\217\347\334\224 -\171\174\361\205\177\237\111\157\153\312\135\373\214\376\004\305 -\301\142\321\175\102\212\274\123\267\224\003\146\060\077\261\347 -\012\247\120\040\125\045\177\166\172\024\015\353\004\016\100\346 -\076\330\210\253\007\047\203\251\165\246\067\163\307\375\113\322 -\115\255\027\100\310\106\276\073\177\121\374\303\266\005\061\334 -\315\205\042\116\161\267\362\161\136\260\032\306\272\223\213\170 -\222\112\205\370\170\017\203\376\057\255\054\367\344\244\273\055 -\320\347\015\072\270\076\316\366\170\366\256\107\044\312\243\065 -\066\316\307\306\207\230\332\354\373\351\262\316\047\233\210\303 -\004\241\366\013\131\150\257\311\333\020\017\115\366\144\143\134 -\245\022\157\222\262\223\224\307\210\027\016\223\266\176\142\213 -\220\177\253\116\237\374\343\165\024\117\052\062\337\133\015\340 -\365\173\223\015\253\241\317\207\341\245\004\105\350\074\022\245 -\011\305\260\321\267\123\363\140\024\272\205\151\152\041\174\037 -\165\141\027\040\027\173\154\073\101\051\134\341\254\132\321\315 -\214\233\353\140\035\031\354\367\345\260\332\371\171\030\245\105 -\077\111\103\127\322\335\044\325\054\243\375\221\215\047\265\345 -\353\024\006\232\114\173\041\273\072\255\060\006\030\300\330\301 -\153\054\177\131\134\135\221\261\160\042\127\353\212\153\110\112 -\325\017\051\354\306\100\300\057\210\114\150\001\027\167\364\044 -\031\117\275\372\341\262\040\041\113\335\032\330\051\175\252\270 -\336\124\354\041\125\200\154\036\365\060\310\243\020\345\262\346 -\052\024\061\303\205\055\214\230\261\206\132\117\211\131\055\271 -\307\367\034\310\212\177\300\235\005\112\346\102\117\142\243\155 -\051\244\037\205\253\333\345\201\310\255\052\075\114\135\133\204 -\046\161\304\205\136\161\044\312\245\033\154\330\141\323\032\340 -\124\333\316\272\251\062\265\042\366\163\101\011\135\270\027\135 -\016\017\231\220\326\107\332\157\012\072\142\050\024\147\202\331 -\361\320\200\131\233\313\061\330\233\017\214\167\116\265\150\212 -\362\154\366\044\016\055\154\160\305\163\321\336\024\320\161\217 -\266\323\173\002\366\343\270\324\011\156\153\236\165\204\071\346 -\177\045\245\362\110\000\300\244\001\332\077 -END -CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE - -# Trust for "StartCom Certification Authority" -# Issuer: CN=StartCom Certification Authority,OU=Secure Digital Certificate Signing,O=StartCom Ltd.,C=IL -# Serial Number: 45 (0x2d) -# Subject: CN=StartCom Certification Authority,OU=Secure Digital Certificate Signing,O=StartCom Ltd.,C=IL -# Not Valid Before: Sun Sep 17 19:46:37 2006 -# Not Valid After : Wed Sep 17 19:46:36 2036 -# Fingerprint (MD5): C9:3B:0D:84:41:FC:A4:76:79:23:08:57:DE:10:19:16 -# Fingerprint (SHA1): A3:F1:33:3F:E2:42:BF:CF:C5:D1:4E:8F:39:42:98:40:68:10:D1:A0 -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 "StartCom Certification Authority" -CKA_CERT_SHA1_HASH MULTILINE_OCTAL -\243\361\063\077\342\102\277\317\305\321\116\217\071\102\230\100 -\150\020\321\240 -END -CKA_CERT_MD5_HASH MULTILINE_OCTAL -\311\073\015\204\101\374\244\166\171\043\010\127\336\020\031\026 -END -CKA_ISSUER MULTILINE_OCTAL -\060\175\061\013\060\011\006\003\125\004\006\023\002\111\114\061 -\026\060\024\006\003\125\004\012\023\015\123\164\141\162\164\103 -\157\155\040\114\164\144\056\061\053\060\051\006\003\125\004\013 -\023\042\123\145\143\165\162\145\040\104\151\147\151\164\141\154 -\040\103\145\162\164\151\146\151\143\141\164\145\040\123\151\147 -\156\151\156\147\061\051\060\047\006\003\125\004\003\023\040\123 -\164\141\162\164\103\157\155\040\103\145\162\164\151\146\151\143 -\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\001\055 -END -CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR -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 "StartCom Certification Authority G2" -# -# Issuer: CN=StartCom Certification Authority G2,O=StartCom Ltd.,C=IL -# Serial Number: 59 (0x3b) -# Subject: CN=StartCom Certification Authority G2,O=StartCom Ltd.,C=IL -# Not Valid Before: Fri Jan 01 01:00:01 2010 -# Not Valid After : Sat Dec 31 23:59:01 2039 -# Fingerprint (MD5): 78:4B:FB:9E:64:82:0A:D3:B8:4C:62:F3:64:F2:90:64 -# Fingerprint (SHA1): 31:F1:FD:68:22:63:20:EE:C6:3B:3F:9D:EA:4A:3E:53:7C:7C:39:17 -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 "StartCom Certification Authority G2" -CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 -CKA_SUBJECT MULTILINE_OCTAL -\060\123\061\013\060\011\006\003\125\004\006\023\002\111\114\061 -\026\060\024\006\003\125\004\012\023\015\123\164\141\162\164\103 -\157\155\040\114\164\144\056\061\054\060\052\006\003\125\004\003 -\023\043\123\164\141\162\164\103\157\155\040\103\145\162\164\151 -\146\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151 -\164\171\040\107\062 -END -CKA_ID UTF8 "0" -CKA_ISSUER MULTILINE_OCTAL -\060\123\061\013\060\011\006\003\125\004\006\023\002\111\114\061 -\026\060\024\006\003\125\004\012\023\015\123\164\141\162\164\103 -\157\155\040\114\164\144\056\061\054\060\052\006\003\125\004\003 -\023\043\123\164\141\162\164\103\157\155\040\103\145\162\164\151 -\146\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151 -\164\171\040\107\062 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\001\073 -END -CKA_VALUE MULTILINE_OCTAL -\060\202\005\143\060\202\003\113\240\003\002\001\002\002\001\073 -\060\015\006\011\052\206\110\206\367\015\001\001\013\005\000\060 -\123\061\013\060\011\006\003\125\004\006\023\002\111\114\061\026 -\060\024\006\003\125\004\012\023\015\123\164\141\162\164\103\157 -\155\040\114\164\144\056\061\054\060\052\006\003\125\004\003\023 -\043\123\164\141\162\164\103\157\155\040\103\145\162\164\151\146 -\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164 -\171\040\107\062\060\036\027\015\061\060\060\061\060\061\060\061 -\060\060\060\061\132\027\015\063\071\061\062\063\061\062\063\065 -\071\060\061\132\060\123\061\013\060\011\006\003\125\004\006\023 -\002\111\114\061\026\060\024\006\003\125\004\012\023\015\123\164 -\141\162\164\103\157\155\040\114\164\144\056\061\054\060\052\006 -\003\125\004\003\023\043\123\164\141\162\164\103\157\155\040\103 -\145\162\164\151\146\151\143\141\164\151\157\156\040\101\165\164 -\150\157\162\151\164\171\040\107\062\060\202\002\042\060\015\006 -\011\052\206\110\206\367\015\001\001\001\005\000\003\202\002\017 -\000\060\202\002\012\002\202\002\001\000\266\211\066\133\007\267 -\040\066\275\202\273\341\026\040\003\225\172\257\016\243\125\311 -\045\231\112\305\320\126\101\207\220\115\041\140\244\024\207\073 -\315\375\262\076\264\147\003\152\355\341\017\113\300\221\205\160 -\105\340\102\236\336\051\043\324\001\015\240\020\171\270\333\003 -\275\363\251\057\321\306\340\017\313\236\212\024\012\270\275\366 -\126\142\361\305\162\266\062\045\331\262\363\275\145\305\015\054 -\156\325\222\157\030\213\000\101\024\202\157\100\040\046\172\050 -\017\365\036\177\047\367\224\261\067\075\267\307\221\367\342\001 -\354\375\224\211\341\314\156\323\066\326\012\031\171\256\327\064 -\202\145\377\174\102\273\266\335\013\246\064\257\113\140\376\177 -\103\111\006\213\214\103\270\126\362\331\177\041\103\027\352\247 -\110\225\001\165\165\352\053\245\103\225\352\025\204\235\010\215 -\046\156\125\233\253\334\322\071\322\061\035\140\342\254\314\126 -\105\044\365\034\124\253\356\206\335\226\062\205\370\114\117\350 -\225\166\266\005\335\066\043\147\274\377\025\342\312\073\346\246 -\354\073\354\046\021\064\110\215\366\200\053\032\043\002\353\212 -\034\072\166\052\173\126\026\034\162\052\263\252\343\140\245\000 -\237\004\233\342\157\036\024\130\133\245\154\213\130\074\303\272 -\116\072\134\367\341\226\053\076\357\007\274\244\345\135\314\115 -\237\015\341\334\252\273\341\156\032\354\217\341\266\114\115\171 -\162\135\027\065\013\035\327\301\107\332\226\044\340\320\162\250 -\132\137\146\055\020\334\057\052\023\256\046\376\012\034\031\314 -\320\076\013\234\310\011\056\371\133\226\172\107\234\351\172\363 -\005\120\164\225\163\236\060\011\363\227\202\136\346\217\071\010 -\036\131\345\065\024\102\023\377\000\234\367\276\252\120\317\342 -\121\110\327\270\157\257\370\116\176\063\230\222\024\142\072\165 -\143\317\173\372\336\202\073\251\273\071\342\304\275\054\000\016 -\310\027\254\023\357\115\045\216\330\263\220\057\251\332\051\175 -\035\257\164\072\262\047\300\301\036\076\165\243\026\251\257\172 -\042\135\237\023\032\317\247\240\353\343\206\012\323\375\346\226 -\225\327\043\310\067\335\304\174\252\066\254\230\032\022\261\340 -\116\350\261\073\365\326\157\361\060\327\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\113 -\305\264\100\153\255\034\263\245\034\145\156\106\066\211\207\005 -\014\016\266\060\015\006\011\052\206\110\206\367\015\001\001\013 -\005\000\003\202\002\001\000\163\127\077\054\325\225\062\176\067 -\333\226\222\353\031\136\176\123\347\101\354\021\266\107\357\265 -\336\355\164\134\305\361\216\111\340\374\156\231\023\315\237\212 -\332\315\072\012\330\072\132\011\077\137\064\320\057\003\322\146 -\035\032\275\234\220\067\310\014\216\007\132\224\105\106\052\346 -\276\172\332\241\251\244\151\022\222\260\175\066\324\104\207\327 -\121\361\051\143\326\165\315\026\344\047\211\035\370\302\062\110 -\375\333\231\320\217\137\124\164\314\254\147\064\021\142\331\014 -\012\067\207\321\243\027\110\216\322\027\035\366\327\375\333\145 -\353\375\250\324\365\326\117\244\133\165\350\305\322\140\262\333 -\011\176\045\213\173\272\122\222\236\076\350\305\167\241\074\340 -\112\163\153\141\317\206\334\103\377\377\041\376\043\135\044\112 -\365\323\155\017\142\004\005\127\202\332\156\244\063\045\171\113 -\056\124\031\213\314\054\075\060\351\321\006\377\350\062\106\276 -\265\063\166\167\250\001\135\226\301\301\325\276\256\045\300\311 -\036\012\011\040\210\241\016\311\363\157\115\202\124\000\040\247 -\322\217\344\071\124\027\056\215\036\270\033\273\033\275\232\116 -\073\020\064\334\234\210\123\357\242\061\133\130\117\221\142\310 -\302\232\232\315\025\135\070\251\326\276\370\023\265\237\022\151 -\362\120\142\254\373\027\067\364\356\270\165\147\140\020\373\203 -\120\371\104\265\165\234\100\027\262\376\375\171\135\156\130\130 -\137\060\374\000\256\257\063\301\016\116\154\272\247\246\241\177 -\062\333\070\340\261\162\027\012\053\221\354\152\143\046\355\211 -\324\170\314\164\036\005\370\153\376\214\152\166\071\051\256\145 -\043\022\225\010\042\034\227\316\133\006\356\014\342\273\274\037 -\104\223\366\330\070\105\005\041\355\344\255\253\022\266\003\244 -\102\056\055\304\011\072\003\147\151\204\232\341\131\220\212\050 -\205\325\135\164\261\321\016\040\130\233\023\245\260\143\246\355 -\173\107\375\105\125\060\244\356\232\324\346\342\207\357\230\311 -\062\202\021\051\042\274\000\012\061\136\055\017\300\216\351\153 -\262\217\056\006\330\321\221\307\306\022\364\114\375\060\027\303 -\301\332\070\133\343\251\352\346\241\272\171\357\163\330\266\123 -\127\055\366\320\341\327\110 -END -CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE - -# Trust for "StartCom Certification Authority G2" -# Issuer: CN=StartCom Certification Authority G2,O=StartCom Ltd.,C=IL -# Serial Number: 59 (0x3b) -# Subject: CN=StartCom Certification Authority G2,O=StartCom Ltd.,C=IL -# Not Valid Before: Fri Jan 01 01:00:01 2010 -# Not Valid After : Sat Dec 31 23:59:01 2039 -# Fingerprint (MD5): 78:4B:FB:9E:64:82:0A:D3:B8:4C:62:F3:64:F2:90:64 -# Fingerprint (SHA1): 31:F1:FD:68:22:63:20:EE:C6:3B:3F:9D:EA:4A:3E:53:7C:7C:39:17 -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 "StartCom Certification Authority G2" -CKA_CERT_SHA1_HASH MULTILINE_OCTAL -\061\361\375\150\042\143\040\356\306\073\077\235\352\112\076\123 -\174\174\071\027 -END -CKA_CERT_MD5_HASH MULTILINE_OCTAL -\170\113\373\236\144\202\012\323\270\114\142\363\144\362\220\144 -END -CKA_ISSUER MULTILINE_OCTAL -\060\123\061\013\060\011\006\003\125\004\006\023\002\111\114\061 -\026\060\024\006\003\125\004\012\023\015\123\164\141\162\164\103 -\157\155\040\114\164\144\056\061\054\060\052\006\003\125\004\003 -\023\043\123\164\141\162\164\103\157\155\040\103\145\162\164\151 -\146\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151 -\164\171\040\107\062 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\001\073 -END -CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR -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 "Buypass Class 2 Root CA" # # Issuer: CN=Buypass Class 2 Root CA,O=Buypass AS-983163327,C=NO @@ -17947,172 +13739,6 @@ CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE # -# Certificate "TURKTRUST Certificate Services Provider Root 2007" -# -# Issuer: O=T..RKTRUST Bilgi ..leti..im ve Bili..im G..venli..i Hizmetleri A...,L=Ankara,C=TR,CN=T..RKTRUST Elektronik Sertifika Hizmet Sa..lay..c..s.. -# Serial Number: 1 (0x1) -# Subject: O=T..RKTRUST Bilgi ..leti..im ve Bili..im G..venli..i Hizmetleri A...,L=Ankara,C=TR,CN=T..RKTRUST Elektronik Sertifika Hizmet Sa..lay..c..s.. -# Not Valid Before: Tue Dec 25 18:37:19 2007 -# Not Valid After : Fri Dec 22 18:37:19 2017 -# Fingerprint (MD5): 2B:70:20:56:86:82:A0:18:C8:07:53:12:28:70:21:72 -# Fingerprint (SHA1): F1:7F:6F:B6:31:DC:99:E3:A3:C8:7F:FE:1C:F1:81:10:88:D9:60:33 -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 "TURKTRUST Certificate Services Provider Root 2007" -CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 -CKA_SUBJECT MULTILINE_OCTAL -\060\201\277\061\077\060\075\006\003\125\004\003\014\066\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\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\136\060\134\006\003\125\004\012\014\125\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\040\050\143\051\040\101\162\141\154\304\261\153\040\062\060 -\060\067 -END -CKA_ID UTF8 "0" -CKA_ISSUER MULTILINE_OCTAL -\060\201\277\061\077\060\075\006\003\125\004\003\014\066\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\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\136\060\134\006\003\125\004\012\014\125\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\040\050\143\051\040\101\162\141\154\304\261\153\040\062\060 -\060\067 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\001\001 -END -CKA_VALUE MULTILINE_OCTAL -\060\202\004\075\060\202\003\045\240\003\002\001\002\002\001\001 -\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060 -\201\277\061\077\060\075\006\003\125\004\003\014\066\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\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\136\060\134\006\003\125\004\012\014\125\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 -\040\050\143\051\040\101\162\141\154\304\261\153\040\062\060\060 -\067\060\036\027\015\060\067\061\062\062\065\061\070\063\067\061 -\071\132\027\015\061\067\061\062\062\062\061\070\063\067\061\071 -\132\060\201\277\061\077\060\075\006\003\125\004\003\014\066\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\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\136\060\134\006\003\125\004\012\014\125\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\040\050\143\051\040\101\162\141\154\304\261\153\040\062 -\060\060\067\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\253\267\076\012\214\310\245\130\025\346\212\357 -\047\075\112\264\350\045\323\315\063\302\040\334\031\356\210\077 -\115\142\360\335\023\167\217\141\251\052\265\324\362\271\061\130 -\051\073\057\077\152\234\157\163\166\045\356\064\040\200\356\352 -\267\360\304\012\315\053\206\224\311\343\140\261\104\122\262\132 -\051\264\221\227\203\330\267\246\024\057\051\111\242\363\005\006 -\373\264\117\332\241\154\232\146\237\360\103\011\312\352\162\217 -\353\000\327\065\071\327\126\027\107\027\060\364\276\277\077\302 -\150\257\066\100\301\251\364\251\247\350\020\153\010\212\367\206 -\036\334\232\052\025\006\366\243\360\364\340\307\024\324\121\177 -\317\264\333\155\257\107\226\027\233\167\161\330\247\161\235\044 -\014\366\224\077\205\061\022\117\272\356\116\202\270\271\076\217 -\043\067\136\314\242\252\165\367\030\157\011\323\256\247\124\050 -\064\373\341\340\073\140\175\240\276\171\211\206\310\237\055\371 -\012\113\304\120\242\347\375\171\026\307\172\013\030\317\316\114 -\357\175\326\007\157\230\361\257\261\301\172\327\201\065\270\252 -\027\264\340\313\002\003\001\000\001\243\102\060\100\060\035\006 -\003\125\035\016\004\026\004\024\051\305\220\253\045\257\021\344 -\141\277\243\377\210\141\221\346\016\376\234\201\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\005\005\000\003\202\001\001 -\000\020\015\332\370\072\354\050\321\024\225\202\261\022\054\121 -\172\101\045\066\114\237\354\077\037\204\235\145\124\134\250\026 -\002\100\372\156\032\067\204\357\162\235\206\012\125\235\126\050 -\254\146\054\320\072\126\223\064\007\045\255\010\260\217\310\017 -\011\131\312\235\230\034\345\124\370\271\105\177\152\227\157\210 -\150\115\112\006\046\067\210\002\016\266\306\326\162\231\316\153 -\167\332\142\061\244\126\037\256\137\215\167\332\135\366\210\374 -\032\331\236\265\201\360\062\270\343\210\320\234\363\152\240\271 -\233\024\131\065\066\117\317\363\216\136\135\027\255\025\225\330 -\335\262\325\025\156\000\116\263\113\317\146\224\344\340\315\265 -\005\332\143\127\213\345\263\252\333\300\056\034\220\104\333\032 -\135\030\244\356\276\004\133\231\325\161\137\125\145\144\142\325 -\242\233\004\131\206\310\142\167\347\174\202\105\152\075\027\277 -\354\235\165\014\256\243\157\132\323\057\230\066\364\360\365\031 -\253\021\135\310\246\343\052\130\152\102\011\303\275\222\046\146 -\062\015\135\010\125\164\377\214\230\320\012\246\204\152\321\071 -\175 -END -CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE - -# Trust for "TURKTRUST Certificate Services Provider Root 2007" -# Issuer: O=T..RKTRUST Bilgi ..leti..im ve Bili..im G..venli..i Hizmetleri A...,L=Ankara,C=TR,CN=T..RKTRUST Elektronik Sertifika Hizmet Sa..lay..c..s.. -# Serial Number: 1 (0x1) -# Subject: O=T..RKTRUST Bilgi ..leti..im ve Bili..im G..venli..i Hizmetleri A...,L=Ankara,C=TR,CN=T..RKTRUST Elektronik Sertifika Hizmet Sa..lay..c..s.. -# Not Valid Before: Tue Dec 25 18:37:19 2007 -# Not Valid After : Fri Dec 22 18:37:19 2017 -# Fingerprint (MD5): 2B:70:20:56:86:82:A0:18:C8:07:53:12:28:70:21:72 -# Fingerprint (SHA1): F1:7F:6F:B6:31:DC:99:E3:A3:C8:7F:FE:1C:F1:81:10:88:D9:60:33 -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 "TURKTRUST Certificate Services Provider Root 2007" -CKA_CERT_SHA1_HASH MULTILINE_OCTAL -\361\177\157\266\061\334\231\343\243\310\177\376\034\361\201\020 -\210\331\140\063 -END -CKA_CERT_MD5_HASH MULTILINE_OCTAL -\053\160\040\126\206\202\240\030\310\007\123\022\050\160\041\162 -END -CKA_ISSUER MULTILINE_OCTAL -\060\201\277\061\077\060\075\006\003\125\004\003\014\066\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\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\136\060\134\006\003\125\004\012\014\125\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\040\050\143\051\040\101\162\141\154\304\261\153\040\062\060 -\060\067 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\001\001 -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 "D-TRUST Root Class 3 CA 2 2009" # # Issuer: CN=D-TRUST Root Class 3 CA 2 2009,O=D-Trust GmbH,C=DE @@ -18399,269 +14025,6 @@ CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE # -# Certificate "PSCProcert" -# -# Issuer: E=acraiz@suscerte.gob.ve,OU=Superintendencia de Servicios de Certificacion Electronica,O=Sistema Nacional de Certificacion Electronica,ST=Distrito Capital,L=Caracas,C=VE,CN=Autoridad de Certificacion Raiz del Estado Venezolano -# Serial Number: 11 (0xb) -# Subject: CN=PSCProcert,C=VE,O=Sistema Nacional de Certificacion Electronica,OU=Proveedor de Certificados PROCERT,ST=Miranda,L=Chacao,E=contacto@procert.net.ve -# Not Valid Before: Tue Dec 28 16:51:00 2010 -# Not Valid After : Fri Dec 25 23:59:59 2020 -# Fingerprint (MD5): E6:24:E9:12:01:AE:0C:DE:8E:85:C4:CE:A3:12:DD:EC -# Fingerprint (SHA1): 70:C1:8D:74:B4:28:81:0A:E4:FD:A5:75:D7:01:9F:99:B0:3D:50:74 -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 "PSCProcert" -CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 -CKA_SUBJECT MULTILINE_OCTAL -\060\201\321\061\046\060\044\006\011\052\206\110\206\367\015\001 -\011\001\026\027\143\157\156\164\141\143\164\157\100\160\162\157 -\143\145\162\164\056\156\145\164\056\166\145\061\017\060\015\006 -\003\125\004\007\023\006\103\150\141\143\141\157\061\020\060\016 -\006\003\125\004\010\023\007\115\151\162\141\156\144\141\061\052 -\060\050\006\003\125\004\013\023\041\120\162\157\166\145\145\144 -\157\162\040\144\145\040\103\145\162\164\151\146\151\143\141\144 -\157\163\040\120\122\117\103\105\122\124\061\066\060\064\006\003 -\125\004\012\023\055\123\151\163\164\145\155\141\040\116\141\143 -\151\157\156\141\154\040\144\145\040\103\145\162\164\151\146\151 -\143\141\143\151\157\156\040\105\154\145\143\164\162\157\156\151 -\143\141\061\013\060\011\006\003\125\004\006\023\002\126\105\061 -\023\060\021\006\003\125\004\003\023\012\120\123\103\120\162\157 -\143\145\162\164 -END -CKA_ID UTF8 "0" -CKA_ISSUER MULTILINE_OCTAL -\060\202\001\036\061\076\060\074\006\003\125\004\003\023\065\101 -\165\164\157\162\151\144\141\144\040\144\145\040\103\145\162\164 -\151\146\151\143\141\143\151\157\156\040\122\141\151\172\040\144 -\145\154\040\105\163\164\141\144\157\040\126\145\156\145\172\157 -\154\141\156\157\061\013\060\011\006\003\125\004\006\023\002\126 -\105\061\020\060\016\006\003\125\004\007\023\007\103\141\162\141 -\143\141\163\061\031\060\027\006\003\125\004\010\023\020\104\151 -\163\164\162\151\164\157\040\103\141\160\151\164\141\154\061\066 -\060\064\006\003\125\004\012\023\055\123\151\163\164\145\155\141 -\040\116\141\143\151\157\156\141\154\040\144\145\040\103\145\162 -\164\151\146\151\143\141\143\151\157\156\040\105\154\145\143\164 -\162\157\156\151\143\141\061\103\060\101\006\003\125\004\013\023 -\072\123\165\160\145\162\151\156\164\145\156\144\145\156\143\151 -\141\040\144\145\040\123\145\162\166\151\143\151\157\163\040\144 -\145\040\103\145\162\164\151\146\151\143\141\143\151\157\156\040 -\105\154\145\143\164\162\157\156\151\143\141\061\045\060\043\006 -\011\052\206\110\206\367\015\001\011\001\026\026\141\143\162\141 -\151\172\100\163\165\163\143\145\162\164\145\056\147\157\142\056 -\166\145 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\001\013 -END -CKA_VALUE MULTILINE_OCTAL -\060\202\011\206\060\202\007\156\240\003\002\001\002\002\001\013 -\060\015\006\011\052\206\110\206\367\015\001\001\013\005\000\060 -\202\001\036\061\076\060\074\006\003\125\004\003\023\065\101\165 -\164\157\162\151\144\141\144\040\144\145\040\103\145\162\164\151 -\146\151\143\141\143\151\157\156\040\122\141\151\172\040\144\145 -\154\040\105\163\164\141\144\157\040\126\145\156\145\172\157\154 -\141\156\157\061\013\060\011\006\003\125\004\006\023\002\126\105 -\061\020\060\016\006\003\125\004\007\023\007\103\141\162\141\143 -\141\163\061\031\060\027\006\003\125\004\010\023\020\104\151\163 -\164\162\151\164\157\040\103\141\160\151\164\141\154\061\066\060 -\064\006\003\125\004\012\023\055\123\151\163\164\145\155\141\040 -\116\141\143\151\157\156\141\154\040\144\145\040\103\145\162\164 -\151\146\151\143\141\143\151\157\156\040\105\154\145\143\164\162 -\157\156\151\143\141\061\103\060\101\006\003\125\004\013\023\072 -\123\165\160\145\162\151\156\164\145\156\144\145\156\143\151\141 -\040\144\145\040\123\145\162\166\151\143\151\157\163\040\144\145 -\040\103\145\162\164\151\146\151\143\141\143\151\157\156\040\105 -\154\145\143\164\162\157\156\151\143\141\061\045\060\043\006\011 -\052\206\110\206\367\015\001\011\001\026\026\141\143\162\141\151 -\172\100\163\165\163\143\145\162\164\145\056\147\157\142\056\166 -\145\060\036\027\015\061\060\061\062\062\070\061\066\065\061\060 -\060\132\027\015\062\060\061\062\062\065\062\063\065\071\065\071 -\132\060\201\321\061\046\060\044\006\011\052\206\110\206\367\015 -\001\011\001\026\027\143\157\156\164\141\143\164\157\100\160\162 -\157\143\145\162\164\056\156\145\164\056\166\145\061\017\060\015 -\006\003\125\004\007\023\006\103\150\141\143\141\157\061\020\060 -\016\006\003\125\004\010\023\007\115\151\162\141\156\144\141\061 -\052\060\050\006\003\125\004\013\023\041\120\162\157\166\145\145 -\144\157\162\040\144\145\040\103\145\162\164\151\146\151\143\141 -\144\157\163\040\120\122\117\103\105\122\124\061\066\060\064\006 -\003\125\004\012\023\055\123\151\163\164\145\155\141\040\116\141 -\143\151\157\156\141\154\040\144\145\040\103\145\162\164\151\146 -\151\143\141\143\151\157\156\040\105\154\145\143\164\162\157\156 -\151\143\141\061\013\060\011\006\003\125\004\006\023\002\126\105 -\061\023\060\021\006\003\125\004\003\023\012\120\123\103\120\162 -\157\143\145\162\164\060\202\002\042\060\015\006\011\052\206\110 -\206\367\015\001\001\001\005\000\003\202\002\017\000\060\202\002 -\012\002\202\002\001\000\325\267\364\243\224\063\241\106\251\125 -\141\111\015\250\207\163\136\221\055\160\301\006\032\224\332\075 -\354\025\102\301\365\214\256\152\027\361\212\255\374\200\225\352 -\203\104\242\133\172\125\316\117\247\245\325\272\270\037\240\047 -\300\120\123\076\215\271\300\016\270\025\334\326\154\370\236\370 -\004\045\337\200\217\020\205\335\175\057\173\200\335\127\000\144 -\043\370\156\311\276\225\117\341\165\354\340\176\136\225\315\261 -\357\276\172\102\330\311\054\323\353\032\032\042\213\267\177\006 -\211\345\074\365\022\300\273\323\013\231\137\220\174\216\055\057 -\167\063\222\112\041\106\250\251\010\254\361\366\021\002\331\225 -\026\236\215\057\226\346\002\335\165\302\024\052\132\326\311\175 -\045\302\301\374\252\147\205\342\354\276\321\174\074\372\257\325 -\156\377\123\101\324\365\062\070\261\342\137\304\371\216\020\357 -\006\251\002\211\377\343\014\156\227\340\337\235\333\041\320\364 -\076\010\151\154\330\324\344\066\370\203\266\262\066\217\234\357 -\072\067\026\175\277\242\151\327\073\133\162\320\257\252\077\134 -\146\223\254\012\042\141\266\322\240\231\310\124\223\135\250\266 -\321\275\135\012\136\167\224\242\055\300\202\216\274\312\003\052 -\064\256\163\361\324\265\014\275\276\147\233\124\353\341\372\240 -\132\354\070\176\076\301\314\242\307\104\061\165\352\077\345\007 -\322\253\241\045\226\366\346\344\240\135\067\030\071\141\000\063 -\135\106\324\000\304\264\312\074\361\242\243\076\363\072\377\151 -\060\056\100\335\366\237\234\046\311\226\067\255\347\071\242\277 -\352\151\333\125\042\225\123\052\224\265\337\255\026\070\201\165 -\146\343\307\054\033\223\234\252\214\243\312\331\154\074\027\155 -\234\334\174\123\340\040\047\103\066\371\022\341\074\134\275\146 -\277\242\151\043\070\270\231\140\231\016\126\123\072\234\176\024 -\214\260\006\157\361\206\166\220\257\375\257\376\220\306\217\237 -\177\213\222\043\234\347\025\166\217\325\213\224\023\162\151\373 -\053\141\143\210\357\346\244\136\346\243\027\152\130\107\313\161 -\117\024\013\136\310\002\010\046\242\313\351\257\153\212\031\307 -\313\024\126\365\341\332\265\331\374\277\163\070\332\371\347\257 -\156\244\067\342\007\047\002\003\001\000\001\243\202\003\027\060 -\202\003\023\060\022\006\003\125\035\023\001\001\377\004\010\060 -\006\001\001\377\002\001\001\060\067\006\003\125\035\022\004\060 -\060\056\202\017\163\165\163\143\145\162\164\145\056\147\157\142 -\056\166\145\240\033\006\005\140\206\136\002\002\240\022\014\020 -\122\111\106\055\107\055\062\060\060\060\064\060\063\066\055\060 -\060\035\006\003\125\035\016\004\026\004\024\101\017\031\070\252 -\231\177\102\013\244\327\047\230\124\242\027\114\055\121\124\060 -\202\001\120\006\003\125\035\043\004\202\001\107\060\202\001\103 -\200\024\255\273\042\035\306\340\322\001\250\375\166\120\122\223 -\355\230\301\115\256\323\241\202\001\046\244\202\001\042\060\202 -\001\036\061\076\060\074\006\003\125\004\003\023\065\101\165\164 -\157\162\151\144\141\144\040\144\145\040\103\145\162\164\151\146 -\151\143\141\143\151\157\156\040\122\141\151\172\040\144\145\154 -\040\105\163\164\141\144\157\040\126\145\156\145\172\157\154\141 -\156\157\061\013\060\011\006\003\125\004\006\023\002\126\105\061 -\020\060\016\006\003\125\004\007\023\007\103\141\162\141\143\141 -\163\061\031\060\027\006\003\125\004\010\023\020\104\151\163\164 -\162\151\164\157\040\103\141\160\151\164\141\154\061\066\060\064 -\006\003\125\004\012\023\055\123\151\163\164\145\155\141\040\116 -\141\143\151\157\156\141\154\040\144\145\040\103\145\162\164\151 -\146\151\143\141\143\151\157\156\040\105\154\145\143\164\162\157 -\156\151\143\141\061\103\060\101\006\003\125\004\013\023\072\123 -\165\160\145\162\151\156\164\145\156\144\145\156\143\151\141\040 -\144\145\040\123\145\162\166\151\143\151\157\163\040\144\145\040 -\103\145\162\164\151\146\151\143\141\143\151\157\156\040\105\154 -\145\143\164\162\157\156\151\143\141\061\045\060\043\006\011\052 -\206\110\206\367\015\001\011\001\026\026\141\143\162\141\151\172 -\100\163\165\163\143\145\162\164\145\056\147\157\142\056\166\145 -\202\001\012\060\016\006\003\125\035\017\001\001\377\004\004\003 -\002\001\006\060\115\006\003\125\035\021\004\106\060\104\202\016 -\160\162\157\143\145\162\164\056\156\145\164\056\166\145\240\025 -\006\005\140\206\136\002\001\240\014\014\012\120\123\103\055\060 -\060\060\060\060\062\240\033\006\005\140\206\136\002\002\240\022 -\014\020\122\111\106\055\112\055\063\061\066\063\065\063\067\063 -\055\067\060\166\006\003\125\035\037\004\157\060\155\060\106\240 -\104\240\102\206\100\150\164\164\160\072\057\057\167\167\167\056 -\163\165\163\143\145\162\164\145\056\147\157\142\056\166\145\057 -\154\143\162\057\103\105\122\124\111\106\111\103\101\104\117\055 -\122\101\111\132\055\123\110\101\063\070\064\103\122\114\104\105 -\122\056\143\162\154\060\043\240\041\240\037\206\035\154\144\141 -\160\072\057\057\141\143\162\141\151\172\056\163\165\163\143\145 -\162\164\145\056\147\157\142\056\166\145\060\067\006\010\053\006 -\001\005\005\007\001\001\004\053\060\051\060\047\006\010\053\006 -\001\005\005\007\060\001\206\033\150\164\164\160\072\057\057\157 -\143\163\160\056\163\165\163\143\145\162\164\145\056\147\157\142 -\056\166\145\060\101\006\003\125\035\040\004\072\060\070\060\066 -\006\006\140\206\136\003\001\002\060\054\060\052\006\010\053\006 -\001\005\005\007\002\001\026\036\150\164\164\160\072\057\057\167 -\167\167\056\163\165\163\143\145\162\164\145\056\147\157\142\056 -\166\145\057\144\160\143\060\015\006\011\052\206\110\206\367\015 -\001\001\013\005\000\003\202\002\001\000\053\131\353\042\231\273 -\204\252\117\336\220\306\321\206\161\043\236\113\003\221\107\160 -\273\300\222\140\354\340\324\347\155\306\323\355\147\203\167\122 -\325\362\345\167\247\066\262\343\124\276\331\273\012\233\021\357 -\141\364\306\231\063\231\365\257\000\071\215\203\277\246\275\065 -\176\054\134\061\064\157\154\333\363\144\001\230\252\224\054\101 -\335\025\206\312\153\051\116\026\300\111\374\327\203\110\023\007 -\121\204\061\122\210\273\206\027\307\153\057\212\040\255\305\013 -\217\160\076\052\273\033\161\217\271\244\240\375\330\225\331\257 -\131\277\045\053\230\351\143\223\057\140\036\304\252\370\167\365 -\213\154\057\355\176\056\265\117\100\015\356\274\127\167\347\331 -\266\324\077\225\047\072\040\325\345\256\253\154\065\237\301\241 -\035\131\334\204\201\356\115\007\342\110\266\236\113\225\055\101 -\261\341\350\336\176\057\005\036\150\356\277\273\220\145\072\310 -\356\352\261\030\067\034\142\223\244\240\061\354\161\154\221\346 -\244\171\211\132\024\247\024\120\005\114\244\000\127\060\054\301 -\265\141\226\334\076\036\204\257\071\102\317\345\320\054\261\044 -\274\337\100\303\355\177\143\112\275\341\117\022\144\206\225\363 -\260\347\310\267\341\123\275\222\346\363\014\226\271\353\350\346 -\222\355\247\201\011\024\013\374\225\172\317\217\326\064\117\066 -\022\334\136\321\064\165\306\106\200\057\225\004\214\307\206\304 -\250\046\211\250\077\031\233\201\273\121\244\112\206\253\013\021 -\017\261\256\143\123\155\050\352\335\063\126\070\034\262\255\200 -\323\327\162\275\232\154\231\143\350\000\273\101\166\005\267\133 -\231\030\212\303\270\022\134\126\317\126\014\175\350\342\317\355 -\274\164\107\373\356\323\027\116\042\117\126\377\120\363\056\346 -\071\246\202\326\161\312\336\267\325\272\150\010\355\231\314\375 -\242\222\313\151\270\235\371\012\244\246\076\117\223\050\052\141 -\154\007\046\000\377\226\137\150\206\270\270\316\312\125\340\253 -\261\075\177\230\327\063\016\132\075\330\170\302\304\140\057\307 -\142\360\141\221\322\070\260\366\236\125\333\100\200\005\022\063 -\316\035\222\233\321\151\263\377\277\361\222\012\141\065\077\335 -\376\206\364\274\340\032\161\263\142\246 -END -CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE - -# Trust for "PSCProcert" -# Issuer: E=acraiz@suscerte.gob.ve,OU=Superintendencia de Servicios de Certificacion Electronica,O=Sistema Nacional de Certificacion Electronica,ST=Distrito Capital,L=Caracas,C=VE,CN=Autoridad de Certificacion Raiz del Estado Venezolano -# Serial Number: 11 (0xb) -# Subject: CN=PSCProcert,C=VE,O=Sistema Nacional de Certificacion Electronica,OU=Proveedor de Certificados PROCERT,ST=Miranda,L=Chacao,E=contacto@procert.net.ve -# Not Valid Before: Tue Dec 28 16:51:00 2010 -# Not Valid After : Fri Dec 25 23:59:59 2020 -# Fingerprint (MD5): E6:24:E9:12:01:AE:0C:DE:8E:85:C4:CE:A3:12:DD:EC -# Fingerprint (SHA1): 70:C1:8D:74:B4:28:81:0A:E4:FD:A5:75:D7:01:9F:99:B0:3D:50:74 -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 "PSCProcert" -CKA_CERT_SHA1_HASH MULTILINE_OCTAL -\160\301\215\164\264\050\201\012\344\375\245\165\327\001\237\231 -\260\075\120\164 -END -CKA_CERT_MD5_HASH MULTILINE_OCTAL -\346\044\351\022\001\256\014\336\216\205\304\316\243\022\335\354 -END -CKA_ISSUER MULTILINE_OCTAL -\060\202\001\036\061\076\060\074\006\003\125\004\003\023\065\101 -\165\164\157\162\151\144\141\144\040\144\145\040\103\145\162\164 -\151\146\151\143\141\143\151\157\156\040\122\141\151\172\040\144 -\145\154\040\105\163\164\141\144\157\040\126\145\156\145\172\157 -\154\141\156\157\061\013\060\011\006\003\125\004\006\023\002\126 -\105\061\020\060\016\006\003\125\004\007\023\007\103\141\162\141 -\143\141\163\061\031\060\027\006\003\125\004\010\023\020\104\151 -\163\164\162\151\164\157\040\103\141\160\151\164\141\154\061\066 -\060\064\006\003\125\004\012\023\055\123\151\163\164\145\155\141 -\040\116\141\143\151\157\156\141\154\040\144\145\040\103\145\162 -\164\151\146\151\143\141\143\151\157\156\040\105\154\145\143\164 -\162\157\156\151\143\141\061\103\060\101\006\003\125\004\013\023 -\072\123\165\160\145\162\151\156\164\145\156\144\145\156\143\151 -\141\040\144\145\040\123\145\162\166\151\143\151\157\163\040\144 -\145\040\103\145\162\164\151\146\151\143\141\143\151\157\156\040 -\105\154\145\143\164\162\157\156\151\143\141\061\045\060\043\006 -\011\052\206\110\206\367\015\001\011\001\026\026\141\143\162\141 -\151\172\100\163\165\163\143\145\162\164\145\056\147\157\142\056 -\166\145 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\001\013 -END -CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR -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 "Swisscom Root CA 2" # # Issuer: CN=Swisscom Root CA 2,OU=Digital Certificate Services,O=Swisscom,C=ch @@ -18837,169 +14200,6 @@ CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE # -# Certificate "CA Disig Root R1" -# -# Issuer: CN=CA Disig Root R1,O=Disig a.s.,L=Bratislava,C=SK -# Serial Number:00:c3:03:9a:ee:50:90:6e:28 -# Subject: CN=CA Disig Root R1,O=Disig a.s.,L=Bratislava,C=SK -# Not Valid Before: Thu Jul 19 09:06:56 2012 -# Not Valid After : Sat Jul 19 09:06:56 2042 -# Fingerprint (MD5): BE:EC:11:93:9A:F5:69:21:BC:D7:C1:C0:67:89:CC:2A -# Fingerprint (SHA1): 8E:1C:74:F8:A6:20:B9:E5:8A:F4:61:FA:EC:2B:47:56:51:1A:52:C6 -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 "CA Disig Root R1" -CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 -CKA_SUBJECT MULTILINE_OCTAL -\060\122\061\013\060\011\006\003\125\004\006\023\002\123\113\061 -\023\060\021\006\003\125\004\007\023\012\102\162\141\164\151\163 -\154\141\166\141\061\023\060\021\006\003\125\004\012\023\012\104 -\151\163\151\147\040\141\056\163\056\061\031\060\027\006\003\125 -\004\003\023\020\103\101\040\104\151\163\151\147\040\122\157\157 -\164\040\122\061 -END -CKA_ID UTF8 "0" -CKA_ISSUER MULTILINE_OCTAL -\060\122\061\013\060\011\006\003\125\004\006\023\002\123\113\061 -\023\060\021\006\003\125\004\007\023\012\102\162\141\164\151\163 -\154\141\166\141\061\023\060\021\006\003\125\004\012\023\012\104 -\151\163\151\147\040\141\056\163\056\061\031\060\027\006\003\125 -\004\003\023\020\103\101\040\104\151\163\151\147\040\122\157\157 -\164\040\122\061 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\011\000\303\003\232\356\120\220\156\050 -END -CKA_VALUE MULTILINE_OCTAL -\060\202\005\151\060\202\003\121\240\003\002\001\002\002\011\000 -\303\003\232\356\120\220\156\050\060\015\006\011\052\206\110\206 -\367\015\001\001\005\005\000\060\122\061\013\060\011\006\003\125 -\004\006\023\002\123\113\061\023\060\021\006\003\125\004\007\023 -\012\102\162\141\164\151\163\154\141\166\141\061\023\060\021\006 -\003\125\004\012\023\012\104\151\163\151\147\040\141\056\163\056 -\061\031\060\027\006\003\125\004\003\023\020\103\101\040\104\151 -\163\151\147\040\122\157\157\164\040\122\061\060\036\027\015\061 -\062\060\067\061\071\060\071\060\066\065\066\132\027\015\064\062 -\060\067\061\071\060\071\060\066\065\066\132\060\122\061\013\060 -\011\006\003\125\004\006\023\002\123\113\061\023\060\021\006\003 -\125\004\007\023\012\102\162\141\164\151\163\154\141\166\141\061 -\023\060\021\006\003\125\004\012\023\012\104\151\163\151\147\040 -\141\056\163\056\061\031\060\027\006\003\125\004\003\023\020\103 -\101\040\104\151\163\151\147\040\122\157\157\164\040\122\061\060 -\202\002\042\060\015\006\011\052\206\110\206\367\015\001\001\001 -\005\000\003\202\002\017\000\060\202\002\012\002\202\002\001\000 -\252\303\170\367\334\230\243\247\132\136\167\030\262\335\004\144 -\017\143\375\233\226\011\200\325\350\252\245\342\234\046\224\072 -\350\231\163\214\235\337\327\337\203\363\170\117\100\341\177\322 -\247\322\345\312\023\223\347\355\306\167\137\066\265\224\257\350 -\070\216\333\233\345\174\273\314\215\353\165\163\341\044\315\346 -\247\055\031\056\330\326\212\153\024\353\010\142\012\330\334\263 -\000\115\303\043\174\137\103\010\043\062\022\334\355\014\255\300 -\175\017\245\172\102\331\132\160\331\277\247\327\001\034\366\233 -\253\216\267\112\206\170\240\036\126\061\256\357\202\012\200\101 -\367\033\311\256\253\062\046\324\054\153\355\175\153\344\342\136 -\042\012\105\313\204\061\115\254\376\333\321\107\272\371\140\227 -\071\261\145\307\336\373\231\344\012\042\261\055\115\345\110\046 -\151\253\342\252\363\373\374\222\051\062\351\263\076\115\037\047 -\241\315\216\271\027\373\045\076\311\156\363\167\332\015\022\366 -\135\307\273\066\020\325\124\326\363\340\342\107\110\346\336\024 -\332\141\122\257\046\264\365\161\117\311\327\322\006\337\143\312 -\377\041\350\131\006\340\010\325\204\025\123\367\103\345\174\305 -\240\211\230\153\163\306\150\316\145\336\275\177\005\367\261\356 -\366\127\241\140\225\305\314\352\223\072\276\231\256\233\002\243 -\255\311\026\265\316\335\136\231\170\176\032\071\176\262\300\005 -\244\300\202\245\243\107\236\214\352\134\266\274\147\333\346\052 -\115\322\004\334\243\256\105\367\274\213\234\034\247\326\325\003 -\334\010\313\056\026\312\134\100\063\350\147\303\056\347\246\104 -\352\021\105\034\065\145\055\036\105\141\044\033\202\056\245\235 -\063\135\145\370\101\371\056\313\224\077\037\243\014\061\044\104 -\355\307\136\255\120\272\306\101\233\254\360\027\145\300\370\135 -\157\133\240\012\064\074\356\327\352\210\237\230\371\257\116\044 -\372\227\262\144\166\332\253\364\355\343\303\140\357\325\371\002 -\310\055\237\203\257\147\151\006\247\061\125\325\317\113\157\377 -\004\005\307\130\254\137\026\033\345\322\243\353\061\333\037\063 -\025\115\320\362\245\123\365\313\341\075\116\150\055\330\022\335 -\252\362\346\115\233\111\345\305\050\241\272\260\132\306\240\265 -\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\211\012\264\070\223\032\346\253\356\233\221 -\030\371\365\074\076\065\320\323\202\060\015\006\011\052\206\110 -\206\367\015\001\001\005\005\000\003\202\002\001\000\062\213\366 -\235\112\311\276\024\345\214\254\070\312\072\011\324\033\316\206 -\263\335\353\324\272\050\276\022\256\105\054\004\164\254\023\121 -\305\130\030\146\115\202\332\325\334\223\300\047\341\276\174\237 -\122\236\022\126\366\325\234\251\364\165\234\372\067\022\217\034 -\223\354\127\376\007\017\253\325\022\367\017\256\141\136\126\200 -\111\365\374\060\365\233\117\037\101\057\034\204\323\211\307\342 -\332\002\166\355\011\317\154\301\270\034\203\034\026\372\224\315 -\175\240\310\030\322\310\235\156\365\275\151\324\155\075\065\350 -\036\242\117\140\327\007\051\374\262\243\244\235\156\025\222\126 -\031\114\012\260\351\174\322\031\115\102\106\354\275\375\366\127 -\133\335\230\176\244\115\314\162\003\203\130\135\357\223\072\101 -\172\143\252\174\072\250\365\254\244\321\335\242\055\266\052\374 -\237\001\216\342\020\261\304\312\344\147\333\125\045\031\077\375 -\350\066\176\263\341\341\201\257\021\026\213\120\227\140\031\202 -\000\300\153\115\163\270\321\023\007\076\352\266\061\117\360\102 -\232\155\342\021\164\345\224\254\215\204\225\074\041\257\305\332 -\107\310\337\071\142\142\313\133\120\013\327\201\100\005\234\233 -\355\272\266\213\036\004\157\226\040\071\355\244\175\051\333\110 -\316\202\334\324\002\215\035\004\061\132\307\113\360\154\141\122 -\327\264\121\302\201\154\315\341\373\247\241\322\222\166\317\261 -\017\067\130\244\362\122\161\147\077\014\210\170\200\211\301\310 -\265\037\222\143\276\247\172\212\126\054\032\250\246\234\265\135 -\263\143\320\023\040\241\353\221\154\320\215\175\257\337\013\344 -\027\271\206\236\070\261\224\014\130\214\340\125\252\073\143\155 -\232\211\140\270\144\052\222\306\067\364\176\103\103\267\163\350 -\001\347\177\227\017\327\362\173\031\375\032\327\217\311\372\205 -\153\172\235\236\211\266\246\050\231\223\210\100\367\076\315\121 -\243\312\352\357\171\107\041\265\376\062\342\307\303\121\157\276 -\200\164\360\244\303\072\362\117\351\137\337\031\012\362\073\023 -\103\254\061\244\263\347\353\374\030\326\001\251\363\052\217\066 -\016\353\264\261\274\267\114\311\153\277\241\363\331\364\355\342 -\360\343\355\144\236\075\057\226\122\117\200\123\213 -END -CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE - -# Trust for "CA Disig Root R1" -# Issuer: CN=CA Disig Root R1,O=Disig a.s.,L=Bratislava,C=SK -# Serial Number:00:c3:03:9a:ee:50:90:6e:28 -# Subject: CN=CA Disig Root R1,O=Disig a.s.,L=Bratislava,C=SK -# Not Valid Before: Thu Jul 19 09:06:56 2012 -# Not Valid After : Sat Jul 19 09:06:56 2042 -# Fingerprint (MD5): BE:EC:11:93:9A:F5:69:21:BC:D7:C1:C0:67:89:CC:2A -# Fingerprint (SHA1): 8E:1C:74:F8:A6:20:B9:E5:8A:F4:61:FA:EC:2B:47:56:51:1A:52:C6 -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 "CA Disig Root R1" -CKA_CERT_SHA1_HASH MULTILINE_OCTAL -\216\034\164\370\246\040\271\345\212\364\141\372\354\053\107\126 -\121\032\122\306 -END -CKA_CERT_MD5_HASH MULTILINE_OCTAL -\276\354\021\223\232\365\151\041\274\327\301\300\147\211\314\052 -END -CKA_ISSUER MULTILINE_OCTAL -\060\122\061\013\060\011\006\003\125\004\006\023\002\123\113\061 -\023\060\021\006\003\125\004\007\023\012\102\162\141\164\151\163 -\154\141\166\141\061\023\060\021\006\003\125\004\012\023\012\104 -\151\163\151\147\040\141\056\163\056\061\031\060\027\006\003\125 -\004\003\023\020\103\101\040\104\151\163\151\147\040\122\157\157 -\164\040\122\061 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\011\000\303\003\232\356\120\220\156\050 -END -CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR -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 "CA Disig Root R2" # # Issuer: CN=CA Disig Root R2,O=Disig a.s.,L=Bratislava,C=SK @@ -21317,333 +16517,6 @@ CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE # -# Certificate "WoSign" -# -# Issuer: CN=Certification Authority of WoSign,O=WoSign CA Limited,C=CN -# Serial Number:5e:68:d6:11:71:94:63:50:56:00:68:f3:3e:c9:c5:91 -# Subject: CN=Certification Authority of WoSign,O=WoSign CA Limited,C=CN -# Not Valid Before: Sat Aug 08 01:00:01 2009 -# Not Valid After : Mon Aug 08 01:00:01 2039 -# Fingerprint (SHA-256): 4B:22:D5:A6:AE:C9:9F:3C:DB:79:AA:5E:C0:68:38:47:9C:D5:EC:BA:71:64:F7:F2:2D:C1:D6:5F:63:D8:57:08 -# Fingerprint (SHA1): B9:42:94:BF:91:EA:8F:B6:4B:E6:10:97:C7:FB:00:13:59:B6:76:CB -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 "WoSign" -CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 -CKA_SUBJECT MULTILINE_OCTAL -\060\125\061\013\060\011\006\003\125\004\006\023\002\103\116\061 -\032\060\030\006\003\125\004\012\023\021\127\157\123\151\147\156 -\040\103\101\040\114\151\155\151\164\145\144\061\052\060\050\006 -\003\125\004\003\023\041\103\145\162\164\151\146\151\143\141\164 -\151\157\156\040\101\165\164\150\157\162\151\164\171\040\157\146 -\040\127\157\123\151\147\156 -END -CKA_ID UTF8 "0" -CKA_ISSUER MULTILINE_OCTAL -\060\125\061\013\060\011\006\003\125\004\006\023\002\103\116\061 -\032\060\030\006\003\125\004\012\023\021\127\157\123\151\147\156 -\040\103\101\040\114\151\155\151\164\145\144\061\052\060\050\006 -\003\125\004\003\023\041\103\145\162\164\151\146\151\143\141\164 -\151\157\156\040\101\165\164\150\157\162\151\164\171\040\157\146 -\040\127\157\123\151\147\156 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\020\136\150\326\021\161\224\143\120\126\000\150\363\076\311 -\305\221 -END -CKA_VALUE MULTILINE_OCTAL -\060\202\005\166\060\202\003\136\240\003\002\001\002\002\020\136 -\150\326\021\161\224\143\120\126\000\150\363\076\311\305\221\060 -\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060\125 -\061\013\060\011\006\003\125\004\006\023\002\103\116\061\032\060 -\030\006\003\125\004\012\023\021\127\157\123\151\147\156\040\103 -\101\040\114\151\155\151\164\145\144\061\052\060\050\006\003\125 -\004\003\023\041\103\145\162\164\151\146\151\143\141\164\151\157 -\156\040\101\165\164\150\157\162\151\164\171\040\157\146\040\127 -\157\123\151\147\156\060\036\027\015\060\071\060\070\060\070\060 -\061\060\060\060\061\132\027\015\063\071\060\070\060\070\060\061 -\060\060\060\061\132\060\125\061\013\060\011\006\003\125\004\006 -\023\002\103\116\061\032\060\030\006\003\125\004\012\023\021\127 -\157\123\151\147\156\040\103\101\040\114\151\155\151\164\145\144 -\061\052\060\050\006\003\125\004\003\023\041\103\145\162\164\151 -\146\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151 -\164\171\040\157\146\040\127\157\123\151\147\156\060\202\002\042 -\060\015\006\011\052\206\110\206\367\015\001\001\001\005\000\003 -\202\002\017\000\060\202\002\012\002\202\002\001\000\275\312\215 -\254\270\221\025\126\227\173\153\134\172\302\336\153\331\241\260 -\303\020\043\372\247\241\262\314\061\372\076\331\246\051\157\026 -\075\340\153\370\270\100\137\333\071\250\000\172\213\240\115\124 -\175\302\042\170\374\216\011\270\250\205\327\314\225\227\113\164 -\330\236\176\360\000\344\016\211\256\111\050\104\032\020\231\062 -\017\045\210\123\244\015\263\017\022\010\026\013\003\161\047\034 -\177\341\333\322\375\147\150\304\005\135\012\016\135\160\327\330 -\227\240\274\123\101\232\221\215\364\236\066\146\172\176\126\301 -\220\137\346\261\150\040\066\244\214\044\054\054\107\013\131\166 -\146\060\265\276\336\355\217\370\235\323\273\001\060\346\362\363 -\016\340\054\222\200\363\205\371\050\212\264\124\056\232\355\367 -\166\374\025\150\026\353\112\154\353\056\022\217\324\317\376\014 -\307\134\035\013\176\005\062\276\136\260\011\052\102\325\311\116 -\220\263\131\015\273\172\176\315\325\010\132\264\177\330\034\151 -\021\371\047\017\173\006\257\124\203\030\173\341\335\124\172\121 -\150\156\167\374\306\277\122\112\146\106\241\262\147\032\273\243 -\117\167\240\276\135\377\374\126\013\103\162\167\220\312\236\371 -\362\071\365\015\251\364\352\327\347\263\020\057\060\102\067\041 -\314\060\160\311\206\230\017\314\130\115\203\273\175\345\032\245 -\067\215\266\254\062\227\000\072\143\161\044\036\236\067\304\377 -\164\324\067\300\342\376\210\106\140\021\335\010\077\120\066\253 -\270\172\244\225\142\152\156\260\312\152\041\132\151\363\363\373 -\035\160\071\225\363\247\156\246\201\211\241\210\305\073\161\312 -\243\122\356\203\273\375\240\167\364\344\157\347\102\333\155\112 -\231\212\064\110\274\027\334\344\200\010\042\266\362\061\300\077 -\004\076\353\237\040\171\326\270\006\144\144\002\061\327\251\315 -\122\373\204\105\151\011\000\052\334\125\213\304\006\106\113\300 -\112\035\011\133\071\050\375\251\253\316\000\371\056\110\113\046 -\346\060\114\245\130\312\264\104\202\117\347\221\036\063\303\260 -\223\377\021\374\201\322\312\037\161\051\335\166\117\222\045\257 -\035\201\267\017\057\214\303\006\314\057\047\243\112\344\016\231 -\272\174\036\105\037\177\252\031\105\226\375\374\075\002\003\001 -\000\001\243\102\060\100\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\035\006\003\125\035\016\004\026 -\004\024\341\146\317\016\321\361\263\113\267\006\040\024\376\207 -\022\325\366\376\373\076\060\015\006\011\052\206\110\206\367\015 -\001\001\005\005\000\003\202\002\001\000\250\313\162\100\262\166 -\301\176\173\374\255\144\343\062\173\314\074\266\135\106\323\365 -\054\342\160\135\310\056\330\006\175\230\321\013\041\240\211\131 -\044\001\235\371\257\011\175\012\043\202\064\325\374\174\162\231 -\271\243\327\124\364\352\122\160\016\305\365\326\073\341\072\011 -\062\346\041\071\223\275\263\025\352\117\152\364\365\213\077\057 -\174\215\130\056\305\341\071\240\076\307\075\112\163\236\100\172 -\300\053\141\251\147\311\363\044\271\263\155\125\054\132\035\236 -\045\162\316\013\255\252\307\125\142\013\276\373\143\263\141\104 -\043\243\313\341\032\016\367\232\006\115\336\324\043\116\041\226 -\133\071\133\127\035\057\135\010\136\011\171\377\174\227\265\115 -\203\256\015\326\346\243\171\340\063\320\231\226\002\060\247\076 -\377\322\243\103\077\005\132\006\352\104\002\332\174\370\110\320 -\063\251\371\007\307\225\341\365\076\365\135\161\272\362\225\251 -\164\210\141\131\343\277\312\132\023\272\162\264\214\135\066\207 -\351\246\305\074\023\277\336\320\104\046\356\267\354\056\160\372 -\327\235\267\254\345\305\100\132\346\327\154\173\054\303\126\233 -\107\315\013\316\372\033\264\041\327\267\146\270\364\045\060\213 -\134\015\271\352\147\262\364\155\256\325\241\236\117\330\237\351 -\047\002\260\035\006\326\217\343\373\110\022\237\177\021\241\020 -\076\114\121\072\226\260\321\023\361\307\330\046\256\072\312\221 -\304\151\235\337\001\051\144\121\157\150\332\024\354\010\101\227 -\220\215\320\262\200\362\317\302\075\277\221\150\305\200\147\036 -\304\140\023\125\325\141\231\127\174\272\225\017\141\111\072\312 -\165\274\311\012\223\077\147\016\022\362\050\342\061\033\300\127 -\026\337\010\174\031\301\176\017\037\205\036\012\066\174\133\176 -\047\274\172\277\340\333\364\332\122\275\336\014\124\160\061\221 -\103\225\310\274\360\076\335\011\176\060\144\120\355\177\001\244 -\063\147\115\150\117\276\025\357\260\366\002\021\242\033\023\045 -\072\334\302\131\361\343\134\106\273\147\054\002\106\352\036\110 -\246\346\133\331\265\274\121\242\222\226\333\252\306\067\042\246 -\376\314\040\164\243\055\251\056\153\313\300\202\021\041\265\223 -\171\356\104\206\276\327\036\344\036\373 -END -CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE - -# Trust for "WoSign" -# Issuer: CN=Certification Authority of WoSign,O=WoSign CA Limited,C=CN -# Serial Number:5e:68:d6:11:71:94:63:50:56:00:68:f3:3e:c9:c5:91 -# Subject: CN=Certification Authority of WoSign,O=WoSign CA Limited,C=CN -# Not Valid Before: Sat Aug 08 01:00:01 2009 -# Not Valid After : Mon Aug 08 01:00:01 2039 -# Fingerprint (SHA-256): 4B:22:D5:A6:AE:C9:9F:3C:DB:79:AA:5E:C0:68:38:47:9C:D5:EC:BA:71:64:F7:F2:2D:C1:D6:5F:63:D8:57:08 -# Fingerprint (SHA1): B9:42:94:BF:91:EA:8F:B6:4B:E6:10:97:C7:FB:00:13:59:B6:76:CB -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 "WoSign" -CKA_CERT_SHA1_HASH MULTILINE_OCTAL -\271\102\224\277\221\352\217\266\113\346\020\227\307\373\000\023 -\131\266\166\313 -END -CKA_CERT_MD5_HASH MULTILINE_OCTAL -\241\362\371\265\322\310\172\164\270\363\005\361\327\341\204\215 -END -CKA_ISSUER MULTILINE_OCTAL -\060\125\061\013\060\011\006\003\125\004\006\023\002\103\116\061 -\032\060\030\006\003\125\004\012\023\021\127\157\123\151\147\156 -\040\103\101\040\114\151\155\151\164\145\144\061\052\060\050\006 -\003\125\004\003\023\041\103\145\162\164\151\146\151\143\141\164 -\151\157\156\040\101\165\164\150\157\162\151\164\171\040\157\146 -\040\127\157\123\151\147\156 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\020\136\150\326\021\161\224\143\120\126\000\150\363\076\311 -\305\221 -END -CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR -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 "WoSign China" -# -# Issuer: CN=CA ...............,O=WoSign CA Limited,C=CN -# Serial Number:50:70:6b:cd:d8:13:fc:1b:4e:3b:33:72:d2:11:48:8d -# Subject: CN=CA ...............,O=WoSign CA Limited,C=CN -# Not Valid Before: Sat Aug 08 01:00:01 2009 -# Not Valid After : Mon Aug 08 01:00:01 2039 -# Fingerprint (SHA-256): D6:F0:34:BD:94:AA:23:3F:02:97:EC:A4:24:5B:28:39:73:E4:47:AA:59:0F:31:0C:77:F4:8F:DF:83:11:22:54 -# Fingerprint (SHA1): 16:32:47:8D:89:F9:21:3A:92:00:85:63:F5:A4:A7:D3:12:40:8A:D6 -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 "WoSign China" -CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 -CKA_SUBJECT MULTILINE_OCTAL -\060\106\061\013\060\011\006\003\125\004\006\023\002\103\116\061 -\032\060\030\006\003\125\004\012\023\021\127\157\123\151\147\156 -\040\103\101\040\114\151\155\151\164\145\144\061\033\060\031\006 -\003\125\004\003\014\022\103\101\040\346\262\203\351\200\232\346 -\240\271\350\257\201\344\271\246 -END -CKA_ID UTF8 "0" -CKA_ISSUER MULTILINE_OCTAL -\060\106\061\013\060\011\006\003\125\004\006\023\002\103\116\061 -\032\060\030\006\003\125\004\012\023\021\127\157\123\151\147\156 -\040\103\101\040\114\151\155\151\164\145\144\061\033\060\031\006 -\003\125\004\003\014\022\103\101\040\346\262\203\351\200\232\346 -\240\271\350\257\201\344\271\246 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\020\120\160\153\315\330\023\374\033\116\073\063\162\322\021 -\110\215 -END -CKA_VALUE MULTILINE_OCTAL -\060\202\005\130\060\202\003\100\240\003\002\001\002\002\020\120 -\160\153\315\330\023\374\033\116\073\063\162\322\021\110\215\060 -\015\006\011\052\206\110\206\367\015\001\001\013\005\000\060\106 -\061\013\060\011\006\003\125\004\006\023\002\103\116\061\032\060 -\030\006\003\125\004\012\023\021\127\157\123\151\147\156\040\103 -\101\040\114\151\155\151\164\145\144\061\033\060\031\006\003\125 -\004\003\014\022\103\101\040\346\262\203\351\200\232\346\240\271 -\350\257\201\344\271\246\060\036\027\015\060\071\060\070\060\070 -\060\061\060\060\060\061\132\027\015\063\071\060\070\060\070\060 -\061\060\060\060\061\132\060\106\061\013\060\011\006\003\125\004 -\006\023\002\103\116\061\032\060\030\006\003\125\004\012\023\021 -\127\157\123\151\147\156\040\103\101\040\114\151\155\151\164\145 -\144\061\033\060\031\006\003\125\004\003\014\022\103\101\040\346 -\262\203\351\200\232\346\240\271\350\257\201\344\271\246\060\202 -\002\042\060\015\006\011\052\206\110\206\367\015\001\001\001\005 -\000\003\202\002\017\000\060\202\002\012\002\202\002\001\000\320 -\111\041\036\045\374\207\301\052\302\254\333\166\206\006\116\347 -\320\164\064\334\355\145\065\374\120\326\210\077\244\360\177\353 -\017\137\171\057\211\261\375\274\143\130\067\223\233\070\370\267 -\133\251\372\330\161\307\264\274\200\227\215\154\113\361\120\325 -\052\051\252\250\031\172\226\346\225\216\164\355\227\012\127\165 -\364\005\333\155\013\071\271\001\177\252\366\326\332\154\346\005 -\340\244\115\122\374\333\320\164\267\021\214\173\215\117\377\207 -\203\256\377\005\003\023\127\120\067\376\214\226\122\020\114\137 -\277\224\161\151\331\226\076\014\103\117\276\060\300\237\071\164 -\117\006\105\135\243\326\126\071\150\007\314\207\117\120\167\223 -\161\331\104\010\261\212\064\351\211\254\333\233\116\341\331\344 -\122\105\214\056\024\037\221\153\031\035\150\051\054\126\304\342 -\036\023\127\144\360\141\343\271\021\337\260\341\127\240\033\255 -\327\137\321\257\333\053\055\077\320\150\216\017\352\237\017\213 -\065\130\033\023\034\364\336\065\241\012\135\326\352\337\022\157 -\300\373\151\007\106\162\334\201\366\004\043\027\340\115\165\341 -\162\157\260\050\353\233\341\341\203\241\237\112\135\257\314\233 -\372\002\040\266\030\142\167\221\073\243\325\145\255\334\174\220 -\167\034\104\101\244\112\213\353\225\162\351\366\011\144\334\250 -\055\237\164\170\350\301\242\011\143\234\357\240\333\117\235\225 -\253\040\117\267\260\367\207\134\246\240\344\067\070\307\134\343 -\065\017\054\255\243\200\242\354\056\135\300\317\355\213\005\302 -\346\163\156\366\211\325\365\322\106\216\352\155\143\033\036\212 -\311\175\246\370\234\353\345\325\143\205\115\163\146\151\021\376 -\310\016\364\301\307\146\111\123\176\344\031\153\361\351\172\131 -\243\155\176\305\027\346\047\306\357\033\333\157\374\015\115\006 -\001\264\016\134\060\106\125\140\257\070\145\072\312\107\272\254 -\054\314\106\037\262\106\226\077\363\355\046\005\356\167\241\152 -\153\176\055\155\130\134\112\324\216\147\270\361\332\325\106\212 -\047\371\021\362\311\102\376\116\336\337\037\134\304\244\206\207 -\026\063\241\247\027\030\245\015\344\005\345\053\302\053\013\242 -\225\220\271\375\140\074\116\211\076\347\234\356\037\273\001\002 -\003\001\000\001\243\102\060\100\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\035\006\003\125\035\016 -\004\026\004\024\340\115\277\334\233\101\135\023\350\144\360\247 -\351\025\244\341\201\301\272\061\060\015\006\011\052\206\110\206 -\367\015\001\001\013\005\000\003\202\002\001\000\152\212\160\070 -\131\266\332\213\030\310\276\052\323\266\031\325\146\051\172\135 -\315\133\057\163\034\046\116\243\175\157\253\267\051\115\246\351 -\245\021\203\247\071\163\257\020\104\222\346\045\135\117\141\372 -\310\006\276\116\113\357\376\363\061\376\306\174\160\012\101\130 -\332\350\231\113\226\311\170\274\230\174\002\051\355\011\200\346 -\012\072\202\002\052\342\311\057\310\126\031\046\356\170\034\043 -\375\367\223\145\116\347\363\230\230\257\315\335\331\236\100\210 -\061\050\072\253\056\013\260\254\014\044\372\172\046\230\363\022 -\141\020\364\135\027\367\176\342\170\227\124\342\214\350\051\272 -\214\020\062\275\335\063\153\070\206\176\071\075\016\003\162\247 -\135\171\217\105\212\131\256\133\041\156\061\106\325\131\215\317 -\025\137\335\061\045\317\333\140\326\201\104\162\051\002\127\366 -\226\324\326\377\352\051\333\071\305\270\054\212\032\215\316\313 -\347\102\061\206\005\150\016\236\024\335\000\220\272\151\105\010 -\333\156\220\201\206\247\052\005\077\346\204\071\370\267\371\127 -\137\114\244\171\132\020\014\136\325\153\377\065\137\005\121\036 -\154\243\165\251\317\120\203\323\174\364\146\367\202\215\075\014 -\175\350\337\173\250\016\033\054\234\256\100\160\207\332\355\247 -\026\202\132\276\065\154\040\116\042\141\331\274\121\172\315\172 -\141\334\113\021\371\376\147\064\317\056\004\146\141\134\127\227 -\043\214\363\206\033\110\337\052\257\247\301\377\330\216\076\003 -\273\330\052\260\372\024\045\262\121\153\206\103\205\056\007\043 -\026\200\215\114\373\264\143\073\314\303\164\355\033\243\036\376 -\065\017\137\174\035\026\206\365\016\303\225\361\057\257\135\045 -\073\121\346\327\166\101\070\321\113\003\071\050\245\036\221\162 -\324\175\253\227\063\304\323\076\340\151\266\050\171\240\011\215 -\034\321\377\101\162\110\006\374\232\056\347\040\371\233\242\336 -\211\355\256\074\011\257\312\127\263\222\211\160\100\344\057\117 -\302\160\203\100\327\044\054\153\347\011\037\323\325\307\301\010 -\364\333\016\073\034\007\013\103\021\204\041\206\351\200\324\165 -\330\253\361\002\142\301\261\176\125\141\317\023\327\046\260\327 -\234\313\051\213\070\112\013\016\220\215\272\241 -END -CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE - -# Trust for "WoSign China" -# Issuer: CN=CA ...............,O=WoSign CA Limited,C=CN -# Serial Number:50:70:6b:cd:d8:13:fc:1b:4e:3b:33:72:d2:11:48:8d -# Subject: CN=CA ...............,O=WoSign CA Limited,C=CN -# Not Valid Before: Sat Aug 08 01:00:01 2009 -# Not Valid After : Mon Aug 08 01:00:01 2039 -# Fingerprint (SHA-256): D6:F0:34:BD:94:AA:23:3F:02:97:EC:A4:24:5B:28:39:73:E4:47:AA:59:0F:31:0C:77:F4:8F:DF:83:11:22:54 -# Fingerprint (SHA1): 16:32:47:8D:89:F9:21:3A:92:00:85:63:F5:A4:A7:D3:12:40:8A:D6 -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 "WoSign China" -CKA_CERT_SHA1_HASH MULTILINE_OCTAL -\026\062\107\215\211\371\041\072\222\000\205\143\365\244\247\323 -\022\100\212\326 -END -CKA_CERT_MD5_HASH MULTILINE_OCTAL -\170\203\133\122\026\166\304\044\073\203\170\350\254\332\232\223 -END -CKA_ISSUER MULTILINE_OCTAL -\060\106\061\013\060\011\006\003\125\004\006\023\002\103\116\061 -\032\060\030\006\003\125\004\012\023\021\127\157\123\151\147\156 -\040\103\101\040\114\151\155\151\164\145\144\061\033\060\031\006 -\003\125\004\003\014\022\103\101\040\346\262\203\351\200\232\346 -\240\271\350\257\201\344\271\246 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\020\120\160\153\315\330\023\374\033\116\073\063\162\322\021 -\110\215 -END -CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR -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 "COMODO RSA Certification Authority" # # Issuer: CN=COMODO RSA Certification Authority,O=COMODO CA Limited,L=Salford,ST=Greater Manchester,C=GB @@ -22358,188 +17231,6 @@ CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE # -# Certificate "VeriSign-C3SSA-G2-temporary-intermediate-after-1024bit-removal" -# -# Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G5,OU="(c) 2006 VeriSign, Inc. - For authorized use only",OU=VeriSign Trust Network,O="VeriSign, Inc.",C=US -# Serial Number:2f:00:6e:cd:17:70:66:e7:5f:a3:82:0a:79:1f:05:ae -# Subject: CN=VeriSign Class 3 Secure Server CA - G2,OU=Terms of use at https://www.verisign.com/rpa (c)09,OU=VeriSign Trust Network,O="VeriSign, Inc.",C=US -# Not Valid Before: Thu Mar 26 00:00:00 2009 -# Not Valid After : Sun Mar 24 23:59:59 2019 -# Fingerprint (SHA-256): 0A:41:51:D5:E5:8B:84:B8:AC:E5:3A:5C:12:12:2A:C9:59:CD:69:91:FB:B3:8E:99:B5:76:C0:AB:DA:C3:58:14 -# Fingerprint (SHA1): 76:44:59:78:1B:AC:B0:47:63:A5:D0:A1:58:91:65:26:1F:29:8E:3B -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 "VeriSign-C3SSA-G2-temporary-intermediate-after-1024bit-removal" -CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 -CKA_SUBJECT MULTILINE_OCTAL -\060\201\265\061\013\060\011\006\003\125\004\006\023\002\125\123 -\061\027\060\025\006\003\125\004\012\023\016\126\145\162\151\123 -\151\147\156\054\040\111\156\143\056\061\037\060\035\006\003\125 -\004\013\023\026\126\145\162\151\123\151\147\156\040\124\162\165 -\163\164\040\116\145\164\167\157\162\153\061\073\060\071\006\003 -\125\004\013\023\062\124\145\162\155\163\040\157\146\040\165\163 -\145\040\141\164\040\150\164\164\160\163\072\057\057\167\167\167 -\056\166\145\162\151\163\151\147\156\056\143\157\155\057\162\160 -\141\040\050\143\051\060\071\061\057\060\055\006\003\125\004\003 -\023\046\126\145\162\151\123\151\147\156\040\103\154\141\163\163 -\040\063\040\123\145\143\165\162\145\040\123\145\162\166\145\162 -\040\103\101\040\055\040\107\062 -END -CKA_ID UTF8 "0" -CKA_ISSUER MULTILINE_OCTAL -\060\201\312\061\013\060\011\006\003\125\004\006\023\002\125\123 -\061\027\060\025\006\003\125\004\012\023\016\126\145\162\151\123 -\151\147\156\054\040\111\156\143\056\061\037\060\035\006\003\125 -\004\013\023\026\126\145\162\151\123\151\147\156\040\124\162\165 -\163\164\040\116\145\164\167\157\162\153\061\072\060\070\006\003 -\125\004\013\023\061\050\143\051\040\062\060\060\066\040\126\145 -\162\151\123\151\147\156\054\040\111\156\143\056\040\055\040\106 -\157\162\040\141\165\164\150\157\162\151\172\145\144\040\165\163 -\145\040\157\156\154\171\061\105\060\103\006\003\125\004\003\023 -\074\126\145\162\151\123\151\147\156\040\103\154\141\163\163\040 -\063\040\120\165\142\154\151\143\040\120\162\151\155\141\162\171 -\040\103\145\162\164\151\146\151\143\141\164\151\157\156\040\101 -\165\164\150\157\162\151\164\171\040\055\040\107\065 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\020\057\000\156\315\027\160\146\347\137\243\202\012\171\037 -\005\256 -END -CKA_VALUE MULTILINE_OCTAL -\060\202\005\071\060\202\004\041\240\003\002\001\002\002\020\057 -\000\156\315\027\160\146\347\137\243\202\012\171\037\005\256\060 -\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060\201 -\312\061\013\060\011\006\003\125\004\006\023\002\125\123\061\027 -\060\025\006\003\125\004\012\023\016\126\145\162\151\123\151\147 -\156\054\040\111\156\143\056\061\037\060\035\006\003\125\004\013 -\023\026\126\145\162\151\123\151\147\156\040\124\162\165\163\164 -\040\116\145\164\167\157\162\153\061\072\060\070\006\003\125\004 -\013\023\061\050\143\051\040\062\060\060\066\040\126\145\162\151 -\123\151\147\156\054\040\111\156\143\056\040\055\040\106\157\162 -\040\141\165\164\150\157\162\151\172\145\144\040\165\163\145\040 -\157\156\154\171\061\105\060\103\006\003\125\004\003\023\074\126 -\145\162\151\123\151\147\156\040\103\154\141\163\163\040\063\040 -\120\165\142\154\151\143\040\120\162\151\155\141\162\171\040\103 -\145\162\164\151\146\151\143\141\164\151\157\156\040\101\165\164 -\150\157\162\151\164\171\040\055\040\107\065\060\036\027\015\060 -\071\060\063\062\066\060\060\060\060\060\060\132\027\015\061\071 -\060\063\062\064\062\063\065\071\065\071\132\060\201\265\061\013 -\060\011\006\003\125\004\006\023\002\125\123\061\027\060\025\006 -\003\125\004\012\023\016\126\145\162\151\123\151\147\156\054\040 -\111\156\143\056\061\037\060\035\006\003\125\004\013\023\026\126 -\145\162\151\123\151\147\156\040\124\162\165\163\164\040\116\145 -\164\167\157\162\153\061\073\060\071\006\003\125\004\013\023\062 -\124\145\162\155\163\040\157\146\040\165\163\145\040\141\164\040 -\150\164\164\160\163\072\057\057\167\167\167\056\166\145\162\151 -\163\151\147\156\056\143\157\155\057\162\160\141\040\050\143\051 -\060\071\061\057\060\055\006\003\125\004\003\023\046\126\145\162 -\151\123\151\147\156\040\103\154\141\163\163\040\063\040\123\145 -\143\165\162\145\040\123\145\162\166\145\162\040\103\101\040\055 -\040\107\062\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\324\126\217\127\073\067\050\246\100\143\322\225 -\325\005\164\332\265\031\152\226\326\161\127\057\342\300\064\214 -\240\225\263\214\341\067\044\363\056\355\103\105\005\216\211\327 -\372\332\112\265\370\076\215\116\307\371\111\120\105\067\100\237 -\164\252\240\121\125\141\361\140\204\211\245\236\200\215\057\260 -\041\252\105\202\304\317\264\024\177\107\025\040\050\202\260\150 -\022\300\256\134\007\327\366\131\314\313\142\126\134\115\111\377 -\046\210\253\124\121\072\057\112\332\016\230\342\211\162\271\374 -\367\150\074\304\037\071\172\313\027\201\363\014\255\017\334\141 -\142\033\020\013\004\036\051\030\161\136\142\313\103\336\276\061 -\272\161\002\031\116\046\251\121\332\214\144\151\003\336\234\375 -\175\375\173\141\274\374\204\174\210\134\264\303\173\355\137\053 -\106\022\361\375\000\001\232\213\133\351\243\005\056\217\056\133 -\336\363\033\170\370\146\221\010\300\136\316\325\260\066\312\324 -\250\173\240\175\371\060\172\277\370\335\031\121\053\040\272\376 -\247\317\241\116\260\147\365\200\252\053\203\056\322\216\124\211 -\216\036\051\013\002\003\001\000\001\243\202\001\054\060\202\001 -\050\060\022\006\003\125\035\023\001\001\377\004\010\060\006\001 -\001\377\002\001\000\060\016\006\003\125\035\017\001\001\377\004 -\004\003\002\001\006\060\051\006\003\125\035\021\004\042\060\040 -\244\036\060\034\061\032\060\030\006\003\125\004\003\023\021\103 -\154\141\163\163\063\103\101\062\060\064\070\055\061\055\065\062 -\060\035\006\003\125\035\016\004\026\004\024\245\357\013\021\316 -\300\101\003\243\112\145\220\110\262\034\340\127\055\175\107\060 -\146\006\003\125\035\040\004\137\060\135\060\133\006\013\140\206 -\110\001\206\370\105\001\007\027\003\060\114\060\043\006\010\053 -\006\001\005\005\007\002\001\026\027\150\164\164\160\163\072\057 -\057\144\056\163\171\155\143\142\056\143\157\155\057\143\160\163 -\060\045\006\010\053\006\001\005\005\007\002\002\060\031\032\027 -\150\164\164\160\163\072\057\057\144\056\163\171\155\143\142\056 -\143\157\155\057\162\160\141\060\057\006\003\125\035\037\004\050 -\060\046\060\044\240\042\240\040\206\036\150\164\164\160\072\057 -\057\163\056\163\171\155\143\142\056\143\157\155\057\160\143\141 -\063\055\147\065\056\143\162\154\060\037\006\003\125\035\043\004 -\030\060\026\200\024\177\323\145\247\302\335\354\273\360\060\011 -\363\103\071\372\002\257\063\061\063\060\015\006\011\052\206\110 -\206\367\015\001\001\005\005\000\003\202\001\001\000\053\216\024 -\314\354\206\010\140\067\213\154\145\211\045\041\336\057\122\242 -\007\236\130\323\263\026\170\001\231\121\225\264\023\167\314\167 -\335\013\134\201\067\326\276\366\142\326\004\067\013\030\163\232 -\323\366\301\242\036\155\234\273\214\021\346\076\022\136\007\137 -\013\203\134\164\002\340\120\364\261\046\033\155\306\350\351\277 -\115\271\001\025\031\354\120\232\371\021\360\201\130\103\054\115 -\021\100\263\132\106\010\246\136\163\241\210\022\065\214\377\003 -\072\275\326\235\372\347\334\226\271\032\144\076\304\375\331\012 -\266\145\236\272\245\250\130\374\073\042\360\242\127\356\212\127 -\107\234\167\307\045\341\254\064\005\115\363\202\176\101\043\272 -\264\127\363\347\306\001\145\327\115\211\231\034\151\115\136\170 -\366\353\162\161\075\262\304\225\001\237\135\014\267\057\045\246 -\134\171\101\357\236\304\147\074\241\235\177\161\072\320\225\227 -\354\170\102\164\230\156\276\076\150\114\127\074\250\223\101\207 -\013\344\271\257\221\373\120\114\014\272\300\044\047\321\025\333 -\145\110\041\012\057\327\334\176\240\314\145\176\171 -END -CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE - -# Trust for "VeriSign-C3SSA-G2-temporary-intermediate-after-1024bit-removal" -# Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G5,OU="(c) 2006 VeriSign, Inc. - For authorized use only",OU=VeriSign Trust Network,O="VeriSign, Inc.",C=US -# Serial Number:2f:00:6e:cd:17:70:66:e7:5f:a3:82:0a:79:1f:05:ae -# Subject: CN=VeriSign Class 3 Secure Server CA - G2,OU=Terms of use at https://www.verisign.com/rpa (c)09,OU=VeriSign Trust Network,O="VeriSign, Inc.",C=US -# Not Valid Before: Thu Mar 26 00:00:00 2009 -# Not Valid After : Sun Mar 24 23:59:59 2019 -# Fingerprint (SHA-256): 0A:41:51:D5:E5:8B:84:B8:AC:E5:3A:5C:12:12:2A:C9:59:CD:69:91:FB:B3:8E:99:B5:76:C0:AB:DA:C3:58:14 -# Fingerprint (SHA1): 76:44:59:78:1B:AC:B0:47:63:A5:D0:A1:58:91:65:26:1F:29:8E:3B -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 "VeriSign-C3SSA-G2-temporary-intermediate-after-1024bit-removal" -CKA_CERT_SHA1_HASH MULTILINE_OCTAL -\166\104\131\170\033\254\260\107\143\245\320\241\130\221\145\046 -\037\051\216\073 -END -CKA_CERT_MD5_HASH MULTILINE_OCTAL -\277\022\155\372\174\325\133\046\171\072\215\252\021\357\057\134 -END -CKA_ISSUER MULTILINE_OCTAL -\060\201\312\061\013\060\011\006\003\125\004\006\023\002\125\123 -\061\027\060\025\006\003\125\004\012\023\016\126\145\162\151\123 -\151\147\156\054\040\111\156\143\056\061\037\060\035\006\003\125 -\004\013\023\026\126\145\162\151\123\151\147\156\040\124\162\165 -\163\164\040\116\145\164\167\157\162\153\061\072\060\070\006\003 -\125\004\013\023\061\050\143\051\040\062\060\060\066\040\126\145 -\162\151\123\151\147\156\054\040\111\156\143\056\040\055\040\106 -\157\162\040\141\165\164\150\157\162\151\172\145\144\040\165\163 -\145\040\157\156\154\171\061\105\060\103\006\003\125\004\003\023 -\074\126\145\162\151\123\151\147\156\040\103\154\141\163\163\040 -\063\040\120\165\142\154\151\143\040\120\162\151\155\141\162\171 -\040\103\145\162\164\151\146\151\143\141\164\151\157\156\040\101 -\165\164\150\157\162\151\164\171\040\055\040\107\065 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\020\057\000\156\315\027\160\146\347\137\243\202\012\171\037 -\005\256 -END -CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_MUST_VERIFY_TRUST -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 "Staat der Nederlanden Root CA - G3" # # Issuer: CN=Staat der Nederlanden Root CA - G3,O=Staat der Nederlanden,C=NL @@ -23818,149 +18509,6 @@ CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE # -# Certificate "Explicitly Distrusted MCSHOLDING CA" -# -# Issuer: CN=CNNIC ROOT,O=CNNIC,C=CN -# Serial Number: 1228079246 (0x4933008e) -# Subject: CN=MCSHOLDING TEST,O=MCSHOLDING,C=EG -# Not Valid Before: Thu Mar 19 06:20:09 2015 -# Not Valid After : Fri Apr 03 06:20:09 2015 -# Fingerprint (SHA-256): 27:40:D9:56:B1:12:7B:79:1A:A1:B3:CC:64:4A:4D:BE:DB:A7:61:86:A2:36:38:B9:51:02:35:1A:83:4E:A8:61 -# Fingerprint (SHA1): E1:F3:59:1E:76:98:65:C4:E4:47:AC:C3:7E:AF:C9:E2:BF:E4:C5:76 -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 "Explicitly Distrusted MCSHOLDING CA" -CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 -CKA_SUBJECT MULTILINE_OCTAL -\060\074\061\013\060\011\006\003\125\004\006\023\002\105\107\061 -\023\060\021\006\003\125\004\012\014\012\115\103\123\110\117\114 -\104\111\116\107\061\030\060\026\006\003\125\004\003\014\017\115 -\103\123\110\117\114\104\111\116\107\040\124\105\123\124 -END -CKA_ID UTF8 "0" -CKA_ISSUER MULTILINE_OCTAL -\060\062\061\013\060\011\006\003\125\004\006\023\002\103\116\061 -\016\060\014\006\003\125\004\012\023\005\103\116\116\111\103\061 -\023\060\021\006\003\125\004\003\023\012\103\116\116\111\103\040 -\122\117\117\124 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\004\111\063\000\216 -END -CKA_VALUE MULTILINE_OCTAL -\060\202\004\222\060\202\003\172\240\003\002\001\002\002\004\111 -\063\000\216\060\015\006\011\052\206\110\206\367\015\001\001\013 -\005\000\060\062\061\013\060\011\006\003\125\004\006\023\002\103 -\116\061\016\060\014\006\003\125\004\012\023\005\103\116\116\111 -\103\061\023\060\021\006\003\125\004\003\023\012\103\116\116\111 -\103\040\122\117\117\124\060\036\027\015\061\065\060\063\061\071 -\060\066\062\060\060\071\132\027\015\061\065\060\064\060\063\060 -\066\062\060\060\071\132\060\074\061\013\060\011\006\003\125\004 -\006\023\002\105\107\061\023\060\021\006\003\125\004\012\014\012 -\115\103\123\110\117\114\104\111\116\107\061\030\060\026\006\003 -\125\004\003\014\017\115\103\123\110\117\114\104\111\116\107\040 -\124\105\123\124\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\245\371\165\014\006\256\356\014\021\315\226 -\063\115\153\316\300\112\014\075\135\353\322\113\011\177\347\107 -\054\254\161\000\371\010\257\064\361\243\152\307\374\346\253\316 -\320\276\312\315\052\230\230\271\320\216\063\111\007\141\040\321 -\132\064\316\203\024\006\171\216\032\277\333\344\240\070\072\356 -\224\271\243\240\130\072\211\024\254\140\076\003\324\307\315\073 -\034\260\232\210\032\111\020\251\260\262\375\345\350\341\004\342 -\352\202\155\376\014\121\105\221\255\165\042\256\377\117\220\013 -\300\123\145\167\076\036\302\126\265\066\306\326\205\314\016\203 -\032\063\037\166\231\133\053\227\053\213\327\321\024\025\114\235 -\131\327\200\057\244\242\205\325\210\066\002\140\125\312\130\337 -\223\374\112\142\007\226\323\304\372\277\215\001\047\227\057\246 -\134\164\361\072\102\156\135\171\024\060\061\032\074\331\262\127 -\115\340\270\077\017\151\061\242\235\145\231\331\326\061\207\265 -\230\046\337\360\313\273\025\300\044\023\142\122\032\153\313\105 -\007\227\343\304\224\136\311\015\107\054\351\317\351\364\217\376 -\065\341\062\347\061\002\003\001\000\001\243\202\001\244\060\202 -\001\240\060\166\006\010\053\006\001\005\005\007\001\001\004\152 -\060\150\060\051\006\010\053\006\001\005\005\007\060\001\206\035 -\150\164\164\160\072\057\057\157\143\163\160\143\156\156\151\143 -\162\157\157\164\056\143\156\156\151\143\056\143\156\060\073\006 -\010\053\006\001\005\005\007\060\002\206\057\150\164\164\160\072 -\057\057\167\167\167\056\143\156\156\151\143\056\143\156\057\144 -\157\167\156\154\157\141\144\057\143\145\162\164\057\103\116\116 -\111\103\122\117\117\124\056\143\145\162\060\037\006\003\125\035 -\043\004\030\060\026\200\024\145\362\061\255\052\367\367\335\122 -\226\012\307\002\301\016\357\246\325\073\021\060\017\006\003\125 -\035\023\001\001\377\004\005\060\003\001\001\377\060\077\006\003 -\125\035\040\004\070\060\066\060\064\006\012\053\006\001\004\001 -\201\351\014\001\006\060\046\060\044\006\010\053\006\001\005\005 -\007\002\001\026\030\150\164\164\160\072\057\057\167\167\167\056 -\143\156\156\151\143\056\143\156\057\143\160\163\057\060\201\206 -\006\003\125\035\037\004\177\060\175\060\102\240\100\240\076\244 -\074\060\072\061\013\060\011\006\003\125\004\006\023\002\103\116 -\061\016\060\014\006\003\125\004\012\014\005\103\116\116\111\103 -\061\014\060\012\006\003\125\004\013\014\003\143\162\154\061\015 -\060\013\006\003\125\004\003\014\004\143\162\154\061\060\067\240 -\065\240\063\206\061\150\164\164\160\072\057\057\143\162\154\056 -\143\156\156\151\143\056\143\156\057\144\157\167\156\154\157\141 -\144\057\162\157\157\164\163\150\141\062\143\162\154\057\103\122 -\114\061\056\143\162\154\060\013\006\003\125\035\017\004\004\003 -\002\001\006\060\035\006\003\125\035\016\004\026\004\024\104\244 -\211\253\024\137\075\157\040\074\252\174\372\031\256\364\110\140 -\005\265\060\015\006\011\052\206\110\206\367\015\001\001\013\005 -\000\003\202\001\001\000\134\264\365\123\233\117\271\340\204\211 -\061\276\236\056\352\236\041\113\245\217\155\241\246\363\057\110 -\353\351\333\255\036\061\200\320\171\073\020\357\232\044\367\223 -\033\065\363\032\302\307\302\054\012\177\157\133\361\137\163\221 -\004\373\015\171\015\351\032\006\326\203\375\116\140\235\154\222 -\103\114\352\144\230\104\253\327\373\107\320\257\037\144\114\342 -\335\167\150\026\302\054\241\240\201\227\000\102\037\176\040\170 -\350\306\120\035\013\177\025\223\131\130\100\024\204\360\247\220 -\153\066\005\147\352\177\042\155\273\321\245\046\115\263\060\244 -\130\324\133\265\032\214\120\214\270\015\341\240\007\263\017\130 -\316\327\005\265\175\065\171\157\242\333\014\000\052\150\044\214 -\176\234\301\166\111\272\174\146\021\336\362\107\316\376\320\316 -\125\276\010\332\362\171\046\052\025\071\316\153\030\246\337\330 -\207\050\231\224\016\055\150\241\232\316\122\066\234\053\354\264 -\150\263\154\025\254\313\160\102\362\304\101\245\310\374\041\170 -\123\167\062\040\251\041\114\162\342\323\262\311\166\033\030\130 -\102\013\102\222\263\344 -END - -# Distrust "Explicitly Distrusted MCSHOLDING CA" -# Issuer: CN=CNNIC ROOT,O=CNNIC,C=CN -# Serial Number: 1228079246 (0x4933008e) -# Subject: CN=MCSHOLDING TEST,O=MCSHOLDING,C=EG -# Not Valid Before: Thu Mar 19 06:20:09 2015 -# Not Valid After : Fri Apr 03 06:20:09 2015 -# Fingerprint (SHA-256): 27:40:D9:56:B1:12:7B:79:1A:A1:B3:CC:64:4A:4D:BE:DB:A7:61:86:A2:36:38:B9:51:02:35:1A:83:4E:A8:61 -# Fingerprint (SHA1): E1:F3:59:1E:76:98:65:C4:E4:47:AC:C3:7E:AF:C9:E2:BF:E4:C5:76 -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 "Explicitly Distrusted MCSHOLDING CA" -CKA_CERT_SHA1_HASH MULTILINE_OCTAL -\341\363\131\036\166\230\145\304\344\107\254\303\176\257\311\342 -\277\344\305\166 -END -CKA_CERT_MD5_HASH MULTILINE_OCTAL -\366\212\253\024\076\326\060\045\267\111\015\167\205\160\231\313 -END -CKA_ISSUER MULTILINE_OCTAL -\060\062\061\013\060\011\006\003\125\004\006\023\002\103\116\061 -\016\060\014\006\003\125\004\012\023\005\103\116\116\111\103\061 -\023\060\021\006\003\125\004\003\023\012\103\116\116\111\103\040 -\122\117\117\124 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\004\111\063\000\216 -END -CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED -CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED -CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED -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 @@ -24429,248 +18977,6 @@ CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE # -# Certificate "Certification Authority of WoSign G2" -# -# Issuer: CN=Certification Authority of WoSign G2,O=WoSign CA Limited,C=CN -# Serial Number:6b:25:da:8a:88:9d:7c:bc:0f:05:b3:b1:7a:61:45:44 -# Subject: CN=Certification Authority of WoSign G2,O=WoSign CA Limited,C=CN -# Not Valid Before: Sat Nov 08 00:58:58 2014 -# Not Valid After : Tue Nov 08 00:58:58 2044 -# Fingerprint (SHA-256): D4:87:A5:6F:83:B0:74:82:E8:5E:96:33:94:C1:EC:C2:C9:E5:1D:09:03:EE:94:6B:02:C3:01:58:1E:D9:9E:16 -# Fingerprint (SHA1): FB:ED:DC:90:65:B7:27:20:37:BC:55:0C:9C:56:DE:BB:F2:78:94:E1 -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 "Certification Authority of WoSign G2" -CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 -CKA_SUBJECT MULTILINE_OCTAL -\060\130\061\013\060\011\006\003\125\004\006\023\002\103\116\061 -\032\060\030\006\003\125\004\012\023\021\127\157\123\151\147\156 -\040\103\101\040\114\151\155\151\164\145\144\061\055\060\053\006 -\003\125\004\003\023\044\103\145\162\164\151\146\151\143\141\164 -\151\157\156\040\101\165\164\150\157\162\151\164\171\040\157\146 -\040\127\157\123\151\147\156\040\107\062 -END -CKA_ID UTF8 "0" -CKA_ISSUER MULTILINE_OCTAL -\060\130\061\013\060\011\006\003\125\004\006\023\002\103\116\061 -\032\060\030\006\003\125\004\012\023\021\127\157\123\151\147\156 -\040\103\101\040\114\151\155\151\164\145\144\061\055\060\053\006 -\003\125\004\003\023\044\103\145\162\164\151\146\151\143\141\164 -\151\157\156\040\101\165\164\150\157\162\151\164\171\040\157\146 -\040\127\157\123\151\147\156\040\107\062 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\020\153\045\332\212\210\235\174\274\017\005\263\261\172\141 -\105\104 -END -CKA_VALUE MULTILINE_OCTAL -\060\202\003\174\060\202\002\144\240\003\002\001\002\002\020\153 -\045\332\212\210\235\174\274\017\005\263\261\172\141\105\104\060 -\015\006\011\052\206\110\206\367\015\001\001\013\005\000\060\130 -\061\013\060\011\006\003\125\004\006\023\002\103\116\061\032\060 -\030\006\003\125\004\012\023\021\127\157\123\151\147\156\040\103 -\101\040\114\151\155\151\164\145\144\061\055\060\053\006\003\125 -\004\003\023\044\103\145\162\164\151\146\151\143\141\164\151\157 -\156\040\101\165\164\150\157\162\151\164\171\040\157\146\040\127 -\157\123\151\147\156\040\107\062\060\036\027\015\061\064\061\061 -\060\070\060\060\065\070\065\070\132\027\015\064\064\061\061\060 -\070\060\060\065\070\065\070\132\060\130\061\013\060\011\006\003 -\125\004\006\023\002\103\116\061\032\060\030\006\003\125\004\012 -\023\021\127\157\123\151\147\156\040\103\101\040\114\151\155\151 -\164\145\144\061\055\060\053\006\003\125\004\003\023\044\103\145 -\162\164\151\146\151\143\141\164\151\157\156\040\101\165\164\150 -\157\162\151\164\171\040\157\146\040\127\157\123\151\147\156\040 -\107\062\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\276\305\304\240\042\200\111\117\277\331\207\021\306 -\123\341\273\017\275\140\177\257\366\202\016\037\334\260\216\075 -\227\340\120\074\217\072\357\146\073\105\007\233\040\370\343\327 -\045\206\065\220\026\242\135\157\060\031\010\207\013\177\006\262 -\235\142\217\336\257\222\245\140\324\053\200\232\122\077\365\232 -\203\351\064\132\313\331\325\142\134\346\016\340\337\006\230\016 -\200\174\312\264\035\023\210\153\016\250\044\167\003\320\356\133 -\363\312\151\221\065\071\126\305\155\343\367\075\117\136\223\070 -\044\312\030\351\044\313\222\003\335\314\034\075\011\160\344\040 -\344\361\256\254\273\163\151\243\143\072\017\105\017\241\112\232 -\302\321\143\254\313\020\370\075\346\116\050\267\353\304\225\261 -\254\375\136\253\372\101\313\135\235\113\334\364\174\166\357\147 -\177\000\172\215\322\240\032\134\115\042\341\265\332\335\166\263 -\324\166\337\136\270\213\230\310\024\124\314\153\027\222\267\340 -\112\277\111\224\141\013\070\220\217\135\044\154\045\173\073\171 -\331\342\176\235\255\237\230\241\006\374\170\024\140\127\370\356 -\200\167\261\002\003\001\000\001\243\102\060\100\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\035\006 -\003\125\035\016\004\026\004\024\372\140\251\353\145\305\335\026 -\024\010\116\014\017\215\233\340\367\144\257\147\060\015\006\011 -\052\206\110\206\367\015\001\001\013\005\000\003\202\001\001\000 -\127\303\172\066\202\234\215\230\342\253\100\252\107\217\307\247 -\133\355\174\347\075\146\132\073\061\273\337\363\026\063\221\374 -\174\173\245\302\246\146\343\252\260\267\047\230\077\111\327\140 -\147\147\077\066\117\112\313\361\024\372\132\207\050\034\355\217 -\101\062\306\225\371\175\332\275\173\133\302\260\041\343\217\106 -\334\041\070\103\164\114\373\060\370\027\162\301\062\374\310\221 -\027\304\314\130\067\116\013\314\132\367\041\065\050\203\154\140 -\055\104\353\122\214\120\075\265\154\022\327\372\011\273\154\262 -\112\261\305\211\344\374\323\122\330\141\027\376\172\224\204\217 -\171\266\063\131\272\017\304\013\342\160\240\113\170\056\372\310 -\237\375\257\221\145\012\170\070\025\345\227\027\024\335\371\340 -\054\064\370\070\320\204\042\000\300\024\121\030\053\002\334\060 -\132\360\350\001\174\065\072\043\257\010\344\257\252\216\050\102 -\111\056\360\365\231\064\276\355\017\113\030\341\322\044\074\273 -\135\107\267\041\362\215\321\012\231\216\343\156\076\255\160\340 -\217\271\312\314\156\201\061\366\173\234\172\171\344\147\161\030 -END -CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE - -# Trust for "Certification Authority of WoSign G2" -# Issuer: CN=Certification Authority of WoSign G2,O=WoSign CA Limited,C=CN -# Serial Number:6b:25:da:8a:88:9d:7c:bc:0f:05:b3:b1:7a:61:45:44 -# Subject: CN=Certification Authority of WoSign G2,O=WoSign CA Limited,C=CN -# Not Valid Before: Sat Nov 08 00:58:58 2014 -# Not Valid After : Tue Nov 08 00:58:58 2044 -# Fingerprint (SHA-256): D4:87:A5:6F:83:B0:74:82:E8:5E:96:33:94:C1:EC:C2:C9:E5:1D:09:03:EE:94:6B:02:C3:01:58:1E:D9:9E:16 -# Fingerprint (SHA1): FB:ED:DC:90:65:B7:27:20:37:BC:55:0C:9C:56:DE:BB:F2:78:94:E1 -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 "Certification Authority of WoSign G2" -CKA_CERT_SHA1_HASH MULTILINE_OCTAL -\373\355\334\220\145\267\047\040\067\274\125\014\234\126\336\273 -\362\170\224\341 -END -CKA_CERT_MD5_HASH MULTILINE_OCTAL -\310\034\175\031\252\313\161\223\362\120\370\122\250\036\272\140 -END -CKA_ISSUER MULTILINE_OCTAL -\060\130\061\013\060\011\006\003\125\004\006\023\002\103\116\061 -\032\060\030\006\003\125\004\012\023\021\127\157\123\151\147\156 -\040\103\101\040\114\151\155\151\164\145\144\061\055\060\053\006 -\003\125\004\003\023\044\103\145\162\164\151\146\151\143\141\164 -\151\157\156\040\101\165\164\150\157\162\151\164\171\040\157\146 -\040\127\157\123\151\147\156\040\107\062 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\020\153\045\332\212\210\235\174\274\017\005\263\261\172\141 -\105\104 -END -CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR -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 "CA WoSign ECC Root" -# -# Issuer: CN=CA WoSign ECC Root,O=WoSign CA Limited,C=CN -# Serial Number:68:4a:58:70:80:6b:f0:8f:02:fa:f6:de:e8:b0:90:90 -# Subject: CN=CA WoSign ECC Root,O=WoSign CA Limited,C=CN -# Not Valid Before: Sat Nov 08 00:58:58 2014 -# Not Valid After : Tue Nov 08 00:58:58 2044 -# Fingerprint (SHA-256): 8B:45:DA:1C:06:F7:91:EB:0C:AB:F2:6B:E5:88:F5:FB:23:16:5C:2E:61:4B:F8:85:56:2D:0D:CE:50:B2:9B:02 -# Fingerprint (SHA1): D2:7A:D2:BE:ED:94:C0:A1:3C:C7:25:21:EA:5D:71:BE:81:19:F3:2B -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 "CA WoSign ECC Root" -CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 -CKA_SUBJECT MULTILINE_OCTAL -\060\106\061\013\060\011\006\003\125\004\006\023\002\103\116\061 -\032\060\030\006\003\125\004\012\023\021\127\157\123\151\147\156 -\040\103\101\040\114\151\155\151\164\145\144\061\033\060\031\006 -\003\125\004\003\023\022\103\101\040\127\157\123\151\147\156\040 -\105\103\103\040\122\157\157\164 -END -CKA_ID UTF8 "0" -CKA_ISSUER MULTILINE_OCTAL -\060\106\061\013\060\011\006\003\125\004\006\023\002\103\116\061 -\032\060\030\006\003\125\004\012\023\021\127\157\123\151\147\156 -\040\103\101\040\114\151\155\151\164\145\144\061\033\060\031\006 -\003\125\004\003\023\022\103\101\040\127\157\123\151\147\156\040 -\105\103\103\040\122\157\157\164 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\020\150\112\130\160\200\153\360\217\002\372\366\336\350\260 -\220\220 -END -CKA_VALUE MULTILINE_OCTAL -\060\202\002\011\060\202\001\217\240\003\002\001\002\002\020\150 -\112\130\160\200\153\360\217\002\372\366\336\350\260\220\220\060 -\012\006\010\052\206\110\316\075\004\003\003\060\106\061\013\060 -\011\006\003\125\004\006\023\002\103\116\061\032\060\030\006\003 -\125\004\012\023\021\127\157\123\151\147\156\040\103\101\040\114 -\151\155\151\164\145\144\061\033\060\031\006\003\125\004\003\023 -\022\103\101\040\127\157\123\151\147\156\040\105\103\103\040\122 -\157\157\164\060\036\027\015\061\064\061\061\060\070\060\060\065 -\070\065\070\132\027\015\064\064\061\061\060\070\060\060\065\070 -\065\070\132\060\106\061\013\060\011\006\003\125\004\006\023\002 -\103\116\061\032\060\030\006\003\125\004\012\023\021\127\157\123 -\151\147\156\040\103\101\040\114\151\155\151\164\145\144\061\033 -\060\031\006\003\125\004\003\023\022\103\101\040\127\157\123\151 -\147\156\040\105\103\103\040\122\157\157\164\060\166\060\020\006 -\007\052\206\110\316\075\002\001\006\005\053\201\004\000\042\003 -\142\000\004\341\375\216\270\103\044\253\226\173\205\302\272\013 -\255\215\340\072\343\044\271\322\261\276\210\072\312\277\112\270 -\371\357\054\057\257\121\120\074\107\165\154\370\224\267\233\374 -\050\036\305\124\314\143\235\026\113\123\301\347\040\253\315\254 -\045\322\177\217\302\301\132\202\136\060\213\172\124\316\003\265 -\221\177\252\224\320\321\212\110\314\202\005\046\241\325\121\022 -\326\173\066\243\102\060\100\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\035\006\003\125\035\016\004 -\026\004\024\252\375\325\132\243\366\207\213\062\205\375\321\062 -\133\200\105\223\363\003\270\060\012\006\010\052\206\110\316\075 -\004\003\003\003\150\000\060\145\002\061\000\344\244\204\260\201 -\325\075\260\164\254\224\244\350\016\075\000\164\114\241\227\153 -\371\015\121\074\241\331\073\364\015\253\251\237\276\116\162\312 -\205\324\331\354\265\062\105\030\157\253\255\002\060\175\307\367 -\151\143\057\241\341\230\357\023\020\321\171\077\321\376\352\073 -\177\336\126\364\220\261\025\021\330\262\042\025\320\057\303\046 -\056\153\361\221\262\220\145\364\232\346\220\356\112 -END -CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE - -# Trust for "CA WoSign ECC Root" -# Issuer: CN=CA WoSign ECC Root,O=WoSign CA Limited,C=CN -# Serial Number:68:4a:58:70:80:6b:f0:8f:02:fa:f6:de:e8:b0:90:90 -# Subject: CN=CA WoSign ECC Root,O=WoSign CA Limited,C=CN -# Not Valid Before: Sat Nov 08 00:58:58 2014 -# Not Valid After : Tue Nov 08 00:58:58 2044 -# Fingerprint (SHA-256): 8B:45:DA:1C:06:F7:91:EB:0C:AB:F2:6B:E5:88:F5:FB:23:16:5C:2E:61:4B:F8:85:56:2D:0D:CE:50:B2:9B:02 -# Fingerprint (SHA1): D2:7A:D2:BE:ED:94:C0:A1:3C:C7:25:21:EA:5D:71:BE:81:19:F3:2B -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 "CA WoSign ECC Root" -CKA_CERT_SHA1_HASH MULTILINE_OCTAL -\322\172\322\276\355\224\300\241\074\307\045\041\352\135\161\276 -\201\031\363\053 -END -CKA_CERT_MD5_HASH MULTILINE_OCTAL -\200\306\123\356\141\202\050\162\360\377\041\271\027\312\262\040 -END -CKA_ISSUER MULTILINE_OCTAL -\060\106\061\013\060\011\006\003\125\004\006\023\002\103\116\061 -\032\060\030\006\003\125\004\012\023\021\127\157\123\151\147\156 -\040\103\101\040\114\151\155\151\164\145\144\061\033\060\031\006 -\003\125\004\003\023\022\103\101\040\127\157\123\151\147\156\040 -\105\103\103\040\122\157\157\164 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\020\150\112\130\160\200\153\360\217\002\372\366\336\350\260 -\220\220 -END -CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR -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 "SZAFIR ROOT CA2" # # Issuer: CN=SZAFIR ROOT CA2,O=Krajowa Izba Rozliczeniowa S.A.,C=PL @@ -27873,3 +22179,1284 @@ 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 "GDCA TrustAUTH R5 ROOT" +# +# Issuer: CN=GDCA TrustAUTH R5 ROOT,O="GUANG DONG CERTIFICATE AUTHORITY CO.,LTD.",C=CN +# Serial Number:7d:09:97:fe:f0:47:ea:7a +# Subject: CN=GDCA TrustAUTH R5 ROOT,O="GUANG DONG CERTIFICATE AUTHORITY CO.,LTD.",C=CN +# Not Valid Before: Wed Nov 26 05:13:15 2014 +# Not Valid After : Mon Dec 31 15:59:59 2040 +# Fingerprint (SHA-256): BF:FF:8F:D0:44:33:48:7D:6A:8A:A6:0C:1A:29:76:7A:9F:C2:BB:B0:5E:42:0F:71:3A:13:B9:92:89:1D:38:93 +# Fingerprint (SHA1): 0F:36:38:5B:81:1A:25:C3:9B:31:4E:83:CA:E9:34:66:70:CC:74:B4 +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 "GDCA TrustAUTH R5 ROOT" +CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 +CKA_SUBJECT MULTILINE_OCTAL +\060\142\061\013\060\011\006\003\125\004\006\023\002\103\116\061 +\062\060\060\006\003\125\004\012\014\051\107\125\101\116\107\040 +\104\117\116\107\040\103\105\122\124\111\106\111\103\101\124\105 +\040\101\125\124\110\117\122\111\124\131\040\103\117\056\054\114 +\124\104\056\061\037\060\035\006\003\125\004\003\014\026\107\104 +\103\101\040\124\162\165\163\164\101\125\124\110\040\122\065\040 +\122\117\117\124 +END +CKA_ID UTF8 "0" +CKA_ISSUER MULTILINE_OCTAL +\060\142\061\013\060\011\006\003\125\004\006\023\002\103\116\061 +\062\060\060\006\003\125\004\012\014\051\107\125\101\116\107\040 +\104\117\116\107\040\103\105\122\124\111\106\111\103\101\124\105 +\040\101\125\124\110\117\122\111\124\131\040\103\117\056\054\114 +\124\104\056\061\037\060\035\006\003\125\004\003\014\026\107\104 +\103\101\040\124\162\165\163\164\101\125\124\110\040\122\065\040 +\122\117\117\124 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\010\175\011\227\376\360\107\352\172 +END +CKA_VALUE MULTILINE_OCTAL +\060\202\005\210\060\202\003\160\240\003\002\001\002\002\010\175 +\011\227\376\360\107\352\172\060\015\006\011\052\206\110\206\367 +\015\001\001\013\005\000\060\142\061\013\060\011\006\003\125\004 +\006\023\002\103\116\061\062\060\060\006\003\125\004\012\014\051 +\107\125\101\116\107\040\104\117\116\107\040\103\105\122\124\111 +\106\111\103\101\124\105\040\101\125\124\110\117\122\111\124\131 +\040\103\117\056\054\114\124\104\056\061\037\060\035\006\003\125 +\004\003\014\026\107\104\103\101\040\124\162\165\163\164\101\125 +\124\110\040\122\065\040\122\117\117\124\060\036\027\015\061\064 +\061\061\062\066\060\065\061\063\061\065\132\027\015\064\060\061 +\062\063\061\061\065\065\071\065\071\132\060\142\061\013\060\011 +\006\003\125\004\006\023\002\103\116\061\062\060\060\006\003\125 +\004\012\014\051\107\125\101\116\107\040\104\117\116\107\040\103 +\105\122\124\111\106\111\103\101\124\105\040\101\125\124\110\117 +\122\111\124\131\040\103\117\056\054\114\124\104\056\061\037\060 +\035\006\003\125\004\003\014\026\107\104\103\101\040\124\162\165 +\163\164\101\125\124\110\040\122\065\040\122\117\117\124\060\202 +\002\042\060\015\006\011\052\206\110\206\367\015\001\001\001\005 +\000\003\202\002\017\000\060\202\002\012\002\202\002\001\000\331 +\243\026\360\310\164\164\167\233\357\063\015\073\006\176\125\374 +\265\140\217\166\206\022\102\175\126\146\076\210\202\355\162\143 +\016\236\213\335\064\054\002\121\121\303\031\375\131\124\204\311 +\361\153\263\114\260\351\350\106\135\070\306\242\247\056\021\127 +\272\202\025\242\234\217\155\260\231\112\012\362\353\211\160\143 +\116\171\304\267\133\275\242\135\261\362\101\002\053\255\251\072 +\243\354\171\012\354\137\072\343\375\357\200\074\255\064\233\032 +\253\210\046\173\126\242\202\206\037\353\065\211\203\177\137\256 +\051\116\075\266\156\354\256\301\360\047\233\256\343\364\354\357 +\256\177\367\206\075\162\172\353\245\373\131\116\247\353\225\214 +\042\071\171\341\055\010\217\314\274\221\270\101\367\024\301\043 +\251\303\255\232\105\104\263\262\327\054\315\306\051\342\120\020 +\256\134\313\202\216\027\030\066\175\227\346\210\232\260\115\064 +\011\364\054\271\132\146\052\260\027\233\236\036\166\235\112\146 +\061\101\337\077\373\305\006\357\033\266\176\032\106\066\367\144 +\143\073\343\071\030\043\347\147\165\024\325\165\127\222\067\275 +\276\152\033\046\120\362\066\046\006\220\305\160\001\144\155\166 +\146\341\221\333\156\007\300\141\200\056\262\056\057\214\160\247 +\321\073\074\263\221\344\156\266\304\073\160\362\154\222\227\011 +\315\107\175\030\300\363\273\236\017\326\213\256\007\266\132\017 +\316\013\014\107\247\345\076\270\275\175\307\233\065\240\141\227 +\072\101\165\027\314\053\226\167\052\222\041\036\331\225\166\040 +\147\150\317\015\275\337\326\037\011\152\232\342\314\163\161\244 +\057\175\022\200\267\123\060\106\136\113\124\231\017\147\311\245 +\310\362\040\301\202\354\235\021\337\302\002\373\032\073\321\355 +\040\232\357\145\144\222\020\015\052\342\336\160\361\030\147\202 +\214\141\336\270\274\321\057\234\373\017\320\053\355\033\166\271 +\344\071\125\370\370\241\035\270\252\200\000\114\202\347\262\177 +\011\270\274\060\240\057\015\365\122\236\216\367\222\263\012\000 +\035\000\124\227\006\340\261\007\331\307\017\134\145\175\074\155 +\131\127\344\355\245\215\351\100\123\237\025\113\240\161\366\032 +\041\343\332\160\006\041\130\024\207\205\167\171\252\202\171\002 +\003\001\000\001\243\102\060\100\060\035\006\003\125\035\016\004 +\026\004\024\342\311\100\237\115\316\350\232\241\174\317\016\077 +\145\305\051\210\152\031\121\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\206\060\015\006\011\052\206\110\206 +\367\015\001\001\013\005\000\003\202\002\001\000\321\111\127\340 +\247\314\150\130\272\001\017\053\031\315\215\260\141\105\254\021 +\355\143\120\151\370\037\177\276\026\217\375\235\353\013\252\062 +\107\166\322\147\044\355\275\174\063\062\227\052\307\005\206\146 +\015\027\175\024\025\033\324\353\375\037\232\366\136\227\151\267 +\032\045\244\012\263\221\077\137\066\254\213\354\127\250\076\347 +\201\212\030\127\071\205\164\032\102\307\351\133\023\137\217\371 +\010\351\222\164\215\365\107\322\253\073\326\373\170\146\116\066 +\175\371\351\222\351\004\336\375\111\143\374\155\373\024\161\223 +\147\057\107\112\267\271\377\036\052\163\160\106\060\277\132\362 +\057\171\245\341\215\014\331\371\262\143\067\214\067\145\205\160 +\152\134\133\011\162\271\255\143\074\261\335\370\374\062\277\067 +\206\344\273\216\230\047\176\272\037\026\341\160\021\362\003\337 +\045\142\062\047\046\030\062\204\237\377\000\072\023\272\232\115 +\364\117\270\024\160\042\261\312\053\220\316\051\301\160\364\057 +\235\177\362\220\036\326\132\337\267\106\374\346\206\372\313\340 +\040\166\172\272\246\313\365\174\336\142\245\261\213\356\336\202 +\146\212\116\072\060\037\077\200\313\255\047\272\014\136\327\320 +\261\126\312\167\161\262\265\165\241\120\251\100\103\027\302\050 +\331\317\122\213\133\310\143\324\102\076\240\063\172\106\056\367 +\012\040\106\124\176\152\117\061\361\201\176\102\164\070\145\163 +\047\356\306\174\270\216\327\245\072\327\230\241\234\214\020\125 +\323\333\113\354\100\220\362\315\156\127\322\142\016\174\127\223 +\261\247\155\315\235\203\273\052\347\345\266\073\161\130\255\375 +\321\105\274\132\221\356\123\025\157\323\105\011\165\156\272\220 +\135\036\004\317\067\337\036\250\146\261\214\346\040\152\357\374 +\110\116\164\230\102\257\051\157\056\152\307\373\175\321\146\061 +\042\314\206\000\176\146\203\014\102\364\275\064\222\303\032\352 +\117\312\176\162\115\013\160\214\246\110\273\246\241\024\366\373 +\130\104\231\024\256\252\013\223\151\240\051\045\112\245\313\053 +\335\212\146\007\026\170\025\127\161\033\354\365\107\204\363\236 +\061\067\172\325\177\044\255\344\274\375\375\314\156\203\350\014 +\250\267\101\154\007\335\275\074\206\227\057\322 +END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE + +# Trust for "GDCA TrustAUTH R5 ROOT" +# Issuer: CN=GDCA TrustAUTH R5 ROOT,O="GUANG DONG CERTIFICATE AUTHORITY CO.,LTD.",C=CN +# Serial Number:7d:09:97:fe:f0:47:ea:7a +# Subject: CN=GDCA TrustAUTH R5 ROOT,O="GUANG DONG CERTIFICATE AUTHORITY CO.,LTD.",C=CN +# Not Valid Before: Wed Nov 26 05:13:15 2014 +# Not Valid After : Mon Dec 31 15:59:59 2040 +# Fingerprint (SHA-256): BF:FF:8F:D0:44:33:48:7D:6A:8A:A6:0C:1A:29:76:7A:9F:C2:BB:B0:5E:42:0F:71:3A:13:B9:92:89:1D:38:93 +# Fingerprint (SHA1): 0F:36:38:5B:81:1A:25:C3:9B:31:4E:83:CA:E9:34:66:70:CC:74:B4 +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 "GDCA TrustAUTH R5 ROOT" +CKA_CERT_SHA1_HASH MULTILINE_OCTAL +\017\066\070\133\201\032\045\303\233\061\116\203\312\351\064\146 +\160\314\164\264 +END +CKA_CERT_MD5_HASH MULTILINE_OCTAL +\143\314\331\075\064\065\134\157\123\243\342\010\160\110\037\264 +END +CKA_ISSUER MULTILINE_OCTAL +\060\142\061\013\060\011\006\003\125\004\006\023\002\103\116\061 +\062\060\060\006\003\125\004\012\014\051\107\125\101\116\107\040 +\104\117\116\107\040\103\105\122\124\111\106\111\103\101\124\105 +\040\101\125\124\110\117\122\111\124\131\040\103\117\056\054\114 +\124\104\056\061\037\060\035\006\003\125\004\003\014\026\107\104 +\103\101\040\124\162\165\163\164\101\125\124\110\040\122\065\040 +\122\117\117\124 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\010\175\011\227\376\360\107\352\172 +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 "TrustCor RootCert CA-1" +# +# Issuer: CN=TrustCor RootCert CA-1,OU=TrustCor Certificate Authority,O=TrustCor Systems S. de R.L.,L=Panama City,ST=Panama,C=PA +# Serial Number:00:da:9b:ec:71:f3:03:b0:19 +# Subject: CN=TrustCor RootCert CA-1,OU=TrustCor Certificate Authority,O=TrustCor Systems S. de R.L.,L=Panama City,ST=Panama,C=PA +# Not Valid Before: Thu Feb 04 12:32:16 2016 +# Not Valid After : Mon Dec 31 17:23:16 2029 +# Fingerprint (SHA-256): D4:0E:9C:86:CD:8F:E4:68:C1:77:69:59:F4:9E:A7:74:FA:54:86:84:B6:C4:06:F3:90:92:61:F4:DC:E2:57:5C +# Fingerprint (SHA1): FF:BD:CD:E7:82:C8:43:5E:3C:6F:26:86:5C:CA:A8:3A:45:5B:C3:0A +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 "TrustCor RootCert CA-1" +CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 +CKA_SUBJECT MULTILINE_OCTAL +\060\201\244\061\013\060\011\006\003\125\004\006\023\002\120\101 +\061\017\060\015\006\003\125\004\010\014\006\120\141\156\141\155 +\141\061\024\060\022\006\003\125\004\007\014\013\120\141\156\141 +\155\141\040\103\151\164\171\061\044\060\042\006\003\125\004\012 +\014\033\124\162\165\163\164\103\157\162\040\123\171\163\164\145 +\155\163\040\123\056\040\144\145\040\122\056\114\056\061\047\060 +\045\006\003\125\004\013\014\036\124\162\165\163\164\103\157\162 +\040\103\145\162\164\151\146\151\143\141\164\145\040\101\165\164 +\150\157\162\151\164\171\061\037\060\035\006\003\125\004\003\014 +\026\124\162\165\163\164\103\157\162\040\122\157\157\164\103\145 +\162\164\040\103\101\055\061 +END +CKA_ID UTF8 "0" +CKA_ISSUER MULTILINE_OCTAL +\060\201\244\061\013\060\011\006\003\125\004\006\023\002\120\101 +\061\017\060\015\006\003\125\004\010\014\006\120\141\156\141\155 +\141\061\024\060\022\006\003\125\004\007\014\013\120\141\156\141 +\155\141\040\103\151\164\171\061\044\060\042\006\003\125\004\012 +\014\033\124\162\165\163\164\103\157\162\040\123\171\163\164\145 +\155\163\040\123\056\040\144\145\040\122\056\114\056\061\047\060 +\045\006\003\125\004\013\014\036\124\162\165\163\164\103\157\162 +\040\103\145\162\164\151\146\151\143\141\164\145\040\101\165\164 +\150\157\162\151\164\171\061\037\060\035\006\003\125\004\003\014 +\026\124\162\165\163\164\103\157\162\040\122\157\157\164\103\145 +\162\164\040\103\101\055\061 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\011\000\332\233\354\161\363\003\260\031 +END +CKA_VALUE MULTILINE_OCTAL +\060\202\004\060\060\202\003\030\240\003\002\001\002\002\011\000 +\332\233\354\161\363\003\260\031\060\015\006\011\052\206\110\206 +\367\015\001\001\013\005\000\060\201\244\061\013\060\011\006\003 +\125\004\006\023\002\120\101\061\017\060\015\006\003\125\004\010 +\014\006\120\141\156\141\155\141\061\024\060\022\006\003\125\004 +\007\014\013\120\141\156\141\155\141\040\103\151\164\171\061\044 +\060\042\006\003\125\004\012\014\033\124\162\165\163\164\103\157 +\162\040\123\171\163\164\145\155\163\040\123\056\040\144\145\040 +\122\056\114\056\061\047\060\045\006\003\125\004\013\014\036\124 +\162\165\163\164\103\157\162\040\103\145\162\164\151\146\151\143 +\141\164\145\040\101\165\164\150\157\162\151\164\171\061\037\060 +\035\006\003\125\004\003\014\026\124\162\165\163\164\103\157\162 +\040\122\157\157\164\103\145\162\164\040\103\101\055\061\060\036 +\027\015\061\066\060\062\060\064\061\062\063\062\061\066\132\027 +\015\062\071\061\062\063\061\061\067\062\063\061\066\132\060\201 +\244\061\013\060\011\006\003\125\004\006\023\002\120\101\061\017 +\060\015\006\003\125\004\010\014\006\120\141\156\141\155\141\061 +\024\060\022\006\003\125\004\007\014\013\120\141\156\141\155\141 +\040\103\151\164\171\061\044\060\042\006\003\125\004\012\014\033 +\124\162\165\163\164\103\157\162\040\123\171\163\164\145\155\163 +\040\123\056\040\144\145\040\122\056\114\056\061\047\060\045\006 +\003\125\004\013\014\036\124\162\165\163\164\103\157\162\040\103 +\145\162\164\151\146\151\143\141\164\145\040\101\165\164\150\157 +\162\151\164\171\061\037\060\035\006\003\125\004\003\014\026\124 +\162\165\163\164\103\157\162\040\122\157\157\164\103\145\162\164 +\040\103\101\055\061\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\277\216\267\225\342\302\046\022\153\063 +\031\307\100\130\012\253\131\252\215\000\243\374\200\307\120\173 +\216\324\040\046\272\062\022\330\043\124\111\045\020\042\230\235 +\106\322\301\311\236\116\033\056\054\016\070\363\032\045\150\034 +\246\132\005\346\036\213\110\277\230\226\164\076\151\312\351\265 +\170\245\006\274\325\000\136\011\012\362\047\172\122\374\055\325 +\261\352\264\211\141\044\363\032\023\333\251\317\122\355\014\044 +\272\271\236\354\176\000\164\372\223\255\154\051\222\256\121\264 +\273\323\127\277\263\363\250\215\234\364\044\113\052\326\231\236 +\364\236\376\300\176\102\072\347\013\225\123\332\267\150\016\220 +\114\373\160\077\217\112\054\224\363\046\335\143\151\251\224\330 +\020\116\305\107\010\220\231\033\027\115\271\154\156\357\140\225 +\021\216\041\200\265\275\240\163\330\320\262\167\304\105\352\132 +\046\373\146\166\166\370\006\037\141\155\017\125\305\203\267\020 +\126\162\006\007\245\363\261\032\003\005\144\016\235\132\212\326 +\206\160\033\044\336\376\050\212\053\320\152\260\374\172\242\334 +\262\171\016\213\145\017\002\003\001\000\001\243\143\060\141\060 +\035\006\003\125\035\016\004\026\004\024\356\153\111\074\172\077 +\015\343\261\011\267\212\310\253\031\237\163\063\120\347\060\037 +\006\003\125\035\043\004\030\060\026\200\024\356\153\111\074\172 +\077\015\343\261\011\267\212\310\253\031\237\163\063\120\347\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\206 +\060\015\006\011\052\206\110\206\367\015\001\001\013\005\000\003 +\202\001\001\000\045\030\324\221\217\023\356\217\036\035\021\123 +\332\055\104\051\031\240\036\153\061\236\115\016\236\255\075\134 +\101\157\225\053\044\241\171\230\072\070\066\373\273\146\236\110 +\377\220\220\357\075\324\270\233\264\207\165\077\040\233\316\162 +\317\241\125\301\115\144\242\031\006\241\007\063\014\013\051\345 +\361\352\253\243\354\265\012\164\220\307\175\162\362\327\134\237 +\221\357\221\213\267\334\355\146\242\317\216\146\073\274\237\072 +\002\340\047\335\026\230\300\225\324\012\244\344\201\232\165\224 +\065\234\220\137\210\067\006\255\131\225\012\260\321\147\323\031 +\312\211\347\062\132\066\034\076\202\250\132\223\276\306\320\144 +\221\266\317\331\266\030\317\333\176\322\145\243\246\304\216\027 +\061\301\373\176\166\333\323\205\343\130\262\167\172\166\073\154 +\057\120\034\347\333\366\147\171\037\365\202\225\232\007\247\024 +\257\217\334\050\041\147\011\322\326\115\132\034\031\034\216\167 +\134\303\224\044\075\062\153\113\176\324\170\224\203\276\067\115 +\316\137\307\036\116\074\340\211\063\225\013\017\245\062\326\074 +\132\171\054\031 +END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE + +# Trust for "TrustCor RootCert CA-1" +# Issuer: CN=TrustCor RootCert CA-1,OU=TrustCor Certificate Authority,O=TrustCor Systems S. de R.L.,L=Panama City,ST=Panama,C=PA +# Serial Number:00:da:9b:ec:71:f3:03:b0:19 +# Subject: CN=TrustCor RootCert CA-1,OU=TrustCor Certificate Authority,O=TrustCor Systems S. de R.L.,L=Panama City,ST=Panama,C=PA +# Not Valid Before: Thu Feb 04 12:32:16 2016 +# Not Valid After : Mon Dec 31 17:23:16 2029 +# Fingerprint (SHA-256): D4:0E:9C:86:CD:8F:E4:68:C1:77:69:59:F4:9E:A7:74:FA:54:86:84:B6:C4:06:F3:90:92:61:F4:DC:E2:57:5C +# Fingerprint (SHA1): FF:BD:CD:E7:82:C8:43:5E:3C:6F:26:86:5C:CA:A8:3A:45:5B:C3:0A +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 "TrustCor RootCert CA-1" +CKA_CERT_SHA1_HASH MULTILINE_OCTAL +\377\275\315\347\202\310\103\136\074\157\046\206\134\312\250\072 +\105\133\303\012 +END +CKA_CERT_MD5_HASH MULTILINE_OCTAL +\156\205\361\334\032\000\323\042\325\262\262\254\153\067\005\105 +END +CKA_ISSUER MULTILINE_OCTAL +\060\201\244\061\013\060\011\006\003\125\004\006\023\002\120\101 +\061\017\060\015\006\003\125\004\010\014\006\120\141\156\141\155 +\141\061\024\060\022\006\003\125\004\007\014\013\120\141\156\141 +\155\141\040\103\151\164\171\061\044\060\042\006\003\125\004\012 +\014\033\124\162\165\163\164\103\157\162\040\123\171\163\164\145 +\155\163\040\123\056\040\144\145\040\122\056\114\056\061\047\060 +\045\006\003\125\004\013\014\036\124\162\165\163\164\103\157\162 +\040\103\145\162\164\151\146\151\143\141\164\145\040\101\165\164 +\150\157\162\151\164\171\061\037\060\035\006\003\125\004\003\014 +\026\124\162\165\163\164\103\157\162\040\122\157\157\164\103\145 +\162\164\040\103\101\055\061 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\011\000\332\233\354\161\363\003\260\031 +END +CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR +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 "TrustCor RootCert CA-2" +# +# Issuer: CN=TrustCor RootCert CA-2,OU=TrustCor Certificate Authority,O=TrustCor Systems S. de R.L.,L=Panama City,ST=Panama,C=PA +# Serial Number:25:a1:df:ca:33:cb:59:02 +# Subject: CN=TrustCor RootCert CA-2,OU=TrustCor Certificate Authority,O=TrustCor Systems S. de R.L.,L=Panama City,ST=Panama,C=PA +# Not Valid Before: Thu Feb 04 12:32:23 2016 +# Not Valid After : Sun Dec 31 17:26:39 2034 +# Fingerprint (SHA-256): 07:53:E9:40:37:8C:1B:D5:E3:83:6E:39:5D:AE:A5:CB:83:9E:50:46:F1:BD:0E:AE:19:51:CF:10:FE:C7:C9:65 +# Fingerprint (SHA1): B8:BE:6D:CB:56:F1:55:B9:63:D4:12:CA:4E:06:34:C7:94:B2:1C:C0 +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 "TrustCor RootCert CA-2" +CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 +CKA_SUBJECT MULTILINE_OCTAL +\060\201\244\061\013\060\011\006\003\125\004\006\023\002\120\101 +\061\017\060\015\006\003\125\004\010\014\006\120\141\156\141\155 +\141\061\024\060\022\006\003\125\004\007\014\013\120\141\156\141 +\155\141\040\103\151\164\171\061\044\060\042\006\003\125\004\012 +\014\033\124\162\165\163\164\103\157\162\040\123\171\163\164\145 +\155\163\040\123\056\040\144\145\040\122\056\114\056\061\047\060 +\045\006\003\125\004\013\014\036\124\162\165\163\164\103\157\162 +\040\103\145\162\164\151\146\151\143\141\164\145\040\101\165\164 +\150\157\162\151\164\171\061\037\060\035\006\003\125\004\003\014 +\026\124\162\165\163\164\103\157\162\040\122\157\157\164\103\145 +\162\164\040\103\101\055\062 +END +CKA_ID UTF8 "0" +CKA_ISSUER MULTILINE_OCTAL +\060\201\244\061\013\060\011\006\003\125\004\006\023\002\120\101 +\061\017\060\015\006\003\125\004\010\014\006\120\141\156\141\155 +\141\061\024\060\022\006\003\125\004\007\014\013\120\141\156\141 +\155\141\040\103\151\164\171\061\044\060\042\006\003\125\004\012 +\014\033\124\162\165\163\164\103\157\162\040\123\171\163\164\145 +\155\163\040\123\056\040\144\145\040\122\056\114\056\061\047\060 +\045\006\003\125\004\013\014\036\124\162\165\163\164\103\157\162 +\040\103\145\162\164\151\146\151\143\141\164\145\040\101\165\164 +\150\157\162\151\164\171\061\037\060\035\006\003\125\004\003\014 +\026\124\162\165\163\164\103\157\162\040\122\157\157\164\103\145 +\162\164\040\103\101\055\062 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\010\045\241\337\312\063\313\131\002 +END +CKA_VALUE MULTILINE_OCTAL +\060\202\006\057\060\202\004\027\240\003\002\001\002\002\010\045 +\241\337\312\063\313\131\002\060\015\006\011\052\206\110\206\367 +\015\001\001\013\005\000\060\201\244\061\013\060\011\006\003\125 +\004\006\023\002\120\101\061\017\060\015\006\003\125\004\010\014 +\006\120\141\156\141\155\141\061\024\060\022\006\003\125\004\007 +\014\013\120\141\156\141\155\141\040\103\151\164\171\061\044\060 +\042\006\003\125\004\012\014\033\124\162\165\163\164\103\157\162 +\040\123\171\163\164\145\155\163\040\123\056\040\144\145\040\122 +\056\114\056\061\047\060\045\006\003\125\004\013\014\036\124\162 +\165\163\164\103\157\162\040\103\145\162\164\151\146\151\143\141 +\164\145\040\101\165\164\150\157\162\151\164\171\061\037\060\035 +\006\003\125\004\003\014\026\124\162\165\163\164\103\157\162\040 +\122\157\157\164\103\145\162\164\040\103\101\055\062\060\036\027 +\015\061\066\060\062\060\064\061\062\063\062\062\063\132\027\015 +\063\064\061\062\063\061\061\067\062\066\063\071\132\060\201\244 +\061\013\060\011\006\003\125\004\006\023\002\120\101\061\017\060 +\015\006\003\125\004\010\014\006\120\141\156\141\155\141\061\024 +\060\022\006\003\125\004\007\014\013\120\141\156\141\155\141\040 +\103\151\164\171\061\044\060\042\006\003\125\004\012\014\033\124 +\162\165\163\164\103\157\162\040\123\171\163\164\145\155\163\040 +\123\056\040\144\145\040\122\056\114\056\061\047\060\045\006\003 +\125\004\013\014\036\124\162\165\163\164\103\157\162\040\103\145 +\162\164\151\146\151\143\141\164\145\040\101\165\164\150\157\162 +\151\164\171\061\037\060\035\006\003\125\004\003\014\026\124\162 +\165\163\164\103\157\162\040\122\157\157\164\103\145\162\164\040 +\103\101\055\062\060\202\002\042\060\015\006\011\052\206\110\206 +\367\015\001\001\001\005\000\003\202\002\017\000\060\202\002\012 +\002\202\002\001\000\247\040\156\302\052\242\142\044\225\220\166 +\310\070\176\200\322\253\301\233\145\005\224\364\301\012\020\325 +\002\254\355\237\223\307\207\310\260\047\053\102\014\075\012\076 +\101\132\236\165\335\215\312\340\233\354\150\062\244\151\222\150 +\214\013\201\016\126\240\076\032\335\054\045\024\202\057\227\323 +\144\106\364\124\251\334\072\124\055\061\053\231\202\362\331\052 +\327\357\161\000\270\061\244\276\172\044\007\303\102\040\362\212 +\324\222\004\033\145\126\114\154\324\373\266\141\132\107\043\264 +\330\151\264\267\072\320\164\074\014\165\241\214\116\166\241\351 +\333\052\245\073\372\316\260\377\176\152\050\375\047\034\310\261 +\351\051\361\127\156\144\264\320\301\025\155\016\276\056\016\106 +\310\136\364\121\376\357\016\143\072\073\161\272\317\157\131\312 +\014\343\233\135\111\270\114\342\127\261\230\212\102\127\234\166 +\357\357\275\321\150\250\322\364\011\273\167\065\276\045\202\010 +\304\026\054\104\040\126\251\104\021\167\357\135\264\035\252\136 +\153\076\213\062\366\007\057\127\004\222\312\365\376\235\302\351 +\350\263\216\114\113\002\061\331\344\074\110\202\047\367\030\202 +\166\110\072\161\261\023\241\071\325\056\305\064\302\035\142\205 +\337\003\376\115\364\257\075\337\134\133\215\372\160\341\245\176 +\047\307\206\056\152\217\022\306\204\136\103\121\120\234\031\233 +\170\346\374\366\355\107\176\173\075\146\357\023\023\210\137\074 +\241\143\373\371\254\207\065\237\363\202\236\244\077\012\234\061 +\151\213\231\244\210\112\216\156\146\115\357\026\304\017\171\050 +\041\140\015\205\026\175\327\124\070\361\222\126\375\265\063\114 +\203\334\327\020\237\113\375\306\370\102\275\272\174\163\002\340 +\377\175\315\133\341\324\254\141\173\127\325\112\173\133\324\205 +\130\047\135\277\370\053\140\254\240\046\256\024\041\047\306\167 +\232\063\200\074\136\106\077\367\303\261\243\206\063\306\350\136 +\015\271\065\054\252\106\301\205\002\165\200\240\353\044\373\025 +\252\344\147\177\156\167\077\364\004\212\057\174\173\343\027\141 +\360\335\011\251\040\310\276\011\244\320\176\104\303\262\060\112 +\070\252\251\354\030\232\007\202\053\333\270\234\030\255\332\340 +\106\027\254\317\135\002\003\001\000\001\243\143\060\141\060\035 +\006\003\125\035\016\004\026\004\024\331\376\041\100\156\224\236 +\274\233\075\234\175\230\040\031\345\214\060\142\262\060\037\006 +\003\125\035\043\004\030\060\026\200\024\331\376\041\100\156\224 +\236\274\233\075\234\175\230\040\031\345\214\060\142\262\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\206\060 +\015\006\011\052\206\110\206\367\015\001\001\013\005\000\003\202 +\002\001\000\236\105\236\014\073\266\357\341\072\310\174\321\000 +\075\317\342\352\006\265\262\072\273\006\113\150\172\320\043\227 +\164\247\054\360\010\330\171\132\327\132\204\212\330\022\232\033 +\331\175\134\115\160\305\245\371\253\345\243\211\211\335\001\372 +\354\335\371\351\222\227\333\260\106\102\363\323\142\252\225\376 +\061\147\024\151\130\220\012\252\013\356\067\043\307\120\121\264 +\365\176\236\343\173\367\344\314\102\062\055\111\014\313\377\111 +\014\233\036\064\375\156\156\226\212\171\003\266\157\333\011\313 +\375\137\145\024\067\341\070\365\363\141\026\130\344\265\155\015 +\013\004\033\077\120\055\177\263\307\172\032\026\200\140\370\212 +\037\351\033\052\306\371\272\001\032\151\277\322\130\307\124\127 +\010\217\341\071\140\167\113\254\131\204\032\210\361\335\313\117 +\170\327\347\341\063\055\374\356\101\372\040\260\276\313\367\070 +\224\300\341\320\205\017\273\355\054\163\253\355\376\222\166\032 +\144\177\133\015\063\011\007\063\173\006\077\021\244\134\160\074 +\205\300\317\343\220\250\203\167\372\333\346\305\214\150\147\020 +\147\245\122\055\360\304\231\217\177\277\321\153\342\265\107\326 +\331\320\205\231\115\224\233\017\113\215\356\000\132\107\035\021 +\003\254\101\030\257\207\267\157\014\072\217\312\317\334\003\301 +\242\011\310\345\375\200\136\310\140\102\001\033\032\123\132\273 +\067\246\267\274\272\204\351\036\154\032\324\144\332\324\103\376 +\223\213\113\362\054\171\026\020\324\223\013\210\217\241\330\206 +\024\106\221\107\233\050\044\357\127\122\116\134\102\234\252\367 +\111\354\047\350\100\036\263\246\211\042\162\234\365\015\063\264 +\130\243\060\073\335\324\152\124\223\276\032\115\363\223\224\367 +\374\204\013\077\204\040\134\064\003\104\305\332\255\274\012\301 +\002\317\036\345\224\331\363\216\133\330\114\360\235\354\141\027 +\273\024\062\124\014\002\051\223\036\222\206\366\177\357\347\222 +\005\016\131\335\231\010\056\056\372\234\000\122\323\305\146\051 +\344\247\227\104\244\016\050\201\023\065\305\366\157\144\346\101 +\304\325\057\314\064\105\045\317\101\000\226\075\112\056\302\226 +\230\117\116\112\234\227\267\333\037\222\062\310\377\017\121\156 +\326\354\011 +END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE + +# Trust for "TrustCor RootCert CA-2" +# Issuer: CN=TrustCor RootCert CA-2,OU=TrustCor Certificate Authority,O=TrustCor Systems S. de R.L.,L=Panama City,ST=Panama,C=PA +# Serial Number:25:a1:df:ca:33:cb:59:02 +# Subject: CN=TrustCor RootCert CA-2,OU=TrustCor Certificate Authority,O=TrustCor Systems S. de R.L.,L=Panama City,ST=Panama,C=PA +# Not Valid Before: Thu Feb 04 12:32:23 2016 +# Not Valid After : Sun Dec 31 17:26:39 2034 +# Fingerprint (SHA-256): 07:53:E9:40:37:8C:1B:D5:E3:83:6E:39:5D:AE:A5:CB:83:9E:50:46:F1:BD:0E:AE:19:51:CF:10:FE:C7:C9:65 +# Fingerprint (SHA1): B8:BE:6D:CB:56:F1:55:B9:63:D4:12:CA:4E:06:34:C7:94:B2:1C:C0 +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 "TrustCor RootCert CA-2" +CKA_CERT_SHA1_HASH MULTILINE_OCTAL +\270\276\155\313\126\361\125\271\143\324\022\312\116\006\064\307 +\224\262\034\300 +END +CKA_CERT_MD5_HASH MULTILINE_OCTAL +\242\341\370\030\013\272\105\325\307\101\052\273\067\122\105\144 +END +CKA_ISSUER MULTILINE_OCTAL +\060\201\244\061\013\060\011\006\003\125\004\006\023\002\120\101 +\061\017\060\015\006\003\125\004\010\014\006\120\141\156\141\155 +\141\061\024\060\022\006\003\125\004\007\014\013\120\141\156\141 +\155\141\040\103\151\164\171\061\044\060\042\006\003\125\004\012 +\014\033\124\162\165\163\164\103\157\162\040\123\171\163\164\145 +\155\163\040\123\056\040\144\145\040\122\056\114\056\061\047\060 +\045\006\003\125\004\013\014\036\124\162\165\163\164\103\157\162 +\040\103\145\162\164\151\146\151\143\141\164\145\040\101\165\164 +\150\157\162\151\164\171\061\037\060\035\006\003\125\004\003\014 +\026\124\162\165\163\164\103\157\162\040\122\157\157\164\103\145 +\162\164\040\103\101\055\062 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\010\045\241\337\312\063\313\131\002 +END +CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR +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 "TrustCor ECA-1" +# +# Issuer: CN=TrustCor ECA-1,OU=TrustCor Certificate Authority,O=TrustCor Systems S. de R.L.,L=Panama City,ST=Panama,C=PA +# Serial Number:00:84:82:2c:5f:1c:62:d0:40 +# Subject: CN=TrustCor ECA-1,OU=TrustCor Certificate Authority,O=TrustCor Systems S. de R.L.,L=Panama City,ST=Panama,C=PA +# Not Valid Before: Thu Feb 04 12:32:33 2016 +# Not Valid After : Mon Dec 31 17:28:07 2029 +# Fingerprint (SHA-256): 5A:88:5D:B1:9C:01:D9:12:C5:75:93:88:93:8C:AF:BB:DF:03:1A:B2:D4:8E:91:EE:15:58:9B:42:97:1D:03:9C +# Fingerprint (SHA1): 58:D1:DF:95:95:67:6B:63:C0:F0:5B:1C:17:4D:8B:84:0B:C8:78:BD +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 "TrustCor ECA-1" +CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 +CKA_SUBJECT MULTILINE_OCTAL +\060\201\234\061\013\060\011\006\003\125\004\006\023\002\120\101 +\061\017\060\015\006\003\125\004\010\014\006\120\141\156\141\155 +\141\061\024\060\022\006\003\125\004\007\014\013\120\141\156\141 +\155\141\040\103\151\164\171\061\044\060\042\006\003\125\004\012 +\014\033\124\162\165\163\164\103\157\162\040\123\171\163\164\145 +\155\163\040\123\056\040\144\145\040\122\056\114\056\061\047\060 +\045\006\003\125\004\013\014\036\124\162\165\163\164\103\157\162 +\040\103\145\162\164\151\146\151\143\141\164\145\040\101\165\164 +\150\157\162\151\164\171\061\027\060\025\006\003\125\004\003\014 +\016\124\162\165\163\164\103\157\162\040\105\103\101\055\061 +END +CKA_ID UTF8 "0" +CKA_ISSUER MULTILINE_OCTAL +\060\201\234\061\013\060\011\006\003\125\004\006\023\002\120\101 +\061\017\060\015\006\003\125\004\010\014\006\120\141\156\141\155 +\141\061\024\060\022\006\003\125\004\007\014\013\120\141\156\141 +\155\141\040\103\151\164\171\061\044\060\042\006\003\125\004\012 +\014\033\124\162\165\163\164\103\157\162\040\123\171\163\164\145 +\155\163\040\123\056\040\144\145\040\122\056\114\056\061\047\060 +\045\006\003\125\004\013\014\036\124\162\165\163\164\103\157\162 +\040\103\145\162\164\151\146\151\143\141\164\145\040\101\165\164 +\150\157\162\151\164\171\061\027\060\025\006\003\125\004\003\014 +\016\124\162\165\163\164\103\157\162\040\105\103\101\055\061 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\011\000\204\202\054\137\034\142\320\100 +END +CKA_VALUE MULTILINE_OCTAL +\060\202\004\040\060\202\003\010\240\003\002\001\002\002\011\000 +\204\202\054\137\034\142\320\100\060\015\006\011\052\206\110\206 +\367\015\001\001\013\005\000\060\201\234\061\013\060\011\006\003 +\125\004\006\023\002\120\101\061\017\060\015\006\003\125\004\010 +\014\006\120\141\156\141\155\141\061\024\060\022\006\003\125\004 +\007\014\013\120\141\156\141\155\141\040\103\151\164\171\061\044 +\060\042\006\003\125\004\012\014\033\124\162\165\163\164\103\157 +\162\040\123\171\163\164\145\155\163\040\123\056\040\144\145\040 +\122\056\114\056\061\047\060\045\006\003\125\004\013\014\036\124 +\162\165\163\164\103\157\162\040\103\145\162\164\151\146\151\143 +\141\164\145\040\101\165\164\150\157\162\151\164\171\061\027\060 +\025\006\003\125\004\003\014\016\124\162\165\163\164\103\157\162 +\040\105\103\101\055\061\060\036\027\015\061\066\060\062\060\064 +\061\062\063\062\063\063\132\027\015\062\071\061\062\063\061\061 +\067\062\070\060\067\132\060\201\234\061\013\060\011\006\003\125 +\004\006\023\002\120\101\061\017\060\015\006\003\125\004\010\014 +\006\120\141\156\141\155\141\061\024\060\022\006\003\125\004\007 +\014\013\120\141\156\141\155\141\040\103\151\164\171\061\044\060 +\042\006\003\125\004\012\014\033\124\162\165\163\164\103\157\162 +\040\123\171\163\164\145\155\163\040\123\056\040\144\145\040\122 +\056\114\056\061\047\060\045\006\003\125\004\013\014\036\124\162 +\165\163\164\103\157\162\040\103\145\162\164\151\146\151\143\141 +\164\145\040\101\165\164\150\157\162\151\164\171\061\027\060\025 +\006\003\125\004\003\014\016\124\162\165\163\164\103\157\162\040 +\105\103\101\055\061\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\317\217\340\021\265\237\250\166\166\333 +\337\017\124\357\163\143\051\202\255\107\306\243\153\355\376\137 +\063\370\103\121\351\032\063\221\061\027\240\164\304\324\247\001 +\346\262\222\076\152\235\355\016\371\164\230\100\323\077\003\200 +\006\202\100\350\261\342\247\121\247\035\203\046\153\253\336\372 +\027\221\053\330\306\254\036\261\236\031\001\325\227\246\352\015 +\267\304\125\037\047\174\322\010\325\166\037\051\025\207\100\071 +\335\070\105\021\165\320\232\247\064\340\277\315\310\122\035\271 +\107\176\015\270\273\306\014\366\163\127\026\132\176\103\221\037 +\125\072\306\155\104\004\252\234\251\234\247\114\211\027\203\256 +\243\004\136\122\200\213\036\022\045\021\031\327\014\175\175\061 +\104\101\352\333\257\260\034\357\201\320\054\305\232\041\233\075 +\355\102\073\120\046\362\354\316\161\141\006\142\041\124\116\177 +\301\235\076\177\040\214\200\313\052\330\227\142\310\203\063\221 +\175\260\242\132\017\127\350\073\314\362\045\262\324\174\057\354 +\115\306\241\072\025\172\347\266\135\065\365\366\110\112\066\105 +\146\324\272\230\130\301\002\003\001\000\001\243\143\060\141\060 +\035\006\003\125\035\016\004\026\004\024\104\236\110\365\314\155 +\110\324\240\113\177\376\131\044\057\203\227\231\232\206\060\037 +\006\003\125\035\043\004\030\060\026\200\024\104\236\110\365\314 +\155\110\324\240\113\177\376\131\044\057\203\227\231\232\206\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\206 +\060\015\006\011\052\206\110\206\367\015\001\001\013\005\000\003 +\202\001\001\000\005\076\065\134\025\160\233\311\307\163\141\157 +\162\053\324\302\217\362\103\135\002\316\304\224\271\224\021\203 +\147\135\342\147\154\165\166\277\273\014\252\066\306\255\107\223 +\143\334\036\176\326\336\056\376\351\031\062\070\003\177\024\366 +\000\163\054\131\261\041\006\341\373\254\030\225\014\243\377\231 +\226\367\053\047\233\325\044\314\035\335\301\072\340\230\104\260 +\304\344\076\167\261\163\251\144\054\366\034\001\174\077\135\105 +\205\300\205\347\045\217\225\334\027\363\074\237\032\156\260\312 +\343\035\052\351\114\143\372\044\141\142\326\332\176\266\034\154 +\365\002\035\324\052\335\125\220\353\052\021\107\074\056\136\164 +\262\202\042\245\175\123\037\105\354\047\221\175\347\042\026\350 +\300\150\066\330\306\361\117\200\104\062\371\341\321\321\035\252 +\336\250\253\234\004\257\255\040\016\144\230\115\245\153\300\110 +\130\226\151\115\334\007\214\121\223\242\337\237\017\075\213\140 +\264\202\215\252\010\116\142\105\340\371\013\322\340\340\074\133 +\336\134\161\047\045\302\346\003\201\213\020\123\343\307\125\242 +\264\237\327\346 +END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE + +# Trust for "TrustCor ECA-1" +# Issuer: CN=TrustCor ECA-1,OU=TrustCor Certificate Authority,O=TrustCor Systems S. de R.L.,L=Panama City,ST=Panama,C=PA +# Serial Number:00:84:82:2c:5f:1c:62:d0:40 +# Subject: CN=TrustCor ECA-1,OU=TrustCor Certificate Authority,O=TrustCor Systems S. de R.L.,L=Panama City,ST=Panama,C=PA +# Not Valid Before: Thu Feb 04 12:32:33 2016 +# Not Valid After : Mon Dec 31 17:28:07 2029 +# Fingerprint (SHA-256): 5A:88:5D:B1:9C:01:D9:12:C5:75:93:88:93:8C:AF:BB:DF:03:1A:B2:D4:8E:91:EE:15:58:9B:42:97:1D:03:9C +# Fingerprint (SHA1): 58:D1:DF:95:95:67:6B:63:C0:F0:5B:1C:17:4D:8B:84:0B:C8:78:BD +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 "TrustCor ECA-1" +CKA_CERT_SHA1_HASH MULTILINE_OCTAL +\130\321\337\225\225\147\153\143\300\360\133\034\027\115\213\204 +\013\310\170\275 +END +CKA_CERT_MD5_HASH MULTILINE_OCTAL +\047\222\043\035\012\365\100\174\351\346\153\235\330\365\347\154 +END +CKA_ISSUER MULTILINE_OCTAL +\060\201\234\061\013\060\011\006\003\125\004\006\023\002\120\101 +\061\017\060\015\006\003\125\004\010\014\006\120\141\156\141\155 +\141\061\024\060\022\006\003\125\004\007\014\013\120\141\156\141 +\155\141\040\103\151\164\171\061\044\060\042\006\003\125\004\012 +\014\033\124\162\165\163\164\103\157\162\040\123\171\163\164\145 +\155\163\040\123\056\040\144\145\040\122\056\114\056\061\047\060 +\045\006\003\125\004\013\014\036\124\162\165\163\164\103\157\162 +\040\103\145\162\164\151\146\151\143\141\164\145\040\101\165\164 +\150\157\162\151\164\171\061\027\060\025\006\003\125\004\003\014 +\016\124\162\165\163\164\103\157\162\040\105\103\101\055\061 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\011\000\204\202\054\137\034\142\320\100 +END +CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR +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 "SSL.com Root Certification Authority RSA" +# +# Issuer: CN=SSL.com Root Certification Authority RSA,O=SSL Corporation,L=Houston,ST=Texas,C=US +# Serial Number:7b:2c:9b:d3:16:80:32:99 +# Subject: CN=SSL.com Root Certification Authority RSA,O=SSL Corporation,L=Houston,ST=Texas,C=US +# Not Valid Before: Fri Feb 12 17:39:39 2016 +# Not Valid After : Tue Feb 12 17:39:39 2041 +# Fingerprint (SHA-256): 85:66:6A:56:2E:E0:BE:5C:E9:25:C1:D8:89:0A:6F:76:A8:7E:C1:6D:4D:7D:5F:29:EA:74:19:CF:20:12:3B:69 +# Fingerprint (SHA1): B7:AB:33:08:D1:EA:44:77:BA:14:80:12:5A:6F:BD:A9:36:49:0C:BB +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 "SSL.com Root Certification Authority RSA" +CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 +CKA_SUBJECT MULTILINE_OCTAL +\060\174\061\013\060\011\006\003\125\004\006\023\002\125\123\061 +\016\060\014\006\003\125\004\010\014\005\124\145\170\141\163\061 +\020\060\016\006\003\125\004\007\014\007\110\157\165\163\164\157 +\156\061\030\060\026\006\003\125\004\012\014\017\123\123\114\040 +\103\157\162\160\157\162\141\164\151\157\156\061\061\060\057\006 +\003\125\004\003\014\050\123\123\114\056\143\157\155\040\122\157 +\157\164\040\103\145\162\164\151\146\151\143\141\164\151\157\156 +\040\101\165\164\150\157\162\151\164\171\040\122\123\101 +END +CKA_ID UTF8 "0" +CKA_ISSUER MULTILINE_OCTAL +\060\174\061\013\060\011\006\003\125\004\006\023\002\125\123\061 +\016\060\014\006\003\125\004\010\014\005\124\145\170\141\163\061 +\020\060\016\006\003\125\004\007\014\007\110\157\165\163\164\157 +\156\061\030\060\026\006\003\125\004\012\014\017\123\123\114\040 +\103\157\162\160\157\162\141\164\151\157\156\061\061\060\057\006 +\003\125\004\003\014\050\123\123\114\056\143\157\155\040\122\157 +\157\164\040\103\145\162\164\151\146\151\143\141\164\151\157\156 +\040\101\165\164\150\157\162\151\164\171\040\122\123\101 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\010\173\054\233\323\026\200\062\231 +END +CKA_VALUE MULTILINE_OCTAL +\060\202\005\335\060\202\003\305\240\003\002\001\002\002\010\173 +\054\233\323\026\200\062\231\060\015\006\011\052\206\110\206\367 +\015\001\001\013\005\000\060\174\061\013\060\011\006\003\125\004 +\006\023\002\125\123\061\016\060\014\006\003\125\004\010\014\005 +\124\145\170\141\163\061\020\060\016\006\003\125\004\007\014\007 +\110\157\165\163\164\157\156\061\030\060\026\006\003\125\004\012 +\014\017\123\123\114\040\103\157\162\160\157\162\141\164\151\157 +\156\061\061\060\057\006\003\125\004\003\014\050\123\123\114\056 +\143\157\155\040\122\157\157\164\040\103\145\162\164\151\146\151 +\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171 +\040\122\123\101\060\036\027\015\061\066\060\062\061\062\061\067 +\063\071\063\071\132\027\015\064\061\060\062\061\062\061\067\063 +\071\063\071\132\060\174\061\013\060\011\006\003\125\004\006\023 +\002\125\123\061\016\060\014\006\003\125\004\010\014\005\124\145 +\170\141\163\061\020\060\016\006\003\125\004\007\014\007\110\157 +\165\163\164\157\156\061\030\060\026\006\003\125\004\012\014\017 +\123\123\114\040\103\157\162\160\157\162\141\164\151\157\156\061 +\061\060\057\006\003\125\004\003\014\050\123\123\114\056\143\157 +\155\040\122\157\157\164\040\103\145\162\164\151\146\151\143\141 +\164\151\157\156\040\101\165\164\150\157\162\151\164\171\040\122 +\123\101\060\202\002\042\060\015\006\011\052\206\110\206\367\015 +\001\001\001\005\000\003\202\002\017\000\060\202\002\012\002\202 +\002\001\000\371\017\335\243\053\175\313\320\052\376\354\147\205 +\246\347\056\033\272\167\341\343\365\257\244\354\372\112\135\221 +\304\127\107\153\030\167\153\166\362\375\223\344\075\017\302\026 +\236\013\146\303\126\224\236\027\203\205\316\126\357\362\026\375 +\000\142\365\042\011\124\350\145\027\116\101\271\340\117\106\227 +\252\033\310\270\156\142\136\151\261\137\333\052\002\176\374\154 +\312\363\101\330\355\320\350\374\077\141\110\355\260\003\024\035 +\020\016\113\031\340\273\116\354\206\145\377\066\363\136\147\002 +\013\235\206\125\141\375\172\070\355\376\342\031\000\267\157\241 +\120\142\165\164\074\240\372\310\045\222\264\156\172\042\307\370 +\036\241\343\262\335\221\061\253\053\035\004\377\245\112\004\067 +\351\205\244\063\053\375\342\326\125\064\174\031\244\112\150\307 +\262\250\323\267\312\241\223\210\353\301\227\274\214\371\035\331 +\042\204\044\164\307\004\075\152\251\051\223\314\353\270\133\341 +\376\137\045\252\064\130\310\301\043\124\235\033\230\021\303\070 +\234\176\075\206\154\245\017\100\206\174\002\364\134\002\117\050 +\313\256\161\237\017\072\310\063\376\021\045\065\352\374\272\305 +\140\075\331\174\030\325\262\251\323\165\170\003\162\042\312\072 +\303\037\357\054\345\056\251\372\236\054\266\121\106\375\257\003 +\326\352\140\150\352\205\026\066\153\205\351\036\300\263\335\304 +\044\334\200\052\201\101\155\224\076\310\340\311\201\101\000\236 +\136\277\177\305\010\230\242\030\054\102\100\263\371\157\070\047 +\113\116\200\364\075\201\107\340\210\174\352\034\316\265\165\134 +\121\056\034\053\177\032\162\050\347\000\265\321\164\306\327\344 +\237\255\007\223\266\123\065\065\374\067\344\303\366\135\026\276 +\041\163\336\222\012\370\240\143\152\274\226\222\152\076\370\274 +\145\125\233\336\365\015\211\046\004\374\045\032\246\045\151\313 +\302\155\312\174\342\131\137\227\254\353\357\056\310\274\327\033 +\131\074\053\314\362\031\310\223\153\047\143\031\317\374\351\046 +\370\312\161\233\177\223\376\064\147\204\116\231\353\374\263\170 +\011\063\160\272\146\246\166\355\033\163\353\032\245\015\304\042 +\023\040\224\126\012\116\054\154\116\261\375\317\234\011\272\242 +\063\355\207\002\003\001\000\001\243\143\060\141\060\035\006\003 +\125\035\016\004\026\004\024\335\004\011\007\242\365\172\175\122 +\123\022\222\225\356\070\200\045\015\246\131\060\017\006\003\125 +\035\023\001\001\377\004\005\060\003\001\001\377\060\037\006\003 +\125\035\043\004\030\060\026\200\024\335\004\011\007\242\365\172 +\175\122\123\022\222\225\356\070\200\045\015\246\131\060\016\006 +\003\125\035\017\001\001\377\004\004\003\002\001\206\060\015\006 +\011\052\206\110\206\367\015\001\001\013\005\000\003\202\002\001 +\000\040\030\021\224\051\373\046\235\034\036\036\160\141\361\225 +\162\223\161\044\255\150\223\130\216\062\257\033\263\160\003\374 +\045\053\164\205\220\075\170\152\364\271\213\245\227\073\265\030 +\221\273\036\247\371\100\133\221\371\125\231\257\036\021\320\134 +\035\247\146\343\261\224\007\014\062\071\246\352\033\260\171\330 +\035\234\160\104\343\212\335\304\371\225\037\212\070\103\077\001 +\205\245\107\247\075\106\262\274\345\042\150\367\173\234\330\054 +\076\012\041\310\055\063\254\277\305\201\231\061\164\301\165\161 +\305\276\261\360\043\105\364\235\153\374\031\143\235\243\274\004 +\306\030\013\045\273\123\211\017\263\200\120\336\105\356\104\177 +\253\224\170\144\230\323\366\050\335\207\330\160\145\164\373\016 +\271\023\353\247\017\141\251\062\226\314\336\273\355\143\114\030 +\273\251\100\367\240\124\156\040\210\161\165\030\352\172\264\064 +\162\340\043\047\167\134\266\220\352\206\045\100\253\357\063\017 +\313\237\202\276\242\040\373\366\265\055\032\346\302\205\261\164 +\017\373\310\145\002\244\122\001\107\335\111\042\301\277\330\353 +\153\254\176\336\354\143\063\025\267\043\010\217\306\017\215\101 +\132\335\216\305\271\217\345\105\077\170\333\272\322\033\100\261 +\376\161\115\077\340\201\242\272\136\264\354\025\340\223\335\010 +\037\176\341\125\231\013\041\336\223\236\012\373\346\243\111\275 +\066\060\376\347\167\262\240\165\227\265\055\201\210\027\145\040 +\367\332\220\000\237\311\122\314\062\312\065\174\365\075\017\330 +\053\327\365\046\154\311\006\064\226\026\352\160\131\032\062\171 +\171\013\266\210\177\017\122\110\075\277\154\330\242\104\056\321 +\116\267\162\130\323\211\023\225\376\104\253\370\327\213\033\156 +\234\274\054\240\133\325\152\000\257\137\067\341\325\372\020\013 +\230\234\206\347\046\217\316\360\354\156\212\127\013\200\343\116 +\262\300\240\143\141\220\272\125\150\067\164\152\266\222\333\237 +\241\206\042\266\145\047\016\354\266\237\102\140\344\147\302\265 +\332\101\013\304\323\213\141\033\274\372\037\221\053\327\104\007 +\136\272\051\254\331\305\351\357\123\110\132\353\200\361\050\130 +\041\315\260\006\125\373\047\077\123\220\160\251\004\036\127\047 +\271 +END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE + +# Trust for "SSL.com Root Certification Authority RSA" +# Issuer: CN=SSL.com Root Certification Authority RSA,O=SSL Corporation,L=Houston,ST=Texas,C=US +# Serial Number:7b:2c:9b:d3:16:80:32:99 +# Subject: CN=SSL.com Root Certification Authority RSA,O=SSL Corporation,L=Houston,ST=Texas,C=US +# Not Valid Before: Fri Feb 12 17:39:39 2016 +# Not Valid After : Tue Feb 12 17:39:39 2041 +# Fingerprint (SHA-256): 85:66:6A:56:2E:E0:BE:5C:E9:25:C1:D8:89:0A:6F:76:A8:7E:C1:6D:4D:7D:5F:29:EA:74:19:CF:20:12:3B:69 +# Fingerprint (SHA1): B7:AB:33:08:D1:EA:44:77:BA:14:80:12:5A:6F:BD:A9:36:49:0C:BB +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 "SSL.com Root Certification Authority RSA" +CKA_CERT_SHA1_HASH MULTILINE_OCTAL +\267\253\063\010\321\352\104\167\272\024\200\022\132\157\275\251 +\066\111\014\273 +END +CKA_CERT_MD5_HASH MULTILINE_OCTAL +\206\151\022\300\160\361\354\254\254\302\325\274\245\133\241\051 +END +CKA_ISSUER MULTILINE_OCTAL +\060\174\061\013\060\011\006\003\125\004\006\023\002\125\123\061 +\016\060\014\006\003\125\004\010\014\005\124\145\170\141\163\061 +\020\060\016\006\003\125\004\007\014\007\110\157\165\163\164\157 +\156\061\030\060\026\006\003\125\004\012\014\017\123\123\114\040 +\103\157\162\160\157\162\141\164\151\157\156\061\061\060\057\006 +\003\125\004\003\014\050\123\123\114\056\143\157\155\040\122\157 +\157\164\040\103\145\162\164\151\146\151\143\141\164\151\157\156 +\040\101\165\164\150\157\162\151\164\171\040\122\123\101 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\010\173\054\233\323\026\200\062\231 +END +CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR +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 "SSL.com Root Certification Authority ECC" +# +# Issuer: CN=SSL.com Root Certification Authority ECC,O=SSL Corporation,L=Houston,ST=Texas,C=US +# Serial Number:75:e6:df:cb:c1:68:5b:a8 +# Subject: CN=SSL.com Root Certification Authority ECC,O=SSL Corporation,L=Houston,ST=Texas,C=US +# Not Valid Before: Fri Feb 12 18:14:03 2016 +# Not Valid After : Tue Feb 12 18:14:03 2041 +# Fingerprint (SHA-256): 34:17:BB:06:CC:60:07:DA:1B:96:1C:92:0B:8A:B4:CE:3F:AD:82:0E:4A:A3:0B:9A:CB:C4:A7:4E:BD:CE:BC:65 +# Fingerprint (SHA1): C3:19:7C:39:24:E6:54:AF:1B:C4:AB:20:95:7A:E2:C3:0E:13:02:6A +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 "SSL.com Root Certification Authority ECC" +CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 +CKA_SUBJECT MULTILINE_OCTAL +\060\174\061\013\060\011\006\003\125\004\006\023\002\125\123\061 +\016\060\014\006\003\125\004\010\014\005\124\145\170\141\163\061 +\020\060\016\006\003\125\004\007\014\007\110\157\165\163\164\157 +\156\061\030\060\026\006\003\125\004\012\014\017\123\123\114\040 +\103\157\162\160\157\162\141\164\151\157\156\061\061\060\057\006 +\003\125\004\003\014\050\123\123\114\056\143\157\155\040\122\157 +\157\164\040\103\145\162\164\151\146\151\143\141\164\151\157\156 +\040\101\165\164\150\157\162\151\164\171\040\105\103\103 +END +CKA_ID UTF8 "0" +CKA_ISSUER MULTILINE_OCTAL +\060\174\061\013\060\011\006\003\125\004\006\023\002\125\123\061 +\016\060\014\006\003\125\004\010\014\005\124\145\170\141\163\061 +\020\060\016\006\003\125\004\007\014\007\110\157\165\163\164\157 +\156\061\030\060\026\006\003\125\004\012\014\017\123\123\114\040 +\103\157\162\160\157\162\141\164\151\157\156\061\061\060\057\006 +\003\125\004\003\014\050\123\123\114\056\143\157\155\040\122\157 +\157\164\040\103\145\162\164\151\146\151\143\141\164\151\157\156 +\040\101\165\164\150\157\162\151\164\171\040\105\103\103 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\010\165\346\337\313\301\150\133\250 +END +CKA_VALUE MULTILINE_OCTAL +\060\202\002\215\060\202\002\024\240\003\002\001\002\002\010\165 +\346\337\313\301\150\133\250\060\012\006\010\052\206\110\316\075 +\004\003\002\060\174\061\013\060\011\006\003\125\004\006\023\002 +\125\123\061\016\060\014\006\003\125\004\010\014\005\124\145\170 +\141\163\061\020\060\016\006\003\125\004\007\014\007\110\157\165 +\163\164\157\156\061\030\060\026\006\003\125\004\012\014\017\123 +\123\114\040\103\157\162\160\157\162\141\164\151\157\156\061\061 +\060\057\006\003\125\004\003\014\050\123\123\114\056\143\157\155 +\040\122\157\157\164\040\103\145\162\164\151\146\151\143\141\164 +\151\157\156\040\101\165\164\150\157\162\151\164\171\040\105\103 +\103\060\036\027\015\061\066\060\062\061\062\061\070\061\064\060 +\063\132\027\015\064\061\060\062\061\062\061\070\061\064\060\063 +\132\060\174\061\013\060\011\006\003\125\004\006\023\002\125\123 +\061\016\060\014\006\003\125\004\010\014\005\124\145\170\141\163 +\061\020\060\016\006\003\125\004\007\014\007\110\157\165\163\164 +\157\156\061\030\060\026\006\003\125\004\012\014\017\123\123\114 +\040\103\157\162\160\157\162\141\164\151\157\156\061\061\060\057 +\006\003\125\004\003\014\050\123\123\114\056\143\157\155\040\122 +\157\157\164\040\103\145\162\164\151\146\151\143\141\164\151\157 +\156\040\101\165\164\150\157\162\151\164\171\040\105\103\103\060 +\166\060\020\006\007\052\206\110\316\075\002\001\006\005\053\201 +\004\000\042\003\142\000\004\105\156\251\120\304\246\043\066\236 +\137\050\215\027\313\226\042\144\077\334\172\216\035\314\010\263 +\242\161\044\272\216\111\271\004\033\107\226\130\253\055\225\310 +\355\236\010\065\310\047\353\211\214\123\130\353\142\212\376\360 +\133\017\153\061\122\143\101\073\211\315\354\354\266\215\031\323 +\064\007\334\273\306\006\177\302\105\225\354\313\177\250\043\340 +\011\351\201\372\363\107\323\243\143\060\141\060\035\006\003\125 +\035\016\004\026\004\024\202\321\205\163\060\347\065\004\323\216 +\002\222\373\345\244\321\304\041\350\315\060\017\006\003\125\035 +\023\001\001\377\004\005\060\003\001\001\377\060\037\006\003\125 +\035\043\004\030\060\026\200\024\202\321\205\163\060\347\065\004 +\323\216\002\222\373\345\244\321\304\041\350\315\060\016\006\003 +\125\035\017\001\001\377\004\004\003\002\001\206\060\012\006\010 +\052\206\110\316\075\004\003\002\003\147\000\060\144\002\060\157 +\347\353\131\021\244\140\317\141\260\226\173\355\005\371\057\023 +\221\334\355\345\374\120\153\021\106\106\263\034\041\000\142\273 +\276\303\347\350\315\007\231\371\015\013\135\162\076\304\252\002 +\060\037\274\272\013\342\060\044\373\174\155\200\125\012\231\076 +\200\015\063\345\146\243\263\243\273\245\325\213\217\011\054\246 +\135\176\342\360\007\010\150\155\322\174\151\156\137\337\345\152 +\145 +END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE + +# Trust for "SSL.com Root Certification Authority ECC" +# Issuer: CN=SSL.com Root Certification Authority ECC,O=SSL Corporation,L=Houston,ST=Texas,C=US +# Serial Number:75:e6:df:cb:c1:68:5b:a8 +# Subject: CN=SSL.com Root Certification Authority ECC,O=SSL Corporation,L=Houston,ST=Texas,C=US +# Not Valid Before: Fri Feb 12 18:14:03 2016 +# Not Valid After : Tue Feb 12 18:14:03 2041 +# Fingerprint (SHA-256): 34:17:BB:06:CC:60:07:DA:1B:96:1C:92:0B:8A:B4:CE:3F:AD:82:0E:4A:A3:0B:9A:CB:C4:A7:4E:BD:CE:BC:65 +# Fingerprint (SHA1): C3:19:7C:39:24:E6:54:AF:1B:C4:AB:20:95:7A:E2:C3:0E:13:02:6A +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 "SSL.com Root Certification Authority ECC" +CKA_CERT_SHA1_HASH MULTILINE_OCTAL +\303\031\174\071\044\346\124\257\033\304\253\040\225\172\342\303 +\016\023\002\152 +END +CKA_CERT_MD5_HASH MULTILINE_OCTAL +\056\332\344\071\177\234\217\067\321\160\237\046\027\121\072\216 +END +CKA_ISSUER MULTILINE_OCTAL +\060\174\061\013\060\011\006\003\125\004\006\023\002\125\123\061 +\016\060\014\006\003\125\004\010\014\005\124\145\170\141\163\061 +\020\060\016\006\003\125\004\007\014\007\110\157\165\163\164\157 +\156\061\030\060\026\006\003\125\004\012\014\017\123\123\114\040 +\103\157\162\160\157\162\141\164\151\157\156\061\061\060\057\006 +\003\125\004\003\014\050\123\123\114\056\143\157\155\040\122\157 +\157\164\040\103\145\162\164\151\146\151\143\141\164\151\157\156 +\040\101\165\164\150\157\162\151\164\171\040\105\103\103 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\010\165\346\337\313\301\150\133\250 +END +CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR +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 "SSL.com EV Root Certification Authority RSA R2" +# +# Issuer: CN=SSL.com EV Root Certification Authority RSA R2,O=SSL Corporation,L=Houston,ST=Texas,C=US +# Serial Number:56:b6:29:cd:34:bc:78:f6 +# Subject: CN=SSL.com EV Root Certification Authority RSA R2,O=SSL Corporation,L=Houston,ST=Texas,C=US +# Not Valid Before: Wed May 31 18:14:37 2017 +# Not Valid After : Fri May 30 18:14:37 2042 +# Fingerprint (SHA-256): 2E:7B:F1:6C:C2:24:85:A7:BB:E2:AA:86:96:75:07:61:B0:AE:39:BE:3B:2F:E9:D0:CC:6D:4E:F7:34:91:42:5C +# Fingerprint (SHA1): 74:3A:F0:52:9B:D0:32:A0:F4:4A:83:CD:D4:BA:A9:7B:7C:2E:C4: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 "SSL.com EV Root Certification Authority RSA R2" +CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 +CKA_SUBJECT MULTILINE_OCTAL +\060\201\202\061\013\060\011\006\003\125\004\006\023\002\125\123 +\061\016\060\014\006\003\125\004\010\014\005\124\145\170\141\163 +\061\020\060\016\006\003\125\004\007\014\007\110\157\165\163\164 +\157\156\061\030\060\026\006\003\125\004\012\014\017\123\123\114 +\040\103\157\162\160\157\162\141\164\151\157\156\061\067\060\065 +\006\003\125\004\003\014\056\123\123\114\056\143\157\155\040\105 +\126\040\122\157\157\164\040\103\145\162\164\151\146\151\143\141 +\164\151\157\156\040\101\165\164\150\157\162\151\164\171\040\122 +\123\101\040\122\062 +END +CKA_ID UTF8 "0" +CKA_ISSUER MULTILINE_OCTAL +\060\201\202\061\013\060\011\006\003\125\004\006\023\002\125\123 +\061\016\060\014\006\003\125\004\010\014\005\124\145\170\141\163 +\061\020\060\016\006\003\125\004\007\014\007\110\157\165\163\164 +\157\156\061\030\060\026\006\003\125\004\012\014\017\123\123\114 +\040\103\157\162\160\157\162\141\164\151\157\156\061\067\060\065 +\006\003\125\004\003\014\056\123\123\114\056\143\157\155\040\105 +\126\040\122\157\157\164\040\103\145\162\164\151\146\151\143\141 +\164\151\157\156\040\101\165\164\150\157\162\151\164\171\040\122 +\123\101\040\122\062 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\010\126\266\051\315\064\274\170\366 +END +CKA_VALUE MULTILINE_OCTAL +\060\202\005\353\060\202\003\323\240\003\002\001\002\002\010\126 +\266\051\315\064\274\170\366\060\015\006\011\052\206\110\206\367 +\015\001\001\013\005\000\060\201\202\061\013\060\011\006\003\125 +\004\006\023\002\125\123\061\016\060\014\006\003\125\004\010\014 +\005\124\145\170\141\163\061\020\060\016\006\003\125\004\007\014 +\007\110\157\165\163\164\157\156\061\030\060\026\006\003\125\004 +\012\014\017\123\123\114\040\103\157\162\160\157\162\141\164\151 +\157\156\061\067\060\065\006\003\125\004\003\014\056\123\123\114 +\056\143\157\155\040\105\126\040\122\157\157\164\040\103\145\162 +\164\151\146\151\143\141\164\151\157\156\040\101\165\164\150\157 +\162\151\164\171\040\122\123\101\040\122\062\060\036\027\015\061 +\067\060\065\063\061\061\070\061\064\063\067\132\027\015\064\062 +\060\065\063\060\061\070\061\064\063\067\132\060\201\202\061\013 +\060\011\006\003\125\004\006\023\002\125\123\061\016\060\014\006 +\003\125\004\010\014\005\124\145\170\141\163\061\020\060\016\006 +\003\125\004\007\014\007\110\157\165\163\164\157\156\061\030\060 +\026\006\003\125\004\012\014\017\123\123\114\040\103\157\162\160 +\157\162\141\164\151\157\156\061\067\060\065\006\003\125\004\003 +\014\056\123\123\114\056\143\157\155\040\105\126\040\122\157\157 +\164\040\103\145\162\164\151\146\151\143\141\164\151\157\156\040 +\101\165\164\150\157\162\151\164\171\040\122\123\101\040\122\062 +\060\202\002\042\060\015\006\011\052\206\110\206\367\015\001\001 +\001\005\000\003\202\002\017\000\060\202\002\012\002\202\002\001 +\000\217\066\145\100\341\326\115\300\327\264\351\106\332\153\352 +\063\107\315\114\371\175\175\276\275\055\075\360\333\170\341\206 +\245\331\272\011\127\150\355\127\076\240\320\010\101\203\347\050 +\101\044\037\343\162\025\320\001\032\373\136\160\043\262\313\237 +\071\343\317\305\116\306\222\155\046\306\173\273\263\332\047\235 +\012\206\351\201\067\005\376\360\161\161\354\303\034\351\143\242 +\027\024\235\357\033\147\323\205\125\002\002\326\111\311\314\132 +\341\261\367\157\062\237\311\324\073\210\101\250\234\275\313\253 +\333\155\173\011\037\242\114\162\220\332\053\010\374\317\074\124 +\316\147\017\250\317\135\226\031\013\304\343\162\353\255\321\175 +\035\047\357\222\353\020\277\133\353\073\257\317\200\335\301\322 +\226\004\133\172\176\244\251\074\070\166\244\142\216\240\071\136 +\352\167\317\135\000\131\217\146\054\076\007\242\243\005\046\021 +\151\227\352\205\267\017\226\013\113\310\100\341\120\272\056\212 +\313\367\017\232\042\347\177\232\067\023\315\362\115\023\153\041 +\321\300\314\042\362\241\106\366\104\151\234\312\141\065\007\000 +\157\326\141\010\021\352\272\270\366\351\263\140\345\115\271\354 +\237\024\146\311\127\130\333\315\207\151\370\212\206\022\003\107 +\277\146\023\166\254\167\175\064\044\205\203\315\327\252\234\220 +\032\237\041\054\177\170\267\144\270\330\350\246\364\170\263\125 +\313\204\322\062\304\170\256\243\217\141\335\316\010\123\255\354 +\210\374\025\344\232\015\346\237\032\167\316\114\217\270\024\025 +\075\142\234\206\070\006\000\146\022\344\131\166\132\123\300\002 +\230\242\020\053\150\104\173\216\171\316\063\112\166\252\133\201 +\026\033\265\212\330\320\000\173\136\142\264\011\326\206\143\016 +\246\005\225\111\272\050\213\210\223\262\064\034\330\244\125\156 +\267\034\320\336\231\125\073\043\364\042\340\371\051\146\046\354 +\040\120\167\333\112\013\217\276\345\002\140\160\101\136\324\256 +\120\071\042\024\046\313\262\073\163\164\125\107\007\171\201\071 +\250\060\023\104\345\004\212\256\226\023\045\102\017\271\123\304 +\233\374\315\344\034\336\074\372\253\326\006\112\037\147\246\230 +\060\034\335\054\333\334\030\225\127\146\306\377\134\213\126\365 +\167\002\003\001\000\001\243\143\060\141\060\017\006\003\125\035 +\023\001\001\377\004\005\060\003\001\001\377\060\037\006\003\125 +\035\043\004\030\060\026\200\024\371\140\273\324\343\325\064\366 +\270\365\006\200\045\247\163\333\106\151\250\236\060\035\006\003 +\125\035\016\004\026\004\024\371\140\273\324\343\325\064\366\270 +\365\006\200\045\247\163\333\106\151\250\236\060\016\006\003\125 +\035\017\001\001\377\004\004\003\002\001\206\060\015\006\011\052 +\206\110\206\367\015\001\001\013\005\000\003\202\002\001\000\126 +\263\216\313\012\235\111\216\277\244\304\221\273\146\027\005\121 +\230\165\373\345\120\054\172\236\361\024\372\253\323\212\076\377 +\221\051\217\143\213\330\264\251\124\001\015\276\223\206\057\371 +\112\155\307\136\365\127\371\312\125\034\022\276\107\017\066\305 +\337\152\267\333\165\302\107\045\177\271\361\143\370\150\055\125 +\004\321\362\215\260\244\317\274\074\136\037\170\347\245\240\040 +\160\260\004\305\267\367\162\247\336\042\015\275\063\045\106\214 +\144\222\046\343\076\056\143\226\332\233\214\075\370\030\011\327 +\003\314\175\206\202\340\312\004\007\121\120\327\377\222\325\014 +\357\332\206\237\231\327\353\267\257\150\342\071\046\224\272\150 +\267\277\203\323\352\172\147\075\142\147\256\045\345\162\350\342 +\344\354\256\022\366\113\053\074\237\351\260\100\363\070\124\263 +\375\267\150\310\332\306\217\121\074\262\373\221\334\034\347\233 +\235\341\267\015\162\217\342\244\304\251\170\371\353\024\254\306 +\103\005\302\145\071\050\030\002\303\202\262\235\005\276\145\355 +\226\137\145\164\074\373\011\065\056\173\234\023\375\033\017\135 +\307\155\201\072\126\017\314\073\341\257\002\057\042\254\106\312 +\106\074\240\034\114\326\104\264\136\056\134\025\146\011\341\046 +\051\376\306\122\141\272\261\163\377\303\014\234\345\154\152\224 +\077\024\312\100\026\225\204\363\131\251\254\137\114\141\223\155 +\321\073\314\242\225\014\042\246\147\147\104\056\271\331\322\212 +\101\263\146\013\132\373\175\043\245\362\032\260\377\336\233\203 +\224\056\321\077\337\222\267\221\257\005\073\145\307\240\154\261 +\315\142\022\303\220\033\343\045\316\064\274\157\167\166\261\020 +\303\367\005\032\300\326\257\164\142\110\027\167\222\151\220\141 +\034\336\225\200\164\124\217\030\034\303\363\003\320\277\244\103 +\165\206\123\030\172\012\056\011\034\066\237\221\375\202\212\042 +\113\321\016\120\045\335\313\003\014\027\311\203\000\010\116\065 +\115\212\213\355\360\002\224\146\054\104\177\313\225\047\226\027 +\255\011\060\254\266\161\027\156\213\027\366\034\011\324\055\073 +\230\245\161\323\124\023\331\140\363\365\113\146\117\372\361\356 +\040\022\215\264\254\127\261\105\143\241\254\166\251\302\373 +END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE + +# Trust for "SSL.com EV Root Certification Authority RSA R2" +# Issuer: CN=SSL.com EV Root Certification Authority RSA R2,O=SSL Corporation,L=Houston,ST=Texas,C=US +# Serial Number:56:b6:29:cd:34:bc:78:f6 +# Subject: CN=SSL.com EV Root Certification Authority RSA R2,O=SSL Corporation,L=Houston,ST=Texas,C=US +# Not Valid Before: Wed May 31 18:14:37 2017 +# Not Valid After : Fri May 30 18:14:37 2042 +# Fingerprint (SHA-256): 2E:7B:F1:6C:C2:24:85:A7:BB:E2:AA:86:96:75:07:61:B0:AE:39:BE:3B:2F:E9:D0:CC:6D:4E:F7:34:91:42:5C +# Fingerprint (SHA1): 74:3A:F0:52:9B:D0:32:A0:F4:4A:83:CD:D4:BA:A9:7B:7C:2E:C4: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 "SSL.com EV Root Certification Authority RSA R2" +CKA_CERT_SHA1_HASH MULTILINE_OCTAL +\164\072\360\122\233\320\062\240\364\112\203\315\324\272\251\173 +\174\056\304\232 +END +CKA_CERT_MD5_HASH MULTILINE_OCTAL +\341\036\061\130\032\256\124\123\002\366\027\152\021\173\115\225 +END +CKA_ISSUER MULTILINE_OCTAL +\060\201\202\061\013\060\011\006\003\125\004\006\023\002\125\123 +\061\016\060\014\006\003\125\004\010\014\005\124\145\170\141\163 +\061\020\060\016\006\003\125\004\007\014\007\110\157\165\163\164 +\157\156\061\030\060\026\006\003\125\004\012\014\017\123\123\114 +\040\103\157\162\160\157\162\141\164\151\157\156\061\067\060\065 +\006\003\125\004\003\014\056\123\123\114\056\143\157\155\040\105 +\126\040\122\157\157\164\040\103\145\162\164\151\146\151\143\141 +\164\151\157\156\040\101\165\164\150\157\162\151\164\171\040\122 +\123\101\040\122\062 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\010\126\266\051\315\064\274\170\366 +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 "SSL.com EV Root Certification Authority ECC" +# +# Issuer: CN=SSL.com EV Root Certification Authority ECC,O=SSL Corporation,L=Houston,ST=Texas,C=US +# Serial Number:2c:29:9c:5b:16:ed:05:95 +# Subject: CN=SSL.com EV Root Certification Authority ECC,O=SSL Corporation,L=Houston,ST=Texas,C=US +# Not Valid Before: Fri Feb 12 18:15:23 2016 +# Not Valid After : Tue Feb 12 18:15:23 2041 +# Fingerprint (SHA-256): 22:A2:C1:F7:BD:ED:70:4C:C1:E7:01:B5:F4:08:C3:10:88:0F:E9:56:B5:DE:2A:4A:44:F9:9C:87:3A:25:A7:C8 +# Fingerprint (SHA1): 4C:DD:51:A3:D1:F5:20:32:14:B0:C6:C5:32:23:03:91:C7:46:42:6D +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 "SSL.com EV Root Certification Authority ECC" +CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 +CKA_SUBJECT MULTILINE_OCTAL +\060\177\061\013\060\011\006\003\125\004\006\023\002\125\123\061 +\016\060\014\006\003\125\004\010\014\005\124\145\170\141\163\061 +\020\060\016\006\003\125\004\007\014\007\110\157\165\163\164\157 +\156\061\030\060\026\006\003\125\004\012\014\017\123\123\114\040 +\103\157\162\160\157\162\141\164\151\157\156\061\064\060\062\006 +\003\125\004\003\014\053\123\123\114\056\143\157\155\040\105\126 +\040\122\157\157\164\040\103\145\162\164\151\146\151\143\141\164 +\151\157\156\040\101\165\164\150\157\162\151\164\171\040\105\103 +\103 +END +CKA_ID UTF8 "0" +CKA_ISSUER MULTILINE_OCTAL +\060\177\061\013\060\011\006\003\125\004\006\023\002\125\123\061 +\016\060\014\006\003\125\004\010\014\005\124\145\170\141\163\061 +\020\060\016\006\003\125\004\007\014\007\110\157\165\163\164\157 +\156\061\030\060\026\006\003\125\004\012\014\017\123\123\114\040 +\103\157\162\160\157\162\141\164\151\157\156\061\064\060\062\006 +\003\125\004\003\014\053\123\123\114\056\143\157\155\040\105\126 +\040\122\157\157\164\040\103\145\162\164\151\146\151\143\141\164 +\151\157\156\040\101\165\164\150\157\162\151\164\171\040\105\103 +\103 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\010\054\051\234\133\026\355\005\225 +END +CKA_VALUE MULTILINE_OCTAL +\060\202\002\224\060\202\002\032\240\003\002\001\002\002\010\054 +\051\234\133\026\355\005\225\060\012\006\010\052\206\110\316\075 +\004\003\002\060\177\061\013\060\011\006\003\125\004\006\023\002 +\125\123\061\016\060\014\006\003\125\004\010\014\005\124\145\170 +\141\163\061\020\060\016\006\003\125\004\007\014\007\110\157\165 +\163\164\157\156\061\030\060\026\006\003\125\004\012\014\017\123 +\123\114\040\103\157\162\160\157\162\141\164\151\157\156\061\064 +\060\062\006\003\125\004\003\014\053\123\123\114\056\143\157\155 +\040\105\126\040\122\157\157\164\040\103\145\162\164\151\146\151 +\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171 +\040\105\103\103\060\036\027\015\061\066\060\062\061\062\061\070 +\061\065\062\063\132\027\015\064\061\060\062\061\062\061\070\061 +\065\062\063\132\060\177\061\013\060\011\006\003\125\004\006\023 +\002\125\123\061\016\060\014\006\003\125\004\010\014\005\124\145 +\170\141\163\061\020\060\016\006\003\125\004\007\014\007\110\157 +\165\163\164\157\156\061\030\060\026\006\003\125\004\012\014\017 +\123\123\114\040\103\157\162\160\157\162\141\164\151\157\156\061 +\064\060\062\006\003\125\004\003\014\053\123\123\114\056\143\157 +\155\040\105\126\040\122\157\157\164\040\103\145\162\164\151\146 +\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164 +\171\040\105\103\103\060\166\060\020\006\007\052\206\110\316\075 +\002\001\006\005\053\201\004\000\042\003\142\000\004\252\022\107 +\220\230\033\373\357\303\100\007\203\040\116\361\060\202\242\006 +\321\362\222\206\141\362\366\041\150\312\000\304\307\352\103\000 +\124\206\334\375\037\337\000\270\101\142\134\334\160\026\062\336 +\037\231\324\314\305\007\310\010\037\141\026\007\121\075\175\134 +\007\123\343\065\070\214\337\315\237\331\056\015\112\266\031\056 +\132\160\132\006\355\276\360\241\260\312\320\011\051\243\143\060 +\141\060\035\006\003\125\035\016\004\026\004\024\133\312\136\345 +\336\322\201\252\315\250\055\144\121\266\331\162\233\227\346\117 +\060\017\006\003\125\035\023\001\001\377\004\005\060\003\001\001 +\377\060\037\006\003\125\035\043\004\030\060\026\200\024\133\312 +\136\345\336\322\201\252\315\250\055\144\121\266\331\162\233\227 +\346\117\060\016\006\003\125\035\017\001\001\377\004\004\003\002 +\001\206\060\012\006\010\052\206\110\316\075\004\003\002\003\150 +\000\060\145\002\061\000\212\346\100\211\067\353\351\325\023\331 +\312\324\153\044\363\260\075\207\106\130\032\354\261\337\157\373 +\126\272\160\153\307\070\314\350\261\214\117\017\367\361\147\166 +\016\203\320\036\121\217\002\060\075\366\043\050\046\114\306\140 +\207\223\046\233\262\065\036\272\326\367\074\321\034\316\372\045 +\074\246\032\201\025\133\363\022\017\154\356\145\212\311\207\250 +\371\007\340\142\232\214\134\112 +END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE + +# Trust for "SSL.com EV Root Certification Authority ECC" +# Issuer: CN=SSL.com EV Root Certification Authority ECC,O=SSL Corporation,L=Houston,ST=Texas,C=US +# Serial Number:2c:29:9c:5b:16:ed:05:95 +# Subject: CN=SSL.com EV Root Certification Authority ECC,O=SSL Corporation,L=Houston,ST=Texas,C=US +# Not Valid Before: Fri Feb 12 18:15:23 2016 +# Not Valid After : Tue Feb 12 18:15:23 2041 +# Fingerprint (SHA-256): 22:A2:C1:F7:BD:ED:70:4C:C1:E7:01:B5:F4:08:C3:10:88:0F:E9:56:B5:DE:2A:4A:44:F9:9C:87:3A:25:A7:C8 +# Fingerprint (SHA1): 4C:DD:51:A3:D1:F5:20:32:14:B0:C6:C5:32:23:03:91:C7:46:42:6D +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 "SSL.com EV Root Certification Authority ECC" +CKA_CERT_SHA1_HASH MULTILINE_OCTAL +\114\335\121\243\321\365\040\062\024\260\306\305\062\043\003\221 +\307\106\102\155 +END +CKA_CERT_MD5_HASH MULTILINE_OCTAL +\131\123\042\145\203\102\001\124\300\316\102\271\132\174\362\220 +END +CKA_ISSUER MULTILINE_OCTAL +\060\177\061\013\060\011\006\003\125\004\006\023\002\125\123\061 +\016\060\014\006\003\125\004\010\014\005\124\145\170\141\163\061 +\020\060\016\006\003\125\004\007\014\007\110\157\165\163\164\157 +\156\061\030\060\026\006\003\125\004\012\014\017\123\123\114\040 +\103\157\162\160\157\162\141\164\151\157\156\061\064\060\062\006 +\003\125\004\003\014\053\123\123\114\056\143\157\155\040\105\126 +\040\122\157\157\164\040\103\145\162\164\151\146\151\143\141\164 +\151\157\156\040\101\165\164\150\157\162\151\164\171\040\105\103 +\103 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\010\054\051\234\133\026\355\005\225 +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 diff --git a/security/nss/lib/ckfw/builtins/nssckbi.h b/security/nss/lib/ckfw/builtins/nssckbi.h index 498751d13..0189369b1 100644 --- a/security/nss/lib/ckfw/builtins/nssckbi.h +++ b/security/nss/lib/ckfw/builtins/nssckbi.h @@ -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 16 -#define NSS_BUILTINS_LIBRARY_VERSION "2.16" +#define NSS_BUILTINS_LIBRARY_VERSION_MINOR 22 +#define NSS_BUILTINS_LIBRARY_VERSION "2.22" /* 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/capi/cfind.c b/security/nss/lib/ckfw/capi/cfind.c index 9ea7fca61..9c4d4f1e7 100644 --- a/security/nss/lib/ckfw/capi/cfind.c +++ b/security/nss/lib/ckfw/capi/cfind.c @@ -331,8 +331,7 @@ collect_class( nss_ZFreeIf(keyProvInfo); if (provName && - (strncmp(provName, "Microsoft", sizeof("Microsoft") - - 1) != 0)) { + (strncmp(provName, "Microsoft", sizeof("Microsoft") - 1) != 0)) { continue; } } else { diff --git a/security/nss/lib/cryptohi/cryptohi.h b/security/nss/lib/cryptohi/cryptohi.h index f658daa9e..e529fa34f 100644 --- a/security/nss/lib/cryptohi/cryptohi.h +++ b/security/nss/lib/cryptohi/cryptohi.h @@ -60,6 +60,14 @@ extern SECItem *DSAU_DecodeDerSigToLen(const SECItem *item, unsigned int len); extern SGNContext *SGN_NewContext(SECOidTag alg, SECKEYPrivateKey *privKey); /* +** Create a new signature context from an algorithmID. +** "alg" the signature algorithm to use +** "privKey" the private key to use +*/ +extern SGNContext *SGN_NewContextWithAlgorithmID(SECAlgorithmID *alg, + SECKEYPrivateKey *privKey); + +/* ** Destroy a signature-context object ** "cx" the object ** "freeit" if PR_TRUE then free the object as well as its sub-objects @@ -106,6 +114,21 @@ extern SECStatus SEC_SignData(SECItem *result, SECKEYPrivateKey *pk, SECOidTag algid); /* +** Sign a single block of data using private key encryption and given +** signature/hash algorithm with parameters from an algorithmID. +** "result" the final signature data (memory is allocated) +** "buf" the input data to sign +** "len" the amount of data to sign +** "pk" the private key to encrypt with +** "algid" the signature/hash algorithm to sign with +** (must be compatible with the key type). +*/ +extern SECStatus SEC_SignDataWithAlgorithmID(SECItem *result, + const unsigned char *buf, int len, + SECKEYPrivateKey *pk, + SECAlgorithmID *algid); + +/* ** Sign a pre-digested block of data using private key encryption, encoding ** The given signature/hash algorithm. ** "result" the final signature data (memory is allocated) @@ -132,6 +155,27 @@ extern SECStatus SEC_DerSignData(PLArenaPool *arena, SECItem *result, SECKEYPrivateKey *pk, SECOidTag algid); /* +** DER sign a single block of data using private key encryption and +** the given signature/hash algorithm with parameters from an +** algorithmID. This routine first computes a digital signature using +** SEC_SignData, then wraps it with an CERTSignedData and then der +** encodes the result. +** "arena" is the memory arena to use to allocate data from +** "result" the final der encoded data (memory is allocated) +** "buf" the input data to sign +** "len" the amount of data to sign +** "pk" the private key to encrypt with +** "algid" the signature/hash algorithm to sign with +** (must be compatible with the key type). +*/ +extern SECStatus SEC_DerSignDataWithAlgorithmID(PLArenaPool *arena, + SECItem *result, + const unsigned char *buf, + int len, + SECKEYPrivateKey *pk, + SECAlgorithmID *algid); + +/* ** Destroy a signed-data object. ** "sd" the object ** "freeit" if PR_TRUE then free the object as well as its sub-objects @@ -146,6 +190,23 @@ extern void SEC_DestroySignedData(CERTSignedData *sd, PRBool freeit); extern SECOidTag SEC_GetSignatureAlgorithmOidTag(KeyType keyType, SECOidTag hashAlgTag); +/* +** Create algorithm parameters for signing. Return a new item +** allocated from arena, or NULL on failure. +** "arena" is the memory arena to use to allocate data from +** "result" the encoded parameters (memory is allocated) +** "signAlgTag" is the signing algorithm +** "hashAlgTag" is the preferred hash algorithm +** "params" is the default parameters +** "key" is the private key +*/ +extern SECItem *SEC_CreateSignatureAlgorithmParameters(PLArenaPool *arena, + SECItem *result, + SECOidTag signAlgTag, + SECOidTag hashAlgTag, + const SECItem *params, + const SECKEYPrivateKey *key); + /****************************************/ /* ** Signature verification operations diff --git a/security/nss/lib/cryptohi/keyi.h b/security/nss/lib/cryptohi/keyi.h index f8f5f7f7d..ee11fc905 100644 --- a/security/nss/lib/cryptohi/keyi.h +++ b/security/nss/lib/cryptohi/keyi.h @@ -17,6 +17,9 @@ KeyType seckey_GetKeyType(SECOidTag pubKeyOid); SECStatus sec_DecodeSigAlg(const SECKEYPublicKey *key, SECOidTag sigAlg, const SECItem *param, SECOidTag *encalg, SECOidTag *hashalg); +SECStatus sec_RSAPSSParamsToMechanism(CK_RSA_PKCS_PSS_PARAMS *mech, + const SECKEYRSAPSSParams *params); + SEC_END_PROTOS #endif /* _KEYHI_H_ */ diff --git a/security/nss/lib/cryptohi/seckey.c b/security/nss/lib/cryptohi/seckey.c index 9ea48b767..0f9353f3b 100644 --- a/security/nss/lib/cryptohi/seckey.c +++ b/security/nss/lib/cryptohi/seckey.c @@ -221,8 +221,7 @@ SECKEY_CreateECPrivateKey(SECKEYECParams *param, SECKEYPublicKey **pubk, void *c PK11_ATTR_SESSION | PK11_ATTR_INSENSITIVE | PK11_ATTR_PUBLIC, - CKF_DERIVE, CKF_DERIVE | - CKF_SIGN, + CKF_DERIVE, CKF_DERIVE | CKF_SIGN, cx); if (!privk) privk = PK11_GenerateKeyPairWithOpFlags(slot, CKM_EC_KEY_PAIR_GEN, @@ -230,8 +229,7 @@ SECKEY_CreateECPrivateKey(SECKEYECParams *param, SECKEYPublicKey **pubk, void *c PK11_ATTR_SESSION | PK11_ATTR_SENSITIVE | PK11_ATTR_PRIVATE, - CKF_DERIVE, CKF_DERIVE | - CKF_SIGN, + CKF_DERIVE, CKF_DERIVE | CKF_SIGN, cx); PK11_FreeSlot(slot); @@ -1048,6 +1046,7 @@ SECKEY_SignatureLen(const SECKEYPublicKey *pubk) switch (pubk->keyType) { case rsaKey: + case rsaPssKey: b0 = pubk->u.rsa.modulus.data[0]; return b0 ? pubk->u.rsa.modulus.len : pubk->u.rsa.modulus.len - 1; case dsaKey: @@ -1974,3 +1973,118 @@ SECKEY_GetECCOid(const SECKEYECParams *params) return oidData->offset; } + +static CK_MECHANISM_TYPE +sec_GetHashMechanismByOidTag(SECOidTag tag) +{ + switch (tag) { + case SEC_OID_SHA512: + return CKM_SHA512; + case SEC_OID_SHA384: + return CKM_SHA384; + case SEC_OID_SHA256: + return CKM_SHA256; + case SEC_OID_SHA224: + return CKM_SHA224; + case SEC_OID_SHA1: + return CKM_SHA_1; + default: + PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); + return CKM_INVALID_MECHANISM; + } +} + +static CK_RSA_PKCS_MGF_TYPE +sec_GetMgfTypeByOidTag(SECOidTag tag) +{ + switch (tag) { + case SEC_OID_SHA512: + return CKG_MGF1_SHA512; + case SEC_OID_SHA384: + return CKG_MGF1_SHA384; + case SEC_OID_SHA256: + return CKG_MGF1_SHA256; + case SEC_OID_SHA224: + return CKG_MGF1_SHA224; + case SEC_OID_SHA1: + return CKG_MGF1_SHA1; + default: + PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); + return 0; + } +} + +SECStatus +sec_RSAPSSParamsToMechanism(CK_RSA_PKCS_PSS_PARAMS *mech, + const SECKEYRSAPSSParams *params) +{ + SECStatus rv = SECSuccess; + SECOidTag hashAlgTag; + unsigned long saltLength; + unsigned long trailerField; + + PORT_Memset(mech, 0, sizeof(CK_RSA_PKCS_PSS_PARAMS)); + + if (params->hashAlg) { + hashAlgTag = SECOID_GetAlgorithmTag(params->hashAlg); + } else { + hashAlgTag = SEC_OID_SHA1; /* default, SHA-1 */ + } + mech->hashAlg = sec_GetHashMechanismByOidTag(hashAlgTag); + if (mech->hashAlg == CKM_INVALID_MECHANISM) { + return SECFailure; + } + + if (params->maskAlg) { + SECAlgorithmID maskHashAlg; + SECOidTag maskHashAlgTag; + PORTCheapArenaPool tmpArena; + + if (SECOID_GetAlgorithmTag(params->maskAlg) != SEC_OID_PKCS1_MGF1) { + /* only MGF1 is known to PKCS#11 */ + PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); + return SECFailure; + } + + PORT_InitCheapArena(&tmpArena, DER_DEFAULT_CHUNKSIZE); + rv = SEC_QuickDERDecodeItem(&tmpArena.arena, &maskHashAlg, + SEC_ASN1_GET(SECOID_AlgorithmIDTemplate), + ¶ms->maskAlg->parameters); + PORT_DestroyCheapArena(&tmpArena); + if (rv != SECSuccess) { + return rv; + } + maskHashAlgTag = SECOID_GetAlgorithmTag(&maskHashAlg); + mech->mgf = sec_GetMgfTypeByOidTag(maskHashAlgTag); + if (mech->mgf == 0) { + return SECFailure; + } + } else { + mech->mgf = CKG_MGF1_SHA1; /* default, MGF1 with SHA-1 */ + } + + if (params->saltLength.data) { + rv = SEC_ASN1DecodeInteger((SECItem *)¶ms->saltLength, &saltLength); + if (rv != SECSuccess) { + return rv; + } + } else { + saltLength = 20; /* default, 20 */ + } + mech->sLen = saltLength; + + if (params->trailerField.data) { + rv = SEC_ASN1DecodeInteger((SECItem *)¶ms->trailerField, &trailerField); + if (rv != SECSuccess) { + return rv; + } + if (trailerField != 1) { + /* the value must be 1, which represents the trailer field + * with hexadecimal value 0xBC */ + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + } + + return rv; +} diff --git a/security/nss/lib/cryptohi/secsign.c b/security/nss/lib/cryptohi/secsign.c index d06cb2e85..dc10f2fa6 100644 --- a/security/nss/lib/cryptohi/secsign.c +++ b/security/nss/lib/cryptohi/secsign.c @@ -22,10 +22,11 @@ struct SGNContextStr { void *hashcx; const SECHashObject *hashobj; SECKEYPrivateKey *key; + SECItem *params; }; -SGNContext * -SGN_NewContext(SECOidTag alg, SECKEYPrivateKey *key) +static SGNContext * +sgn_NewContext(SECOidTag alg, SECItem *params, SECKEYPrivateKey *key) { SGNContext *cx; SECOidTag hashalg, signalg; @@ -40,7 +41,7 @@ SGN_NewContext(SECOidTag alg, SECKEYPrivateKey *key) * it may just support CKM_SHA1_RSA_PKCS and/or CKM_MD5_RSA_PKCS. */ /* we have a private key, not a public key, so don't pass it in */ - rv = sec_DecodeSigAlg(NULL, alg, NULL, &signalg, &hashalg); + rv = sec_DecodeSigAlg(NULL, alg, params, &signalg, &hashalg); if (rv != SECSuccess) { PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); return 0; @@ -49,7 +50,8 @@ SGN_NewContext(SECOidTag alg, SECKEYPrivateKey *key) /* verify our key type */ if (key->keyType != keyType && - !((key->keyType == dsaKey) && (keyType == fortezzaKey))) { + !((key->keyType == dsaKey) && (keyType == fortezzaKey)) && + !((key->keyType == rsaKey) && (keyType == rsaPssKey))) { PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); return 0; } @@ -59,10 +61,24 @@ SGN_NewContext(SECOidTag alg, SECKEYPrivateKey *key) cx->hashalg = hashalg; cx->signalg = signalg; cx->key = key; + cx->params = params; } return cx; } +SGNContext * +SGN_NewContext(SECOidTag alg, SECKEYPrivateKey *key) +{ + return sgn_NewContext(alg, NULL, key); +} + +SGNContext * +SGN_NewContextWithAlgorithmID(SECAlgorithmID *alg, SECKEYPrivateKey *key) +{ + SECOidTag tag = SECOID_GetAlgorithmTag(alg); + return sgn_NewContext(tag, &alg->parameters, key); +} + void SGN_DestroyContext(SGNContext *cx, PRBool freeit) { @@ -148,6 +164,7 @@ SGN_End(SGNContext *cx, SECItem *result) result->data = 0; digder.data = 0; + sigitem.data = 0; /* Finish up digest function */ if (cx->hashcx == NULL) { @@ -156,7 +173,8 @@ SGN_End(SGNContext *cx, SECItem *result) } (*cx->hashobj->end)(cx->hashcx, digest, &part1, sizeof(digest)); - if (privKey->keyType == rsaKey) { + if (privKey->keyType == rsaKey && + cx->signalg != SEC_OID_PKCS1_RSA_PSS_SIGNATURE) { arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if (!arena) { @@ -200,26 +218,65 @@ SGN_End(SGNContext *cx, SECItem *result) goto loser; } - rv = PK11_Sign(privKey, &sigitem, &digder); - if (rv != SECSuccess) { - PORT_Free(sigitem.data); - sigitem.data = NULL; - goto loser; + if (cx->signalg == SEC_OID_PKCS1_RSA_PSS_SIGNATURE) { + CK_RSA_PKCS_PSS_PARAMS mech; + SECItem mechItem = { siBuffer, (unsigned char *)&mech, sizeof(mech) }; + + PORT_Memset(&mech, 0, sizeof(mech)); + + if (cx->params && cx->params->data) { + SECKEYRSAPSSParams params; + + arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); + if (!arena) { + rv = SECFailure; + goto loser; + } + + PORT_Memset(¶ms, 0, sizeof(params)); + rv = SEC_QuickDERDecodeItem(arena, ¶ms, + SECKEY_RSAPSSParamsTemplate, + cx->params); + if (rv != SECSuccess) { + goto loser; + } + rv = sec_RSAPSSParamsToMechanism(&mech, ¶ms); + if (rv != SECSuccess) { + goto loser; + } + } else { + mech.hashAlg = CKM_SHA_1; + mech.mgf = CKG_MGF1_SHA1; + mech.sLen = digder.len; + } + rv = PK11_SignWithMechanism(privKey, CKM_RSA_PKCS_PSS, &mechItem, + &sigitem, &digder); + if (rv != SECSuccess) { + goto loser; + } + } else { + rv = PK11_Sign(privKey, &sigitem, &digder); + if (rv != SECSuccess) { + goto loser; + } } if ((cx->signalg == SEC_OID_ANSIX9_DSA_SIGNATURE) || (cx->signalg == SEC_OID_ANSIX962_EC_PUBLIC_KEY)) { /* DSAU_EncodeDerSigWithLen works for DSA and ECDSA */ rv = DSAU_EncodeDerSigWithLen(result, &sigitem, sigitem.len); - PORT_Free(sigitem.data); if (rv != SECSuccess) goto loser; + SECITEM_FreeItem(&sigitem, PR_FALSE); } else { result->len = sigitem.len; result->data = sigitem.data; } loser: + if (rv != SECSuccess) { + SECITEM_FreeItem(&sigitem, PR_FALSE); + } SGN_DestroyDigestInfo(di); if (arena != NULL) { PORT_FreeArena(arena, PR_FALSE); @@ -229,18 +286,14 @@ loser: /************************************************************************/ -/* -** Sign a block of data returning in result a bunch of bytes that are the -** signature. Returns zero on success, an error code on failure. -*/ -SECStatus -SEC_SignData(SECItem *res, const unsigned char *buf, int len, - SECKEYPrivateKey *pk, SECOidTag algid) +static SECStatus +sec_SignData(SECItem *res, const unsigned char *buf, int len, + SECKEYPrivateKey *pk, SECOidTag algid, SECItem *params) { SECStatus rv; SGNContext *sgn; - sgn = SGN_NewContext(algid, pk); + sgn = sgn_NewContext(algid, params, pk); if (sgn == NULL) return SECFailure; @@ -260,6 +313,25 @@ loser: return rv; } +/* +** Sign a block of data returning in result a bunch of bytes that are the +** signature. Returns zero on success, an error code on failure. +*/ +SECStatus +SEC_SignData(SECItem *res, const unsigned char *buf, int len, + SECKEYPrivateKey *pk, SECOidTag algid) +{ + return sec_SignData(res, buf, len, pk, algid, NULL); +} + +SECStatus +SEC_SignDataWithAlgorithmID(SECItem *res, const unsigned char *buf, int len, + SECKEYPrivateKey *pk, SECAlgorithmID *algid) +{ + SECOidTag tag = SECOID_GetAlgorithmTag(algid); + return sec_SignData(res, buf, len, pk, tag, &algid->parameters); +} + /************************************************************************/ DERTemplate CERTSignedDataTemplate[] = @@ -294,10 +366,10 @@ const SEC_ASN1Template CERT_SignedDataTemplate[] = SEC_ASN1_CHOOSER_IMPLEMENT(CERT_SignedDataTemplate) -SECStatus -SEC_DerSignData(PLArenaPool *arena, SECItem *result, +static SECStatus +sec_DerSignData(PLArenaPool *arena, SECItem *result, const unsigned char *buf, int len, SECKEYPrivateKey *pk, - SECOidTag algID) + SECOidTag algID, SECItem *params) { SECItem it; CERTSignedData sd; @@ -339,7 +411,7 @@ SEC_DerSignData(PLArenaPool *arena, SECItem *result, } /* Sign input buffer */ - rv = SEC_SignData(&it, buf, len, pk, algID); + rv = sec_SignData(&it, buf, len, pk, algID, params); if (rv) goto loser; @@ -349,7 +421,7 @@ SEC_DerSignData(PLArenaPool *arena, SECItem *result, sd.data.len = len; sd.signature.data = it.data; sd.signature.len = it.len << 3; /* convert to bit string */ - rv = SECOID_SetAlgorithmID(arena, &sd.signatureAlgorithm, algID, 0); + rv = SECOID_SetAlgorithmID(arena, &sd.signatureAlgorithm, algID, params); if (rv) goto loser; @@ -363,6 +435,24 @@ loser: } SECStatus +SEC_DerSignData(PLArenaPool *arena, SECItem *result, + const unsigned char *buf, int len, SECKEYPrivateKey *pk, + SECOidTag algID) +{ + return sec_DerSignData(arena, result, buf, len, pk, algID, NULL); +} + +SECStatus +SEC_DerSignDataWithAlgorithmID(PLArenaPool *arena, SECItem *result, + const unsigned char *buf, int len, + SECKEYPrivateKey *pk, + SECAlgorithmID *algID) +{ + SECOidTag tag = SECOID_GetAlgorithmTag(algID); + return sec_DerSignData(arena, result, buf, len, pk, tag, &algID->parameters); +} + +SECStatus SGN_Digest(SECKEYPrivateKey *privKey, SECOidTag algtag, SECItem *result, SECItem *digest) { @@ -509,3 +599,243 @@ SEC_GetSignatureAlgorithmOidTag(KeyType keyType, SECOidTag hashAlgTag) } return sigTag; } + +static SECItem * +sec_CreateRSAPSSParameters(PLArenaPool *arena, + SECItem *result, + SECOidTag hashAlgTag, + const SECItem *params, + const SECKEYPrivateKey *key) +{ + SECKEYRSAPSSParams pssParams; + int modBytes, hashLength; + unsigned long saltLength; + PRBool defaultSHA1 = PR_FALSE; + SECStatus rv; + + if (key->keyType != rsaKey && key->keyType != rsaPssKey) { + PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); + return NULL; + } + + PORT_Memset(&pssParams, 0, sizeof(pssParams)); + + if (params && params->data) { + /* The parameters field should either be empty or contain + * valid RSA-PSS parameters */ + PORT_Assert(!(params->len == 2 && + params->data[0] == SEC_ASN1_NULL && + params->data[1] == 0)); + rv = SEC_QuickDERDecodeItem(arena, &pssParams, + SECKEY_RSAPSSParamsTemplate, + params); + if (rv != SECSuccess) { + return NULL; + } + defaultSHA1 = PR_TRUE; + } + + if (pssParams.trailerField.data) { + unsigned long trailerField; + + rv = SEC_ASN1DecodeInteger((SECItem *)&pssParams.trailerField, + &trailerField); + if (rv != SECSuccess) { + return NULL; + } + if (trailerField != 1) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return NULL; + } + } + + modBytes = PK11_GetPrivateModulusLen((SECKEYPrivateKey *)key); + + /* Determine the hash algorithm to use, based on hashAlgTag and + * pssParams.hashAlg; there are four cases */ + if (hashAlgTag != SEC_OID_UNKNOWN) { + SECOidTag tag = SEC_OID_UNKNOWN; + + if (pssParams.hashAlg) { + tag = SECOID_GetAlgorithmTag(pssParams.hashAlg); + } else if (defaultSHA1) { + tag = SEC_OID_SHA1; + } + + if (tag != SEC_OID_UNKNOWN && tag != hashAlgTag) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return NULL; + } + } else if (hashAlgTag == SEC_OID_UNKNOWN) { + if (pssParams.hashAlg) { + hashAlgTag = SECOID_GetAlgorithmTag(pssParams.hashAlg); + } else if (defaultSHA1) { + hashAlgTag = SEC_OID_SHA1; + } else { + /* Find a suitable hash algorithm based on the NIST recommendation */ + if (modBytes <= 384) { /* 128, in NIST 800-57, Part 1 */ + hashAlgTag = SEC_OID_SHA256; + } else if (modBytes <= 960) { /* 192, NIST 800-57, Part 1 */ + hashAlgTag = SEC_OID_SHA384; + } else { + hashAlgTag = SEC_OID_SHA512; + } + } + } + + if (hashAlgTag != SEC_OID_SHA1 && hashAlgTag != SEC_OID_SHA224 && + hashAlgTag != SEC_OID_SHA256 && hashAlgTag != SEC_OID_SHA384 && + hashAlgTag != SEC_OID_SHA512) { + PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); + return NULL; + } + + /* Now that the hash algorithm is decided, check if it matches the + * existing parameters if any */ + if (pssParams.maskAlg) { + SECAlgorithmID maskHashAlg; + + if (SECOID_GetAlgorithmTag(pssParams.maskAlg) != SEC_OID_PKCS1_MGF1) { + PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); + return NULL; + } + + if (pssParams.maskAlg->parameters.data == NULL) { + PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); + return NULL; + } + + PORT_Memset(&maskHashAlg, 0, sizeof(maskHashAlg)); + rv = SEC_QuickDERDecodeItem(arena, &maskHashAlg, + SEC_ASN1_GET(SECOID_AlgorithmIDTemplate), + &pssParams.maskAlg->parameters); + if (rv != SECSuccess) { + return NULL; + } + + /* Following the recommendation in RFC 4055, assume the hash + * algorithm identical to pssParam.hashAlg */ + if (SECOID_GetAlgorithmTag(&maskHashAlg) != hashAlgTag) { + PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); + return NULL; + } + } else if (defaultSHA1) { + if (hashAlgTag != SEC_OID_SHA1) { + PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); + return NULL; + } + } + + hashLength = HASH_ResultLenByOidTag(hashAlgTag); + + if (pssParams.saltLength.data) { + rv = SEC_ASN1DecodeInteger((SECItem *)&pssParams.saltLength, + &saltLength); + if (rv != SECSuccess) { + return NULL; + } + + /* The specified salt length is too long */ + if (saltLength > modBytes - hashLength - 2) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return NULL; + } + } else if (defaultSHA1) { + saltLength = 20; + } + + /* Fill in the parameters */ + if (pssParams.hashAlg) { + if (hashAlgTag == SEC_OID_SHA1) { + /* Omit hashAlg if the the algorithm is SHA-1 (default) */ + pssParams.hashAlg = NULL; + } + } else { + if (hashAlgTag != SEC_OID_SHA1) { + pssParams.hashAlg = PORT_ArenaZAlloc(arena, sizeof(SECAlgorithmID)); + if (!pssParams.hashAlg) { + return NULL; + } + rv = SECOID_SetAlgorithmID(arena, pssParams.hashAlg, hashAlgTag, + NULL); + if (rv != SECSuccess) { + return NULL; + } + } + } + + if (pssParams.maskAlg) { + if (hashAlgTag == SEC_OID_SHA1) { + /* Omit maskAlg if the the algorithm is SHA-1 (default) */ + pssParams.maskAlg = NULL; + } + } else { + if (hashAlgTag != SEC_OID_SHA1) { + SECItem *hashAlgItem; + + PORT_Assert(pssParams.hashAlg != NULL); + + hashAlgItem = SEC_ASN1EncodeItem(arena, NULL, pssParams.hashAlg, + SEC_ASN1_GET(SECOID_AlgorithmIDTemplate)); + if (!hashAlgItem) { + return NULL; + } + pssParams.maskAlg = PORT_ArenaZAlloc(arena, sizeof(SECAlgorithmID)); + if (!pssParams.maskAlg) { + return NULL; + } + rv = SECOID_SetAlgorithmID(arena, pssParams.maskAlg, + SEC_OID_PKCS1_MGF1, hashAlgItem); + if (rv != SECSuccess) { + return NULL; + } + } + } + + if (pssParams.saltLength.data) { + if (saltLength == 20) { + /* Omit the salt length if it is the default */ + pssParams.saltLength.data = NULL; + } + } else { + /* Find a suitable length from the hash algorithm and modulus bits */ + saltLength = PR_MIN(hashLength, modBytes - hashLength - 2); + + if (saltLength != 20 && + !SEC_ASN1EncodeInteger(arena, &pssParams.saltLength, saltLength)) { + return NULL; + } + } + + if (pssParams.trailerField.data) { + /* Omit trailerField if the value is 1 (default) */ + pssParams.trailerField.data = NULL; + } + + return SEC_ASN1EncodeItem(arena, result, + &pssParams, SECKEY_RSAPSSParamsTemplate); +} + +SECItem * +SEC_CreateSignatureAlgorithmParameters(PLArenaPool *arena, + SECItem *result, + SECOidTag signAlgTag, + SECOidTag hashAlgTag, + const SECItem *params, + const SECKEYPrivateKey *key) +{ + switch (signAlgTag) { + case SEC_OID_PKCS1_RSA_PSS_SIGNATURE: + return sec_CreateRSAPSSParameters(arena, result, + hashAlgTag, params, key); + + default: + if (params == NULL) + return NULL; + if (result == NULL) + result = SECITEM_AllocItem(arena, NULL, 0); + if (SECITEM_CopyItem(arena, result, params) != SECSuccess) + return NULL; + return result; + } +} diff --git a/security/nss/lib/cryptohi/secvfy.c b/security/nss/lib/cryptohi/secvfy.c index 2ac21abd4..83c9c579d 100644 --- a/security/nss/lib/cryptohi/secvfy.c +++ b/security/nss/lib/cryptohi/secvfy.c @@ -136,6 +136,8 @@ struct VFYContextStr { unsigned char dsasig[DSA_MAX_SIGNATURE_LEN]; /* the full ECDSA signature */ unsigned char ecdsasig[2 * MAX_ECKEY_LEN]; + /* the full RSA signature, only used in RSA-PSS */ + unsigned char rsasig[(RSA_MAX_MODULUS_BITS + 7) / 8]; } u; unsigned int pkcs1RSADigestInfoLen; /* the encoded DigestInfo from a RSA PKCS#1 signature */ @@ -148,6 +150,7 @@ struct VFYContextStr { * VFY_CreateContext call. If false, the * signature must be provided with a * VFY_EndWithSignature call. */ + SECItem *params; }; static SECStatus @@ -250,9 +253,38 @@ sec_DecodeSigAlg(const SECKEYPublicKey *key, SECOidTag sigAlg, *hashalg = SEC_OID_SHA1; break; case SEC_OID_PKCS1_RSA_ENCRYPTION: - case SEC_OID_PKCS1_RSA_PSS_SIGNATURE: *hashalg = SEC_OID_UNKNOWN; /* get it from the RSA signature */ break; + case SEC_OID_PKCS1_RSA_PSS_SIGNATURE: + if (param && param->data) { + SECKEYRSAPSSParams pssParam; + arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); + if (arena == NULL) { + return SECFailure; + } + PORT_Memset(&pssParam, 0, sizeof pssParam); + rv = SEC_QuickDERDecodeItem(arena, &pssParam, + SECKEY_RSAPSSParamsTemplate, + param); + if (rv != SECSuccess) { + PORT_FreeArena(arena, PR_FALSE); + return rv; + } + if (pssParam.hashAlg) { + *hashalg = SECOID_GetAlgorithmTag(pssParam.hashAlg); + } else { + *hashalg = SEC_OID_SHA1; /* default, SHA-1 */ + } + PORT_FreeArena(arena, PR_FALSE); + /* only accept hash algorithms */ + if (HASH_GetHashTypeByOidTag(*hashalg) == HASH_AlgNULL) { + /* error set by HASH_GetHashTypeByOidTag */ + return SECFailure; + } + } else { + *hashalg = SEC_OID_SHA1; /* default, SHA-1 */ + } + break; case SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE: case SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION: @@ -434,6 +466,20 @@ vfy_CreateContext(const SECKEYPublicKey *key, const SECItem *sig, cx->key, sig, wincx); break; + case rsaPssKey: + sigLen = SECKEY_SignatureLen(key); + if (sigLen == 0) { + /* error set by SECKEY_SignatureLen */ + rv = SECFailure; + break; + } + if (sig->len != sigLen) { + PORT_SetError(SEC_ERROR_BAD_SIGNATURE); + rv = SECFailure; + break; + } + PORT_Memcpy(cx->u.buffer, sig->data, sigLen); + break; case dsaKey: case ecKey: sigLen = SECKEY_SignatureLen(key); @@ -496,6 +542,7 @@ VFYContext * VFY_CreateContextWithAlgorithmID(const SECKEYPublicKey *key, const SECItem *sig, const SECAlgorithmID *sigAlgorithm, SECOidTag *hash, void *wincx) { + VFYContext *cx; SECOidTag encAlg, hashAlg; SECStatus rv = sec_DecodeSigAlg(key, SECOID_GetAlgorithmTag((SECAlgorithmID *)sigAlgorithm), @@ -503,7 +550,13 @@ VFY_CreateContextWithAlgorithmID(const SECKEYPublicKey *key, const SECItem *sig, if (rv != SECSuccess) { return NULL; } - return vfy_CreateContext(key, sig, encAlg, hashAlg, hash, wincx); + + cx = vfy_CreateContext(key, sig, encAlg, hashAlg, hash, wincx); + if (sigAlgorithm->parameters.data) { + cx->params = SECITEM_DupItem(&sigAlgorithm->parameters); + } + + return cx; } void @@ -520,6 +573,9 @@ VFY_DestroyContext(VFYContext *cx, PRBool freeit) if (cx->pkcs1RSADigestInfo) { PORT_Free(cx->pkcs1RSADigestInfo); } + if (cx->params) { + SECITEM_FreeItem(cx->params, PR_TRUE); + } if (freeit) { PORT_ZFree(cx, sizeof(VFYContext)); } @@ -562,7 +618,7 @@ VFY_EndWithSignature(VFYContext *cx, SECItem *sig) { unsigned char final[HASH_LENGTH_MAX]; unsigned part; - SECItem hash, dsasig; /* dsasig is also used for ECDSA */ + SECItem hash, rsasig, dsasig; /* dsasig is also used for ECDSA */ SECStatus rv; if ((cx->hasSignature == PR_FALSE) && (sig == NULL)) { @@ -598,25 +654,70 @@ VFY_EndWithSignature(VFYContext *cx, SECItem *sig) return SECFailure; } break; - case rsaKey: { - SECItem digest; - digest.data = final; - digest.len = part; - if (sig) { - SECOidTag hashid; - PORT_Assert(cx->hashAlg != SEC_OID_UNKNOWN); - rv = recoverPKCS1DigestInfo(cx->hashAlg, &hashid, - &cx->pkcs1RSADigestInfo, - &cx->pkcs1RSADigestInfoLen, - cx->key, - sig, cx->wincx); - PORT_Assert(cx->hashAlg == hashid); + case rsaKey: + if (cx->encAlg == SEC_OID_PKCS1_RSA_PSS_SIGNATURE) { + CK_RSA_PKCS_PSS_PARAMS mech; + SECItem mechItem = { siBuffer, (unsigned char *)&mech, sizeof(mech) }; + SECKEYRSAPSSParams params; + PLArenaPool *arena; + + arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); + if (arena == NULL) { + return SECFailure; + } + + PORT_Memset(¶ms, 0, sizeof(params)); + rv = SEC_QuickDERDecodeItem(arena, ¶ms, + SECKEY_RSAPSSParamsTemplate, + cx->params); + if (rv != SECSuccess) { + PORT_FreeArena(arena, PR_FALSE); + return SECFailure; + } + rv = sec_RSAPSSParamsToMechanism(&mech, ¶ms); + PORT_FreeArena(arena, PR_FALSE); if (rv != SECSuccess) { return SECFailure; } + rsasig.data = cx->u.buffer; + rsasig.len = SECKEY_SignatureLen(cx->key); + if (rsasig.len == 0) { + return SECFailure; + } + if (sig) { + if (sig->len != rsasig.len) { + PORT_SetError(SEC_ERROR_BAD_SIGNATURE); + return SECFailure; + } + PORT_Memcpy(rsasig.data, sig->data, rsasig.len); + } + hash.data = final; + hash.len = part; + if (PK11_VerifyWithMechanism(cx->key, CKM_RSA_PKCS_PSS, &mechItem, + &rsasig, &hash, cx->wincx) != SECSuccess) { + PORT_SetError(SEC_ERROR_BAD_SIGNATURE); + return SECFailure; + } + } else { + SECItem digest; + digest.data = final; + digest.len = part; + if (sig) { + SECOidTag hashid; + PORT_Assert(cx->hashAlg != SEC_OID_UNKNOWN); + rv = recoverPKCS1DigestInfo(cx->hashAlg, &hashid, + &cx->pkcs1RSADigestInfo, + &cx->pkcs1RSADigestInfoLen, + cx->key, + sig, cx->wincx); + PORT_Assert(cx->hashAlg == hashid); + if (rv != SECSuccess) { + return SECFailure; + } + } + return verifyPKCS1DigestInfo(cx, &digest); } - return verifyPKCS1DigestInfo(cx, &digest); - } + break; default: PORT_SetError(SEC_ERROR_BAD_SIGNATURE); return SECFailure; /* shouldn't happen */ @@ -722,7 +823,7 @@ VFY_VerifyDigestWithAlgorithmID(const SECItem *digest, static SECStatus vfy_VerifyData(const unsigned char *buf, int len, const SECKEYPublicKey *key, const SECItem *sig, SECOidTag encAlg, SECOidTag hashAlg, - SECOidTag *hash, void *wincx) + const SECItem *params, SECOidTag *hash, void *wincx) { SECStatus rv; VFYContext *cx; @@ -730,6 +831,9 @@ vfy_VerifyData(const unsigned char *buf, int len, const SECKEYPublicKey *key, cx = vfy_CreateContext(key, sig, encAlg, hashAlg, hash, wincx); if (cx == NULL) return SECFailure; + if (params) { + cx->params = SECITEM_DupItem(params); + } rv = VFY_Begin(cx); if (rv == SECSuccess) { @@ -748,7 +852,7 @@ VFY_VerifyDataDirect(const unsigned char *buf, int len, SECOidTag encAlg, SECOidTag hashAlg, SECOidTag *hash, void *wincx) { - return vfy_VerifyData(buf, len, key, sig, encAlg, hashAlg, hash, wincx); + return vfy_VerifyData(buf, len, key, sig, encAlg, hashAlg, NULL, hash, wincx); } SECStatus @@ -760,7 +864,7 @@ VFY_VerifyData(const unsigned char *buf, int len, const SECKEYPublicKey *key, if (rv != SECSuccess) { return rv; } - return vfy_VerifyData(buf, len, key, sig, encAlg, hashAlg, NULL, wincx); + return vfy_VerifyData(buf, len, key, sig, encAlg, hashAlg, NULL, NULL, wincx); } SECStatus @@ -777,5 +881,6 @@ VFY_VerifyDataWithAlgorithmID(const unsigned char *buf, int len, if (rv != SECSuccess) { return rv; } - return vfy_VerifyData(buf, len, key, sig, encAlg, hashAlg, hash, wincx); + return vfy_VerifyData(buf, len, key, sig, encAlg, hashAlg, + &sigAlgorithm->parameters, hash, wincx); } diff --git a/security/nss/lib/dbm/src/h_page.c b/security/nss/lib/dbm/src/h_page.c index bf1252aeb..e5623224b 100644 --- a/security/nss/lib/dbm/src/h_page.c +++ b/security/nss/lib/dbm/src/h_page.c @@ -426,6 +426,9 @@ ugly_split(HTAB *hashp, uint32 obucket, BUFHEAD *old_bufp, last_bfp = NULL; scopyto = (uint16)copyto; /* ANSI */ + if (ino[0] < 1) { + return DATABASE_CORRUPTED_ERROR; + } n = ino[0] - 1; while (n < ino[0]) { @@ -463,7 +466,13 @@ ugly_split(HTAB *hashp, uint32 obucket, BUFHEAD *old_bufp, * Fix up the old page -- the extra 2 are the fields * which contained the overflow information. */ + if (ino[0] < (moved + 2)) { + return DATABASE_CORRUPTED_ERROR; + } ino[0] -= (moved + 2); + if (scopyto < sizeof(uint16) * (ino[0] + 3)) { + return DATABASE_CORRUPTED_ERROR; + } FREESPACE(ino) = scopyto - sizeof(uint16) * (ino[0] + 3); OFFSET(ino) = scopyto; @@ -486,8 +495,14 @@ ugly_split(HTAB *hashp, uint32 obucket, BUFHEAD *old_bufp, for (n = 1; (n < ino[0]) && (ino[n + 1] >= REAL_KEY); n += 2) { cino = (char *)ino; key.data = (uint8 *)cino + ino[n]; + if (off < ino[n]) { + return DATABASE_CORRUPTED_ERROR; + } key.size = off - ino[n]; val.data = (uint8 *)cino + ino[n + 1]; + if (ino[n] < ino[n + 1]) { + return DATABASE_CORRUPTED_ERROR; + } val.size = ino[n] - ino[n + 1]; off = ino[n + 1]; diff --git a/security/nss/lib/dbm/src/hash.c b/security/nss/lib/dbm/src/hash.c index b80aad4d3..98b1c07c7 100644 --- a/security/nss/lib/dbm/src/hash.c +++ b/security/nss/lib/dbm/src/hash.c @@ -704,8 +704,7 @@ hash_put( return (DBM_ERROR); } - rv = hash_access(hashp, flag == R_NOOVERWRITE ? HASH_PUTNEW - : HASH_PUT, + rv = hash_access(hashp, flag == R_NOOVERWRITE ? HASH_PUTNEW : HASH_PUT, (DBT *)key, (DBT *)data); if (rv == DATABASE_CORRUPTED_ERROR) { diff --git a/security/nss/lib/dev/devslot.c b/security/nss/lib/dev/devslot.c index 9f0bd8226..ebd6e6aa5 100644 --- a/security/nss/lib/dev/devslot.c +++ b/security/nss/lib/dev/devslot.c @@ -33,6 +33,8 @@ nssSlot_Destroy( if (PR_ATOMIC_DECREMENT(&slot->base.refCount) == 0) { PK11_FreeSlot(slot->pk11slot); PZ_DestroyLock(slot->base.lock); + PZ_DestroyCondVar(slot->isPresentCondition); + PZ_DestroyLock(slot->isPresentLock); return nssArena_Destroy(slot->base.arena); } } @@ -88,20 +90,28 @@ NSS_IMPLEMENT void nssSlot_ResetDelay( NSSSlot *slot) { - slot->lastTokenPing = 0; + PZ_Lock(slot->isPresentLock); + slot->lastTokenPingState = nssSlotLastPingState_Reset; + PZ_Unlock(slot->isPresentLock); } static PRBool -within_token_delay_period(const NSSSlot *slot) +token_status_checked(const NSSSlot *slot) { - PRIntervalTime time, lastTime; + PRIntervalTime time; + int lastPingState = slot->lastTokenPingState; + /* When called from the same thread, that means + * nssSlot_IsTokenPresent() is called recursively through + * nssSlot_Refresh(). Return immediately in that case. */ + if (slot->isPresentThread == PR_GetCurrentThread()) { + return PR_TRUE; + } /* Set the delay time for checking the token presence */ if (s_token_delay_time == 0) { s_token_delay_time = PR_SecondsToInterval(NSSSLOT_TOKEN_DELAY_TIME); } time = PR_IntervalNow(); - lastTime = slot->lastTokenPing; - if ((lastTime) && ((time - lastTime) < s_token_delay_time)) { + if ((lastPingState == nssSlotLastPingState_Valid) && ((time - slot->lastTokenPingTime) < s_token_delay_time)) { return PR_TRUE; } return PR_FALSE; @@ -117,35 +127,63 @@ nssSlot_IsTokenPresent( nssSession *session; CK_SLOT_INFO slotInfo; void *epv; + PRBool isPresent = PR_FALSE; + /* permanent slots are always present unless they're disabled */ if (nssSlot_IsPermanent(slot)) { return !PK11_IsDisabled(slot->pk11slot); } + /* avoid repeated calls to check token status within set interval */ - if (within_token_delay_period(slot)) { - return ((slot->ckFlags & CKF_TOKEN_PRESENT) != 0); + PZ_Lock(slot->isPresentLock); + if (token_status_checked(slot)) { + CK_FLAGS ckFlags = slot->ckFlags; + PZ_Unlock(slot->isPresentLock); + return ((ckFlags & CKF_TOKEN_PRESENT) != 0); } + PZ_Unlock(slot->isPresentLock); - /* First obtain the slot info */ + /* First obtain the slot epv before we set up the condition + * variable, so we can just return if we couldn't get it. */ epv = slot->epv; if (!epv) { return PR_FALSE; } + + /* set up condition so only one thread is active in this part of the code at a time */ + PZ_Lock(slot->isPresentLock); + while (slot->isPresentThread) { + PR_WaitCondVar(slot->isPresentCondition, PR_INTERVAL_NO_TIMEOUT); + } + /* if we were one of multiple threads here, the first thread will have + * given us the answer, no need to make more queries of the token. */ + if (token_status_checked(slot)) { + CK_FLAGS ckFlags = slot->ckFlags; + PZ_Unlock(slot->isPresentLock); + return ((ckFlags & CKF_TOKEN_PRESENT) != 0); + } + /* this is the winning thread, block all others until we've determined + * if the token is present and that it needs initialization. */ + slot->lastTokenPingState = nssSlotLastPingState_Update; + slot->isPresentThread = PR_GetCurrentThread(); + + PZ_Unlock(slot->isPresentLock); + nssSlot_EnterMonitor(slot); ckrv = CKAPI(epv)->C_GetSlotInfo(slot->slotID, &slotInfo); nssSlot_ExitMonitor(slot); if (ckrv != CKR_OK) { slot->token->base.name[0] = 0; /* XXX */ - slot->lastTokenPing = PR_IntervalNow(); - return PR_FALSE; + isPresent = PR_FALSE; + goto done; } slot->ckFlags = slotInfo.flags; /* check for the presence of the token */ if ((slot->ckFlags & CKF_TOKEN_PRESENT) == 0) { if (!slot->token) { /* token was never present */ - slot->lastTokenPing = PR_IntervalNow(); - return PR_FALSE; + isPresent = PR_FALSE; + goto done; } session = nssToken_GetDefaultSession(slot->token); if (session) { @@ -167,15 +205,15 @@ nssSlot_IsTokenPresent( slot->token->base.name[0] = 0; /* XXX */ /* clear the token cache */ nssToken_Remove(slot->token); - slot->lastTokenPing = PR_IntervalNow(); - return PR_FALSE; + isPresent = PR_FALSE; + goto done; } /* token is present, use the session info to determine if the card * has been removed and reinserted. */ session = nssToken_GetDefaultSession(slot->token); if (session) { - PRBool isPresent = PR_FALSE; + PRBool tokenRemoved; nssSession_EnterMonitor(session); if (session->handle != CK_INVALID_SESSION) { CK_SESSION_INFO sessionInfo; @@ -187,12 +225,12 @@ nssSlot_IsTokenPresent( session->handle = CK_INVALID_SESSION; } } - isPresent = session->handle != CK_INVALID_SESSION; + tokenRemoved = (session->handle == CK_INVALID_SESSION); nssSession_ExitMonitor(session); /* token not removed, finished */ - if (isPresent) { - slot->lastTokenPing = PR_IntervalNow(); - return PR_TRUE; + if (!tokenRemoved) { + isPresent = PR_TRUE; + goto done; } } /* the token has been removed, and reinserted, or the slot contains @@ -203,15 +241,32 @@ nssSlot_IsTokenPresent( nssToken_Remove(slot->token); /* token has been removed, need to refresh with new session */ nssrv = nssSlot_Refresh(slot); + isPresent = PR_TRUE; if (nssrv != PR_SUCCESS) { slot->token->base.name[0] = 0; /* XXX */ slot->ckFlags &= ~CKF_TOKEN_PRESENT; - /* TODO: insert a barrier here to avoid reordering of the assingments */ - slot->lastTokenPing = PR_IntervalNow(); - return PR_FALSE; + isPresent = PR_FALSE; + } +done: + /* Once we've set up the condition variable, + * Before returning, it's necessary to: + * 1) Set the lastTokenPingTime so that any other threads waiting on this + * initialization and any future calls within the initialization window + * return the just-computed status. + * 2) Indicate we're complete, waking up all other threads that may still + * be waiting on initialization can progress. + */ + PZ_Lock(slot->isPresentLock); + /* don't update the time if we were reset while we were + * getting the token state */ + if (slot->lastTokenPingState == nssSlotLastPingState_Update) { + slot->lastTokenPingTime = PR_IntervalNow(); + slot->lastTokenPingState = nssSlotLastPingState_Valid; } - slot->lastTokenPing = PR_IntervalNow(); - return PR_TRUE; + slot->isPresentThread = NULL; + PR_NotifyAllCondVar(slot->isPresentCondition); + PZ_Unlock(slot->isPresentLock); + return isPresent; } NSS_IMPLEMENT void * @@ -229,7 +284,7 @@ nssSlot_GetToken( if (nssSlot_IsTokenPresent(slot)) { /* Even if a token should be present, check `slot->token` too as it - * might be gone already. This would happen mostly on shutdown. */ + * might be gone already. This would happen mostly on shutdown. */ nssSlot_EnterMonitor(slot); if (slot->token) rvToken = nssToken_AddRef(slot->token); diff --git a/security/nss/lib/dev/devt.h b/security/nss/lib/dev/devt.h index db93deb12..0f6d9e49a 100644 --- a/security/nss/lib/dev/devt.h +++ b/security/nss/lib/dev/devt.h @@ -70,6 +70,14 @@ struct nssSlotAuthInfoStr { PRIntervalTime askPasswordTimeout; }; +/* values for lastTokenPingState */ +typedef enum { + nssSlotLastPingState_Reset = 0, /* the state has just been reset, discard + * our cache */ + nssSlotLastPingState_Update = 1, /* we are updating the lastTokenPingTime */ + nssSlotLastPingState_Valid = 2, /* lastTokenPingTime is valid */ +} nssSlotLastPingState; + struct NSSSlotStr { struct nssDeviceBaseStr base; NSSModule *module; /* Parent */ @@ -77,10 +85,14 @@ struct NSSSlotStr { CK_SLOT_ID slotID; CK_FLAGS ckFlags; /* from CK_SLOT_INFO.flags */ struct nssSlotAuthInfoStr authInfo; - PRIntervalTime lastTokenPing; + PRIntervalTime lastTokenPingTime; + nssSlotLastPingState lastTokenPingState; PZLock *lock; void *epv; PK11SlotInfo *pk11slot; + PZLock *isPresentLock; + PRCondVar *isPresentCondition; + PRThread *isPresentThread; }; struct nssSessionStr { diff --git a/security/nss/lib/dev/devutil.c b/security/nss/lib/dev/devutil.c index b8f82c810..74c32f088 100644 --- a/security/nss/lib/dev/devutil.c +++ b/security/nss/lib/dev/devutil.c @@ -32,15 +32,21 @@ nssCryptokiObject_Create( /* a failure here indicates a device error */ return (nssCryptokiObject *)NULL; } + if (cert_template[0].ulValueLen == 0 || !cert_template[0].pValue) { + nss_ZFreeIf(cert_template[1].pValue); + return (nssCryptokiObject *)NULL; + } object = nss_ZNEW(NULL, nssCryptokiObject); if (!object) { + nss_ZFreeIf(cert_template[0].pValue); + nss_ZFreeIf(cert_template[1].pValue); return (nssCryptokiObject *)NULL; } object->handle = h; object->token = nssToken_AddRef(t); isTokenObject = (CK_BBOOL *)cert_template[0].pValue; object->isTokenObject = *isTokenObject; - nss_ZFreeIf(isTokenObject); + nss_ZFreeIf(cert_template[0].pValue); NSS_CK_ATTRIBUTE_TO_UTF8(&cert_template[1], object->label); return object; } diff --git a/security/nss/lib/freebl/Makefile b/security/nss/lib/freebl/Makefile index 914a0119c..a4b1a86ae 100644 --- a/security/nss/lib/freebl/Makefile +++ b/security/nss/lib/freebl/Makefile @@ -110,7 +110,9 @@ endif # NSS_X86_OR_X64 means the target is either x86 or x64 ifeq (,$(filter-out i386 x386 x86 x86_64,$(CPU_ARCH))) DEFINES += -DNSS_X86_OR_X64 - CFLAGS += -mpclmul -maes + EXTRA_SRCS += gcm-x86.c aes-x86.c +$(OBJDIR)/gcm-x86.o: CFLAGS += -mpclmul -maes +$(OBJDIR)/aes-x86.o: CFLAGS += -mpclmul -maes ifneq (,$(USE_64)$(USE_X32)) DEFINES += -DNSS_X64 else @@ -490,8 +492,6 @@ else endif # Solaris for non-sparc family CPUs endif # target == SunO -# poly1305-donna-x64-sse2-incremental-source.c requires __int128 support -# in GCC 4.6.0. ifdef USE_64 ifdef CC_IS_CLANG HAVE_INT128_SUPPORT = 1 @@ -508,38 +508,39 @@ ifdef USE_64 endif endif +ifndef HAVE_INT128_SUPPORT + DEFINES += -DKRML_NOUINT128 +endif + ifndef NSS_DISABLE_CHACHAPOLY ifeq ($(CPU_ARCH),x86_64) ifdef HAVE_INT128_SUPPORT - EXTRA_SRCS += poly1305-donna-x64-sse2-incremental-source.c + EXTRA_SRCS += Hacl_Poly1305_64.c else EXTRA_SRCS += poly1305.c endif - - ifneq (1,$(CC_IS_GCC)) - EXTRA_SRCS += chacha20.c + else + ifeq ($(CPU_ARCH),aarch64) + EXTRA_SRCS += Hacl_Poly1305_64.c else - EXTRA_SRCS += chacha20_vec.c + EXTRA_SRCS += poly1305.c endif - else - EXTRA_SRCS += poly1305.c - EXTRA_SRCS += chacha20.c endif # x86_64 + + VERIFIED_SRCS += Hacl_Chacha20.c + VERIFIED_SRCS += Hacl_Chacha20_Vec128.c endif # NSS_DISABLE_CHACHAPOLY -ifeq (,$(filter-out i386 x386 x86 x86_64,$(CPU_ARCH))) +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 else # All non intel architectures get the generic 32 bit implementation (slow!) ECL_SRCS += curve25519_32.c endif -ifndef HAVE_INT128_SUPPORT - ECL_SRCS += uint128.c -endif - ####################################################################### # (5) Execute "global" rules. (OPTIONAL) # ####################################################################### @@ -563,12 +564,12 @@ rijndael_tables: $(DEFINES) $(INCLUDES) $(OBJDIR)/libfreebl.a $(OBJDIR)/make_rijndael_tab -vpath %.h mpi ecl -vpath %.c mpi ecl +vpath %.h mpi ecl verified +vpath %.c mpi ecl verified vpath %.S mpi ecl vpath %.s mpi ecl vpath %.asm mpi ecl -INCLUDES += -Impi -Iecl +INCLUDES += -Impi -Iecl -Iverified DEFINES += -DMP_API_COMPATIBLE @@ -587,8 +588,6 @@ ECL_OBJS += $(addprefix $(OBJDIR)/$(PROG_PREFIX), $(ECL_USERS:.c=$(OBJ_SUFFIX))) $(ECL_OBJS): $(ECL_HDRS) - - $(OBJDIR)/sysrand$(OBJ_SUFFIX): sysrand.c unix_rand.c win_rand.c $(OBJDIR)/$(PROG_PREFIX)mpprime$(OBJ_SUFFIX): primes.c diff --git a/security/nss/lib/freebl/aes-x86.c b/security/nss/lib/freebl/aes-x86.c new file mode 100644 index 000000000..830b4782f --- /dev/null +++ b/security/nss/lib/freebl/aes-x86.c @@ -0,0 +1,157 @@ +/* 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 FREEBL_NO_DEPEND +#include "stubs.h" +#endif +#include "rijndael.h" +#include "secerr.h" + +#include <wmmintrin.h> /* aes-ni */ + +#define EXPAND_KEY128(k, rcon, res) \ + tmp_key = _mm_aeskeygenassist_si128(k, rcon); \ + tmp_key = _mm_shuffle_epi32(tmp_key, 0xFF); \ + tmp = _mm_xor_si128(k, _mm_slli_si128(k, 4)); \ + tmp = _mm_xor_si128(tmp, _mm_slli_si128(tmp, 4)); \ + tmp = _mm_xor_si128(tmp, _mm_slli_si128(tmp, 4)); \ + res = _mm_xor_si128(tmp, tmp_key) + +static void +native_key_expansion128(AESContext *cx, const unsigned char *key) +{ + __m128i *keySchedule = cx->keySchedule; + pre_align __m128i tmp_key post_align; + pre_align __m128i tmp post_align; + keySchedule[0] = _mm_loadu_si128((__m128i *)key); + EXPAND_KEY128(keySchedule[0], 0x01, keySchedule[1]); + EXPAND_KEY128(keySchedule[1], 0x02, keySchedule[2]); + EXPAND_KEY128(keySchedule[2], 0x04, keySchedule[3]); + EXPAND_KEY128(keySchedule[3], 0x08, keySchedule[4]); + EXPAND_KEY128(keySchedule[4], 0x10, keySchedule[5]); + EXPAND_KEY128(keySchedule[5], 0x20, keySchedule[6]); + EXPAND_KEY128(keySchedule[6], 0x40, keySchedule[7]); + EXPAND_KEY128(keySchedule[7], 0x80, keySchedule[8]); + EXPAND_KEY128(keySchedule[8], 0x1B, keySchedule[9]); + EXPAND_KEY128(keySchedule[9], 0x36, keySchedule[10]); +} + +#define EXPAND_KEY192_PART1(res, k0, kt, rcon) \ + tmp2 = _mm_slli_si128(k0, 4); \ + tmp1 = _mm_xor_si128(k0, tmp2); \ + tmp2 = _mm_slli_si128(tmp2, 4); \ + tmp1 = _mm_xor_si128(_mm_xor_si128(tmp1, tmp2), _mm_slli_si128(tmp2, 4)); \ + tmp2 = _mm_aeskeygenassist_si128(kt, rcon); \ + res = _mm_xor_si128(tmp1, _mm_shuffle_epi32(tmp2, 0x55)) + +#define EXPAND_KEY192_PART2(res, k1, k2) \ + tmp2 = _mm_xor_si128(k1, _mm_slli_si128(k1, 4)); \ + res = _mm_xor_si128(tmp2, _mm_shuffle_epi32(k2, 0xFF)) + +#define EXPAND_KEY192(k0, res1, res2, res3, carry, rcon1, rcon2) \ + EXPAND_KEY192_PART1(tmp3, k0, res1, rcon1); \ + EXPAND_KEY192_PART2(carry, res1, tmp3); \ + res1 = _mm_castpd_si128(_mm_shuffle_pd(_mm_castsi128_pd(res1), \ + _mm_castsi128_pd(tmp3), 0)); \ + res2 = _mm_castpd_si128(_mm_shuffle_pd(_mm_castsi128_pd(tmp3), \ + _mm_castsi128_pd(carry), 1)); \ + EXPAND_KEY192_PART1(res3, tmp3, carry, rcon2) + +static void +native_key_expansion192(AESContext *cx, const unsigned char *key) +{ + __m128i *keySchedule = cx->keySchedule; + pre_align __m128i tmp1 post_align; + pre_align __m128i tmp2 post_align; + pre_align __m128i tmp3 post_align; + pre_align __m128i carry post_align; + keySchedule[0] = _mm_loadu_si128((__m128i *)key); + keySchedule[1] = _mm_loadu_si128((__m128i *)(key + 16)); + EXPAND_KEY192(keySchedule[0], keySchedule[1], keySchedule[2], + keySchedule[3], carry, 0x1, 0x2); + EXPAND_KEY192_PART2(keySchedule[4], carry, keySchedule[3]); + EXPAND_KEY192(keySchedule[3], keySchedule[4], keySchedule[5], + keySchedule[6], carry, 0x4, 0x8); + EXPAND_KEY192_PART2(keySchedule[7], carry, keySchedule[6]); + EXPAND_KEY192(keySchedule[6], keySchedule[7], keySchedule[8], + keySchedule[9], carry, 0x10, 0x20); + EXPAND_KEY192_PART2(keySchedule[10], carry, keySchedule[9]); + EXPAND_KEY192(keySchedule[9], keySchedule[10], keySchedule[11], + keySchedule[12], carry, 0x40, 0x80); +} + +#define EXPAND_KEY256_PART(res, rconx, k1x, k2x, X) \ + tmp_key = _mm_shuffle_epi32(_mm_aeskeygenassist_si128(k2x, rconx), X); \ + tmp2 = _mm_slli_si128(k1x, 4); \ + tmp1 = _mm_xor_si128(k1x, tmp2); \ + tmp2 = _mm_slli_si128(tmp2, 4); \ + tmp1 = _mm_xor_si128(_mm_xor_si128(tmp1, tmp2), _mm_slli_si128(tmp2, 4)); \ + res = _mm_xor_si128(tmp1, tmp_key); + +#define EXPAND_KEY256(res1, res2, k1, k2, rcon) \ + EXPAND_KEY256_PART(res1, rcon, k1, k2, 0xFF); \ + EXPAND_KEY256_PART(res2, 0x00, k2, res1, 0xAA) + +static void +native_key_expansion256(AESContext *cx, const unsigned char *key) +{ + __m128i *keySchedule = cx->keySchedule; + pre_align __m128i tmp_key post_align; + pre_align __m128i tmp1 post_align; + pre_align __m128i tmp2 post_align; + keySchedule[0] = _mm_loadu_si128((__m128i *)key); + keySchedule[1] = _mm_loadu_si128((__m128i *)(key + 16)); + EXPAND_KEY256(keySchedule[2], keySchedule[3], keySchedule[0], + keySchedule[1], 0x01); + EXPAND_KEY256(keySchedule[4], keySchedule[5], keySchedule[2], + keySchedule[3], 0x02); + EXPAND_KEY256(keySchedule[6], keySchedule[7], keySchedule[4], + keySchedule[5], 0x04); + EXPAND_KEY256(keySchedule[8], keySchedule[9], keySchedule[6], + keySchedule[7], 0x08); + EXPAND_KEY256(keySchedule[10], keySchedule[11], keySchedule[8], + keySchedule[9], 0x10); + EXPAND_KEY256(keySchedule[12], keySchedule[13], keySchedule[10], + keySchedule[11], 0x20); + EXPAND_KEY256_PART(keySchedule[14], 0x40, keySchedule[12], + keySchedule[13], 0xFF); +} + +/* + * AES key expansion using aes-ni instructions. + */ +void +rijndael_native_key_expansion(AESContext *cx, const unsigned char *key, + unsigned int Nk) +{ + switch (Nk) { + case 4: + native_key_expansion128(cx, key); + return; + case 6: + native_key_expansion192(cx, key); + return; + case 8: + native_key_expansion256(cx, key); + return; + default: + /* This shouldn't happen (checked by the caller). */ + return; + } +} + +void +rijndael_native_encryptBlock(AESContext *cx, + unsigned char *output, + const unsigned char *input) +{ + int i; + pre_align __m128i m post_align = _mm_loadu_si128((__m128i *)input); + m = _mm_xor_si128(m, cx->keySchedule[0]); + for (i = 1; i < cx->Nr; ++i) { + m = _mm_aesenc_si128(m, cx->keySchedule[i]); + } + m = _mm_aesenclast_si128(m, cx->keySchedule[cx->Nr]); + _mm_storeu_si128((__m128i *)output, m); +} diff --git a/security/nss/lib/freebl/blake2b.c b/security/nss/lib/freebl/blake2b.c new file mode 100644 index 000000000..4099c67e0 --- /dev/null +++ b/security/nss/lib/freebl/blake2b.c @@ -0,0 +1,430 @@ +/* + * blake2b.c - definitions for the blake2b hash function + * + * 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 FREEBL_NO_DEPEND +#include "stubs.h" +#endif + +#include "secerr.h" +#include "blapi.h" +#include "blake2b.h" +#include "crypto_primitives.h" + +/** + * This contains the BLAKE2b initialization vectors. + */ +static const uint64_t iv[8] = { + 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL, + 0xa54ff53a5f1d36f1ULL, 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, + 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL +}; + +/** + * This contains the table of permutations for blake2b compression function. + */ +static const uint8_t sigma[12][16] = { + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, + { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }, + { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 }, + { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 }, + { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 }, + { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 }, + { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 }, + { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 }, + { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 }, + { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0 }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, + { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } +}; + +/** + * This function increments the blake2b ctx counter. + */ +void +blake2b_IncrementCounter(BLAKE2BContext* ctx, const uint64_t inc) +{ + ctx->t[0] += inc; + ctx->t[1] += ctx->t[0] < inc; +} + +/** + * This macro implements the blake2b mixing function which mixes two 8-byte + * words from the message into the hash. + */ +#define G(a, b, c, d, x, y) \ + a += b + x; \ + d = ROTR64(d ^ a, 32); \ + c += d; \ + b = ROTR64(b ^ c, 24); \ + a += b + y; \ + d = ROTR64(d ^ a, 16); \ + c += d; \ + b = ROTR64(b ^ c, 63) + +#define ROUND(i) \ + G(v[0], v[4], v[8], v[12], m[sigma[i][0]], m[sigma[i][1]]); \ + G(v[1], v[5], v[9], v[13], m[sigma[i][2]], m[sigma[i][3]]); \ + G(v[2], v[6], v[10], v[14], m[sigma[i][4]], m[sigma[i][5]]); \ + G(v[3], v[7], v[11], v[15], m[sigma[i][6]], m[sigma[i][7]]); \ + G(v[0], v[5], v[10], v[15], m[sigma[i][8]], m[sigma[i][9]]); \ + G(v[1], v[6], v[11], v[12], m[sigma[i][10]], m[sigma[i][11]]); \ + G(v[2], v[7], v[8], v[13], m[sigma[i][12]], m[sigma[i][13]]); \ + G(v[3], v[4], v[9], v[14], m[sigma[i][14]], m[sigma[i][15]]) + +/** + * The blake2b compression function which takes a full 128-byte chunk of the + * input message and mixes it into the ongoing ctx array, i.e., permute the + * ctx while xoring in the block of data. + */ +void +blake2b_Compress(BLAKE2BContext* ctx, const uint8_t* block) +{ + size_t i; + uint64_t v[16], m[16]; + + PORT_Memcpy(m, block, BLAKE2B_BLOCK_LENGTH); +#if !defined(IS_LITTLE_ENDIAN) + for (i = 0; i < 16; ++i) { + m[i] = FREEBL_HTONLL(m[i]); + } +#endif + + PORT_Memcpy(v, ctx->h, 8 * 8); + PORT_Memcpy(v + 8, iv, 8 * 8); + + v[12] ^= ctx->t[0]; + v[13] ^= ctx->t[1]; + v[14] ^= ctx->f; + + ROUND(0); + ROUND(1); + ROUND(2); + ROUND(3); + ROUND(4); + ROUND(5); + ROUND(6); + ROUND(7); + ROUND(8); + ROUND(9); + ROUND(10); + ROUND(11); + + for (i = 0; i < 8; i++) { + ctx->h[i] ^= v[i] ^ v[i + 8]; + } +} + +/** + * This function can be used for both keyed and unkeyed version. + */ +BLAKE2BContext* +BLAKE2B_NewContext() +{ + return PORT_ZNew(BLAKE2BContext); +} + +/** + * Zero and free the context and can be used for both keyed and unkeyed version. + */ +void +BLAKE2B_DestroyContext(BLAKE2BContext* ctx, PRBool freeit) +{ + PORT_Memset(ctx, 0, sizeof(*ctx)); + if (freeit) { + PORT_Free(ctx); + } +} + +/** + * This function initializes blake2b ctx and can be used for both keyed and + * unkeyed version. It also checks ctx and sets error states. + */ +static SECStatus +blake2b_Begin(BLAKE2BContext* ctx, uint8_t outlen, const uint8_t* key, + size_t keylen) +{ + PORT_Assert(ctx != NULL); + if (!ctx) { + goto failure; + } + if (outlen == 0 || outlen > BLAKE2B512_LENGTH) { + goto failure; + } + if (key && keylen > BLAKE2B_KEY_SIZE) { + goto failure; + } + /* Note: key can be null if it's unkeyed. */ + if ((key == NULL && keylen > 0) || keylen > BLAKE2B_KEY_SIZE || + (key != NULL && keylen == 0)) { + goto failure; + } + + /* Mix key size(keylen) and desired hash length(outlen) into h0 */ + uint64_t param = outlen ^ (keylen << 8) ^ (1 << 16) ^ (1 << 24); + PORT_Memcpy(ctx->h, iv, 8 * 8); + ctx->h[0] ^= param; + ctx->outlen = outlen; + + /* This updates the context for only the keyed version */ + if (keylen > 0 && keylen <= BLAKE2B_KEY_SIZE && key) { + uint8_t block[BLAKE2B_BLOCK_LENGTH] = { 0 }; + PORT_Memcpy(block, key, keylen); + BLAKE2B_Update(ctx, block, BLAKE2B_BLOCK_LENGTH); + PORT_Memset(block, 0, BLAKE2B_BLOCK_LENGTH); + } + + return SECSuccess; + +failure: + PORT_Memset(&ctx, 0, sizeof(ctx)); + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; +} + +SECStatus +BLAKE2B_Begin(BLAKE2BContext* ctx) +{ + return blake2b_Begin(ctx, BLAKE2B512_LENGTH, NULL, 0); +} + +SECStatus +BLAKE2B_MAC_Begin(BLAKE2BContext* ctx, const PRUint8* key, const size_t keylen) +{ + PORT_Assert(key != NULL); + if (!key) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + return blake2b_Begin(ctx, BLAKE2B512_LENGTH, (const uint8_t*)key, keylen); +} + +static void +blake2b_IncrementCompress(BLAKE2BContext* ctx, size_t blockLength, + const unsigned char* input) +{ + blake2b_IncrementCounter(ctx, blockLength); + blake2b_Compress(ctx, input); +} + +/** + * This function updates blake2b ctx and can be used for both keyed and unkeyed + * version. + */ +SECStatus +BLAKE2B_Update(BLAKE2BContext* ctx, const unsigned char* in, + unsigned int inlen) +{ + size_t left = ctx->buflen; + size_t fill = BLAKE2B_BLOCK_LENGTH - left; + + /* Nothing to do if there's nothing. */ + if (inlen == 0) { + return SECSuccess; + } + + PORT_Assert(ctx != NULL); + PORT_Assert(in != NULL); + PORT_Assert(left <= BLAKE2B_BLOCK_LENGTH); + if (!ctx || !in) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + + /* Is this a reused context? */ + if (ctx->f) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + + if (inlen > fill) { + if (ctx->buflen) { + /* There's some remaining data in ctx->buf that we have to prepend + * to in. */ + PORT_Memcpy(ctx->buf + left, in, fill); + ctx->buflen = 0; + blake2b_IncrementCompress(ctx, BLAKE2B_BLOCK_LENGTH, ctx->buf); + in += fill; + inlen -= fill; + } + while (inlen > BLAKE2B_BLOCK_LENGTH) { + blake2b_IncrementCompress(ctx, BLAKE2B_BLOCK_LENGTH, in); + in += BLAKE2B_BLOCK_LENGTH; + inlen -= BLAKE2B_BLOCK_LENGTH; + } + } + + /* Store the remaining data from in in ctx->buf to process later. + * Note that ctx->buflen can be BLAKE2B_BLOCK_LENGTH. We can't process that + * here because we have to update ctx->f before compressing the last block. + */ + PORT_Assert(inlen <= BLAKE2B_BLOCK_LENGTH); + PORT_Memcpy(ctx->buf + ctx->buflen, in, inlen); + ctx->buflen += inlen; + + return SECSuccess; +} + +/** + * This function finalizes ctx, pads final block and stores hash. + * It can be used for both keyed and unkeyed version. + */ +SECStatus +BLAKE2B_End(BLAKE2BContext* ctx, unsigned char* out, + unsigned int* digestLen, size_t maxDigestLen) +{ + size_t i; + unsigned int outlen = PR_MIN(BLAKE2B512_LENGTH, maxDigestLen); + + /* Argument checks */ + if (!ctx || !out) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + + /* Sanity check against outlen in context. */ + if (ctx->outlen < outlen) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + + /* Is this a reused context? */ + if (ctx->f != 0) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + + /* Process the remaining data from ctx->buf (padded with 0). */ + blake2b_IncrementCounter(ctx, ctx->buflen); + /* BLAKE2B_BLOCK_LENGTH - ctx->buflen can be 0. */ + PORT_Memset(ctx->buf + ctx->buflen, 0, BLAKE2B_BLOCK_LENGTH - ctx->buflen); + ctx->f = UINT64_MAX; + blake2b_Compress(ctx, ctx->buf); + + /* Write out the blake2b context(ctx). */ + for (i = 0; i < outlen; ++i) { + out[i] = ctx->h[i / 8] >> ((i % 8) * 8); + } + + if (digestLen) { + *digestLen = outlen; + } + + return SECSuccess; +} + +SECStatus +blake2b_HashBuf(uint8_t* output, const uint8_t* input, uint8_t outlen, + size_t inlen, const uint8_t* key, size_t keylen) +{ + SECStatus rv = SECFailure; + BLAKE2BContext ctx = { { 0 } }; + + if (inlen != 0) { + PORT_Assert(input != NULL); + if (input == NULL) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + goto done; + } + } + + PORT_Assert(output != NULL); + if (output == NULL) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + goto done; + } + + if (blake2b_Begin(&ctx, outlen, key, keylen) != SECSuccess) { + goto done; + } + + if (BLAKE2B_Update(&ctx, input, inlen) != SECSuccess) { + goto done; + } + + if (BLAKE2B_End(&ctx, output, NULL, outlen) != SECSuccess) { + goto done; + } + rv = SECSuccess; + +done: + PORT_Memset(&ctx, 0, sizeof ctx); + return rv; +} + +SECStatus +BLAKE2B_Hash(unsigned char* dest, const char* src) +{ + return blake2b_HashBuf(dest, (const unsigned char*)src, BLAKE2B512_LENGTH, + PORT_Strlen(src), NULL, 0); +} + +SECStatus +BLAKE2B_HashBuf(unsigned char* output, const unsigned char* input, PRUint32 inlen) +{ + return blake2b_HashBuf(output, input, BLAKE2B512_LENGTH, inlen, NULL, 0); +} + +SECStatus +BLAKE2B_MAC_HashBuf(unsigned char* output, const unsigned char* input, + unsigned int inlen, const unsigned char* key, + unsigned int keylen) +{ + PORT_Assert(key != NULL); + if (!key && keylen <= BLAKE2B_KEY_SIZE) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + return blake2b_HashBuf(output, input, BLAKE2B512_LENGTH, inlen, key, keylen); +} + +unsigned int +BLAKE2B_FlattenSize(BLAKE2BContext* ctx) +{ + return sizeof(BLAKE2BContext); +} + +SECStatus +BLAKE2B_Flatten(BLAKE2BContext* ctx, unsigned char* space) +{ + PORT_Assert(space != NULL); + if (!space) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + PORT_Memcpy(space, ctx, sizeof(BLAKE2BContext)); + return SECSuccess; +} + +BLAKE2BContext* +BLAKE2B_Resurrect(unsigned char* space, void* arg) +{ + PORT_Assert(space != NULL); + if (!space) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return NULL; + } + BLAKE2BContext* ctx = BLAKE2B_NewContext(); + if (ctx == NULL) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return NULL; + } + + PORT_Memcpy(ctx, space, sizeof(BLAKE2BContext)); + return ctx; +} + +void +BLAKE2B_Clone(BLAKE2BContext* dest, BLAKE2BContext* src) +{ + PORT_Assert(dest != NULL); + PORT_Assert(src != NULL); + if (!dest || !src) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return; + } + PORT_Memcpy(dest, src, sizeof(BLAKE2BContext)); +} diff --git a/security/nss/lib/freebl/blake2b.h b/security/nss/lib/freebl/blake2b.h new file mode 100644 index 000000000..d19a49f0e --- /dev/null +++ b/security/nss/lib/freebl/blake2b.h @@ -0,0 +1,23 @@ +/* + * blake2b.h - header file for blake2b hash function + * + * 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 BLAKE_H +#define BLAKE_H + +#include <stddef.h> +#include <stdint.h> + +struct Blake2bContextStr { + uint64_t h[8]; /* chained state */ + uint64_t t[2]; /* total number of bytes */ + uint64_t f; /* last block flag */ + uint8_t buf[BLAKE2B_BLOCK_LENGTH]; /* input buffer */ + size_t buflen; /* size of remaining bytes in buf */ + size_t outlen; /* digest size */ +}; + +#endif /* BLAKE_H */ diff --git a/security/nss/lib/freebl/blapi.h b/security/nss/lib/freebl/blapi.h index 31e471ac4..ca2149972 100644 --- a/security/nss/lib/freebl/blapi.h +++ b/security/nss/lib/freebl/blapi.h @@ -1402,6 +1402,84 @@ TLS_P_hash(HASH_HashType hashAlg, const SECItem *secret, const char *label, /******************************************/ /* +** Implements the Blake2b hash function. +*/ + +/* +** Hash a null terminated string "src" into "dest" using Blake2b +*/ +extern SECStatus BLAKE2B_Hash(unsigned char *dest, const char *src); + +/* +** Hash a non-null terminated string "src" into "dest" using Blake2b +*/ +extern SECStatus BLAKE2B_HashBuf(unsigned char *output, + const unsigned char *input, PRUint32 inlen); + +extern SECStatus BLAKE2B_MAC_HashBuf(unsigned char *output, + const unsigned char *input, + unsigned int inlen, + const unsigned char *key, + unsigned int keylen); + +/* +** Create a new Blake2b context +*/ +extern BLAKE2BContext *BLAKE2B_NewContext(); + +/* +** Destroy a Blake2b secure hash context. +** "ctx" the context +** "freeit" if PR_TRUE then free the object as well as its sub-objects +*/ +extern void BLAKE2B_DestroyContext(BLAKE2BContext *ctx, PRBool freeit); + +/* +** Reset a Blake2b context, preparing it for a fresh round of hashing +*/ +extern SECStatus BLAKE2B_Begin(BLAKE2BContext *ctx); + +extern SECStatus BLAKE2B_MAC_Begin(BLAKE2BContext *ctx, const PRUint8 *key, + const size_t keylen); + +/* +** Update the Blake hash function with more data. +*/ +extern SECStatus BLAKE2B_Update(BLAKE2BContext *ctx, const unsigned char *in, + unsigned int inlen); + +/* +** Finish the Blake hash function. Produce the digested results in "digest" +*/ +extern SECStatus BLAKE2B_End(BLAKE2BContext *ctx, unsigned char *out, + unsigned int *digestLen, size_t maxDigestLen); + +/* + * Return the size of a buffer needed to flatten the Blake2b Context into + * "ctx" the context + * returns size; + */ +extern unsigned int BLAKE2B_FlattenSize(BLAKE2BContext *ctx); + +/* + * Flatten the Blake2b Context into a buffer: + * "ctx" the context + * "space" the buffer to flatten to + * returns status; + */ +extern SECStatus BLAKE2B_Flatten(BLAKE2BContext *ctx, unsigned char *space); + +/* + * Resurrect a flattened context into a Blake2b Context + * "space" the buffer of the flattend buffer + * "arg" ptr to void used by cryptographic resurrect + * returns resurected context + */ +extern BLAKE2BContext *BLAKE2B_Resurrect(unsigned char *space, void *arg); +extern void BLAKE2B_Clone(BLAKE2BContext *dest, BLAKE2BContext *src); + +/******************************************/ +/* ** Pseudo Random Number Generation. FIPS compliance desirable. */ diff --git a/security/nss/lib/freebl/blapii.h b/security/nss/lib/freebl/blapii.h index b1be7bedf..743a1168b 100644 --- a/security/nss/lib/freebl/blapii.h +++ b/security/nss/lib/freebl/blapii.h @@ -22,8 +22,10 @@ typedef void (*freeblDestroyFunc)(void *cx, PRBool freeit); SEC_BEGIN_PROTOS +#ifndef NSS_FIPS_DISABLED SECStatus BL_FIPSEntryOK(PRBool freeblOnly); PRBool BL_POSTRan(PRBool freeblOnly); +#endif #if defined(XP_UNIX) && !defined(NO_FORK_CHECK) @@ -78,5 +80,11 @@ SECStatus generate_prime(mp_int *prime, int primeLen); PRBool aesni_support(); PRBool clmul_support(); PRBool avx_support(); +PRBool ssse3_support(); +PRBool arm_neon_support(); +PRBool arm_aes_support(); +PRBool arm_pmull_support(); +PRBool arm_sha1_support(); +PRBool arm_sha2_support(); #endif /* _BLAPII_H_ */ diff --git a/security/nss/lib/freebl/blapit.h b/security/nss/lib/freebl/blapit.h index 2a17b5f46..c718c6f27 100644 --- a/security/nss/lib/freebl/blapit.h +++ b/security/nss/lib/freebl/blapit.h @@ -91,25 +91,27 @@ typedef int __BLAPI_DEPRECATED __attribute__((deprecated)); /* * Number of bytes each hash algorithm produces */ -#define MD2_LENGTH 16 /* Bytes */ -#define MD5_LENGTH 16 /* Bytes */ -#define SHA1_LENGTH 20 /* Bytes */ -#define SHA256_LENGTH 32 /* bytes */ -#define SHA384_LENGTH 48 /* bytes */ -#define SHA512_LENGTH 64 /* bytes */ +#define MD2_LENGTH 16 /* Bytes */ +#define MD5_LENGTH 16 /* Bytes */ +#define SHA1_LENGTH 20 /* Bytes */ +#define SHA256_LENGTH 32 /* bytes */ +#define SHA384_LENGTH 48 /* bytes */ +#define SHA512_LENGTH 64 /* bytes */ +#define BLAKE2B512_LENGTH 64 /* Bytes */ #define HASH_LENGTH_MAX SHA512_LENGTH /* * Input block size for each hash algorithm. */ -#define MD2_BLOCK_LENGTH 64 /* bytes */ -#define MD5_BLOCK_LENGTH 64 /* bytes */ -#define SHA1_BLOCK_LENGTH 64 /* bytes */ -#define SHA224_BLOCK_LENGTH 64 /* bytes */ -#define SHA256_BLOCK_LENGTH 64 /* bytes */ -#define SHA384_BLOCK_LENGTH 128 /* bytes */ -#define SHA512_BLOCK_LENGTH 128 /* bytes */ +#define MD2_BLOCK_LENGTH 64 /* bytes */ +#define MD5_BLOCK_LENGTH 64 /* bytes */ +#define SHA1_BLOCK_LENGTH 64 /* bytes */ +#define SHA224_BLOCK_LENGTH 64 /* bytes */ +#define SHA256_BLOCK_LENGTH 64 /* bytes */ +#define SHA384_BLOCK_LENGTH 128 /* bytes */ +#define SHA512_BLOCK_LENGTH 128 /* bytes */ +#define BLAKE2B_BLOCK_LENGTH 128 /* Bytes */ #define HASH_BLOCK_LENGTH_MAX SHA512_BLOCK_LENGTH #define AES_KEY_WRAP_IV_BYTES 8 @@ -127,6 +129,8 @@ typedef int __BLAPI_DEPRECATED __attribute__((deprecated)); #define NSS_FREEBL_DEFAULT_CHUNKSIZE 2048 +#define BLAKE2B_KEY_SIZE 64 + /* * These values come from the initial key size limits from the PKCS #11 * module. They may be arbitrarily adjusted to any value freebl supports. @@ -213,6 +217,7 @@ struct SHA512ContextStr; struct AESKeyWrapContextStr; struct SEEDContextStr; struct ChaCha20Poly1305ContextStr; +struct Blake2bContextStr; typedef struct DESContextStr DESContext; typedef struct RC2ContextStr RC2Context; @@ -232,6 +237,7 @@ typedef struct SHA512ContextStr SHA384Context; typedef struct AESKeyWrapContextStr AESKeyWrapContext; typedef struct SEEDContextStr SEEDContext; typedef struct ChaCha20Poly1305ContextStr ChaCha20Poly1305Context; +typedef struct Blake2bContextStr BLAKE2BContext; /*************************************************************************** ** RSA Public and Private Key structures diff --git a/security/nss/lib/freebl/blinit.c b/security/nss/lib/freebl/blinit.c index d7f2ec53a..f369e62e7 100644 --- a/security/nss/lib/freebl/blinit.c +++ b/security/nss/lib/freebl/blinit.c @@ -23,6 +23,12 @@ static PRCallOnceType coFreeblInit; static PRBool aesni_support_ = PR_FALSE; static PRBool clmul_support_ = PR_FALSE; static PRBool avx_support_ = PR_FALSE; +static PRBool ssse3_support_ = PR_FALSE; +static PRBool arm_neon_support_ = PR_FALSE; +static PRBool arm_aes_support_ = PR_FALSE; +static PRBool arm_sha1_support_ = PR_FALSE; +static PRBool arm_sha2_support_ = PR_FALSE; +static PRBool arm_pmull_support_ = PR_FALSE; #ifdef NSS_X86_OR_X64 /* @@ -62,6 +68,7 @@ check_xcr0_ymm() #define ECX_XSAVE (1 << 26) #define ECX_OSXSAVE (1 << 27) #define ECX_AVX (1 << 28) +#define ECX_SSSE3 (1 << 9) #define AVX_BITS (ECX_XSAVE | ECX_OSXSAVE | ECX_AVX) void @@ -71,6 +78,7 @@ CheckX86CPUSupport() char *disable_hw_aes = PR_GetEnvSecure("NSS_DISABLE_HW_AES"); char *disable_pclmul = PR_GetEnvSecure("NSS_DISABLE_PCLMUL"); char *disable_avx = PR_GetEnvSecure("NSS_DISABLE_AVX"); + char *disable_ssse3 = PR_GetEnvSecure("NSS_DISABLE_SSSE3"); freebl_cpuid(1, &eax, &ebx, &ecx, &edx); aesni_support_ = (PRBool)((ecx & ECX_AESNI) != 0 && disable_hw_aes == NULL); clmul_support_ = (PRBool)((ecx & ECX_CLMUL) != 0 && disable_pclmul == NULL); @@ -78,9 +86,131 @@ CheckX86CPUSupport() * as well as XMM and YMM state. */ avx_support_ = (PRBool)((ecx & AVX_BITS) == AVX_BITS) && check_xcr0_ymm() && disable_avx == NULL; + ssse3_support_ = (PRBool)((ecx & ECX_SSSE3) != 0 && + disable_ssse3 == NULL); } #endif /* NSS_X86_OR_X64 */ +/* clang-format off */ +#if (defined(__aarch64__) || defined(__arm__)) && !defined(__ANDROID__) +#ifndef __has_include +#define __has_include(x) 0 +#endif +#if (__has_include(<sys/auxv.h>) || defined(__linux__)) && \ + defined(__GNUC__) && __GNUC__ >= 2 && defined(__ELF__) +#include <sys/auxv.h> +extern unsigned long getauxval(unsigned long type) __attribute__((weak)); +#else +static unsigned long (*getauxval)(unsigned long) = NULL; +#define AT_HWCAP2 0 +#define AT_HWCAP 0 +#endif /* defined(__GNUC__) && __GNUC__ >= 2 && defined(__ELF__)*/ +#endif /* (defined(__aarch64__) || defined(__arm__)) && !defined(__ANDROID__) */ +/* clang-format on */ + +#if defined(__aarch64__) && !defined(__ANDROID__) +// Defines from hwcap.h in Linux kernel - ARM64 +#ifndef HWCAP_AES +#define HWCAP_AES (1 << 3) +#endif +#ifndef HWCAP_PMULL +#define HWCAP_PMULL (1 << 4) +#endif +#ifndef HWCAP_SHA1 +#define HWCAP_SHA1 (1 << 5) +#endif +#ifndef HWCAP_SHA2 +#define HWCAP_SHA2 (1 << 6) +#endif + +void +CheckARMSupport() +{ + char *disable_arm_neon = PR_GetEnvSecure("NSS_DISABLE_ARM_NEON"); + char *disable_hw_aes = PR_GetEnvSecure("NSS_DISABLE_HW_AES"); + if (getauxval) { + long hwcaps = getauxval(AT_HWCAP); + arm_aes_support_ = hwcaps & HWCAP_AES && disable_hw_aes == NULL; + arm_pmull_support_ = hwcaps & HWCAP_PMULL; + arm_sha1_support_ = hwcaps & HWCAP_SHA1; + arm_sha2_support_ = hwcaps & HWCAP_SHA2; + } + /* aarch64 must support NEON. */ + arm_neon_support_ = disable_arm_neon == NULL; +} +#endif /* defined(__aarch64__) && !defined(__ANDROID__) */ + +#if defined(__arm__) && !defined(__ANDROID__) +// Defines from hwcap.h in Linux kernel - ARM +/* + * HWCAP flags - for elf_hwcap (in kernel) and AT_HWCAP + */ +#ifndef HWCAP_NEON +#define HWCAP_NEON (1 << 12) +#endif + +/* + * HWCAP2 flags - for elf_hwcap2 (in kernel) and AT_HWCAP2 + */ +#ifndef HWCAP2_AES +#define HWCAP2_AES (1 << 0) +#endif +#ifndef HWCAP2_PMULL +#define HWCAP2_PMULL (1 << 1) +#endif +#ifndef HWCAP2_SHA1 +#define HWCAP2_SHA1 (1 << 2) +#endif +#ifndef HWCAP2_SHA2 +#define HWCAP2_SHA2 (1 << 3) +#endif + +void +CheckARMSupport() +{ + char *disable_arm_neon = PR_GetEnvSecure("NSS_DISABLE_ARM_NEON"); + char *disable_hw_aes = PR_GetEnvSecure("NSS_DISABLE_HW_AES"); + if (getauxval) { + long hwcaps = getauxval(AT_HWCAP2); + arm_aes_support_ = hwcaps & HWCAP2_AES && disable_hw_aes == NULL; + arm_pmull_support_ = hwcaps & HWCAP2_PMULL; + arm_sha1_support_ = hwcaps & HWCAP2_SHA1; + arm_sha2_support_ = hwcaps & HWCAP2_SHA2; + arm_neon_support_ = hwcaps & HWCAP_NEON && disable_arm_neon == NULL; + } +} +#endif /* defined(__arm__) && !defined(__ANDROID__) */ + +// Enable when Firefox can use it. +// #if defined(__ANDROID__) && (defined(__arm__) || defined(__aarch64__)) +// #include <cpu-features.h> +// void +// CheckARMSupport() +// { +// char *disable_arm_neon = PR_GetEnvSecure("NSS_DISABLE_ARM_NEON"); +// char *disable_hw_aes = PR_GetEnvSecure("NSS_DISABLE_HW_AES"); +// AndroidCpuFamily family = android_getCpuFamily(); +// uint64_t features = android_getCpuFeatures(); +// if (family == ANDROID_CPU_FAMILY_ARM64) { +// arm_aes_support_ = features & ANDROID_CPU_ARM64_FEATURE_AES && +// disable_hw_aes == NULL; +// arm_pmull_support_ = features & ANDROID_CPU_ARM64_FEATURE_PMULL; +// arm_sha1_support_ = features & ANDROID_CPU_ARM64_FEATURE_SHA1; +// arm_sha2_support_ = features & ANDROID_CPU_ARM64_FEATURE_SHA2; +// arm_neon_support_ = disable_arm_neon == NULL; +// } +// if (family == ANDROID_CPU_FAMILY_ARM) { +// arm_aes_support_ = features & ANDROID_CPU_ARM_FEATURE_AES && +// disable_hw_aes == NULL; +// arm_pmull_support_ = features & ANDROID_CPU_ARM_FEATURE_PMULL; +// arm_sha1_support_ = features & ANDROID_CPU_ARM_FEATURE_SHA1; +// arm_sha2_support_ = features & ANDROID_CPU_ARM_FEATURE_SHA2; +// arm_neon_support_ = hwcaps & ANDROID_CPU_ARM_FEATURE_NEON && +// disable_arm_neon == NULL; +// } +// } +// #endif /* defined(__ANDROID__) && (defined(__arm__) || defined(__aarch64__)) */ + PRBool aesni_support() { @@ -96,12 +226,44 @@ avx_support() { return avx_support_; } +PRBool +ssse3_support() +{ + return ssse3_support_; +} +PRBool +arm_neon_support() +{ + return arm_neon_support_; +} +PRBool +arm_aes_support() +{ + return arm_aes_support_; +} +PRBool +arm_pmull_support() +{ + return arm_pmull_support_; +} +PRBool +arm_sha1_support() +{ + return arm_sha1_support_; +} +PRBool +arm_sha2_support() +{ + return arm_sha2_support_; +} static PRStatus FreeblInit(void) { #ifdef NSS_X86_OR_X64 CheckX86CPUSupport(); +#elif (defined(__aarch64__) || defined(__arm__)) && !defined(__ANDROID__) + CheckARMSupport(); #endif return PR_SUCCESS; } diff --git a/security/nss/lib/freebl/chacha20.c b/security/nss/lib/freebl/chacha20.c deleted file mode 100644 index f55d1e670..000000000 --- a/security/nss/lib/freebl/chacha20.c +++ /dev/null @@ -1,119 +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/. */ - -/* Adopted from the public domain code in NaCl by djb. */ - -#include <string.h> -#include <stdio.h> - -#include "prtypes.h" -#include "secport.h" -#include "chacha20.h" - -#if defined(_MSC_VER) -#pragma intrinsic(_lrotl) -#define ROTL32(x, n) _lrotl(x, n) -#else -#define ROTL32(x, n) ((x << n) | (x >> ((8 * sizeof x) - n))) -#endif - -#define ROTATE(v, c) ROTL32((v), (c)) - -#define U32TO8_LITTLE(p, v) \ - { \ - (p)[0] = ((v)) & 0xff; \ - (p)[1] = ((v) >> 8) & 0xff; \ - (p)[2] = ((v) >> 16) & 0xff; \ - (p)[3] = ((v) >> 24) & 0xff; \ - } -#define U8TO32_LITTLE(p) \ - (((PRUint32)((p)[0])) | ((PRUint32)((p)[1]) << 8) | \ - ((PRUint32)((p)[2]) << 16) | ((PRUint32)((p)[3]) << 24)) - -#define QUARTERROUND(x, a, b, c, d) \ - x[a] = x[a] + x[b]; \ - x[d] = ROTATE(x[d] ^ x[a], 16); \ - x[c] = x[c] + x[d]; \ - x[b] = ROTATE(x[b] ^ x[c], 12); \ - x[a] = x[a] + x[b]; \ - x[d] = ROTATE(x[d] ^ x[a], 8); \ - x[c] = x[c] + x[d]; \ - x[b] = ROTATE(x[b] ^ x[c], 7); - -static void -ChaChaCore(unsigned char output[64], const PRUint32 input[16], int num_rounds) -{ - PRUint32 x[16]; - int i; - - PORT_Memcpy(x, input, sizeof(PRUint32) * 16); - for (i = num_rounds; i > 0; i -= 2) { - QUARTERROUND(x, 0, 4, 8, 12) - QUARTERROUND(x, 1, 5, 9, 13) - QUARTERROUND(x, 2, 6, 10, 14) - QUARTERROUND(x, 3, 7, 11, 15) - QUARTERROUND(x, 0, 5, 10, 15) - QUARTERROUND(x, 1, 6, 11, 12) - QUARTERROUND(x, 2, 7, 8, 13) - QUARTERROUND(x, 3, 4, 9, 14) - } - - for (i = 0; i < 16; ++i) { - x[i] = x[i] + input[i]; - } - for (i = 0; i < 16; ++i) { - U32TO8_LITTLE(output + 4 * i, x[i]); - } -} - -static const unsigned char sigma[16] = "expand 32-byte k"; - -void -ChaCha20XOR(unsigned char *out, const unsigned char *in, unsigned int inLen, - const unsigned char key[32], const unsigned char nonce[12], - uint32_t counter) -{ - unsigned char block[64]; - PRUint32 input[16]; - unsigned int i; - - input[4] = U8TO32_LITTLE(key + 0); - input[5] = U8TO32_LITTLE(key + 4); - input[6] = U8TO32_LITTLE(key + 8); - input[7] = U8TO32_LITTLE(key + 12); - - input[8] = U8TO32_LITTLE(key + 16); - input[9] = U8TO32_LITTLE(key + 20); - input[10] = U8TO32_LITTLE(key + 24); - input[11] = U8TO32_LITTLE(key + 28); - - input[0] = U8TO32_LITTLE(sigma + 0); - input[1] = U8TO32_LITTLE(sigma + 4); - input[2] = U8TO32_LITTLE(sigma + 8); - input[3] = U8TO32_LITTLE(sigma + 12); - - input[12] = counter; - input[13] = U8TO32_LITTLE(nonce + 0); - input[14] = U8TO32_LITTLE(nonce + 4); - input[15] = U8TO32_LITTLE(nonce + 8); - - while (inLen >= 64) { - ChaChaCore(block, input, 20); - for (i = 0; i < 64; i++) { - out[i] = in[i] ^ block[i]; - } - - input[12]++; - inLen -= 64; - in += 64; - out += 64; - } - - if (inLen > 0) { - ChaChaCore(block, input, 20); - for (i = 0; i < inLen; i++) { - out[i] = in[i] ^ block[i]; - } - } -} diff --git a/security/nss/lib/freebl/chacha20.h b/security/nss/lib/freebl/chacha20.h deleted file mode 100644 index 7e396fa8c..000000000 --- a/security/nss/lib/freebl/chacha20.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * chacha20.h - header file for ChaCha20 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_CHACHA20_H_ -#define FREEBL_CHACHA20_H_ - -#if defined(_MSC_VER) && _MSC_VER < 1600 -#include "prtypes.h" -typedef PRUint32 uint32_t; -typedef PRUint64 uint64_t; -#else -#include <stdint.h> -#endif - -/* ChaCha20XOR encrypts |inLen| bytes from |in| with the given key and - * nonce and writes the result to |out|, which may be equal to |in|. The - * initial block counter is specified by |counter|. */ -extern void ChaCha20XOR(unsigned char *out, const unsigned char *in, - unsigned int inLen, const unsigned char key[32], - const unsigned char nonce[12], uint32_t counter); - -#endif /* FREEBL_CHACHA20_H_ */ diff --git a/security/nss/lib/freebl/chacha20_vec.c b/security/nss/lib/freebl/chacha20_vec.c deleted file mode 100644 index 12f94d897..000000000 --- a/security/nss/lib/freebl/chacha20_vec.c +++ /dev/null @@ -1,327 +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 is by Ted Krovetz and was submitted to SUPERCOP and - * marked as public domain. It was been altered to allow for non-aligned inputs - * and to allow the block counter to be passed in specifically. */ - -#include <string.h> - -#include "chacha20.h" -#include "blapii.h" - -#ifndef CHACHA_RNDS -#define CHACHA_RNDS 20 /* 8 (high speed), 20 (conservative), 12 (middle) */ -#endif - -/* Architecture-neutral way to specify 16-byte vector of ints */ -typedef unsigned vec __attribute__((vector_size(16))); - -/* This implementation is designed for Neon, SSE and AltiVec machines. The - * following specify how to do certain vector operations efficiently on - * each architecture, using intrinsics. - * This implementation supports parallel processing of multiple blocks, - * including potentially using general-purpose registers. - */ -#if __ARM_NEON__ -#include <arm_neon.h> -#define GPR_TOO 1 -#define VBPI 2 -#define ONE (vec) vsetq_lane_u32(1, vdupq_n_u32(0), 0) -#define LOAD(m) (vec)(*((vec *)(m))) -#define STORE(m, r) (*((vec *)(m))) = (r) -#define ROTV1(x) (vec) vextq_u32((uint32x4_t)x, (uint32x4_t)x, 1) -#define ROTV2(x) (vec) vextq_u32((uint32x4_t)x, (uint32x4_t)x, 2) -#define ROTV3(x) (vec) vextq_u32((uint32x4_t)x, (uint32x4_t)x, 3) -#define ROTW16(x) (vec) vrev32q_u16((uint16x8_t)x) -#if __clang__ -#define ROTW7(x) (x << ((vec){ 7, 7, 7, 7 })) ^ (x >> ((vec){ 25, 25, 25, 25 })) -#define ROTW8(x) (x << ((vec){ 8, 8, 8, 8 })) ^ (x >> ((vec){ 24, 24, 24, 24 })) -#define ROTW12(x) (x << ((vec){ 12, 12, 12, 12 })) ^ (x >> ((vec){ 20, 20, 20, 20 })) -#else -#define ROTW7(x) (vec) vsriq_n_u32(vshlq_n_u32((uint32x4_t)x, 7), (uint32x4_t)x, 25) -#define ROTW8(x) (vec) vsriq_n_u32(vshlq_n_u32((uint32x4_t)x, 8), (uint32x4_t)x, 24) -#define ROTW12(x) (vec) vsriq_n_u32(vshlq_n_u32((uint32x4_t)x, 12), (uint32x4_t)x, 20) -#endif -#elif __SSE2__ -#include <emmintrin.h> -#define GPR_TOO 0 -#if __clang__ -#define VBPI 4 -#else -#define VBPI 3 -#endif -#define ONE (vec) _mm_set_epi32(0, 0, 0, 1) -#define LOAD(m) (vec) _mm_loadu_si128((__m128i *)(m)) -#define STORE(m, r) _mm_storeu_si128((__m128i *)(m), (__m128i)(r)) -#define ROTV1(x) (vec) _mm_shuffle_epi32((__m128i)x, _MM_SHUFFLE(0, 3, 2, 1)) -#define ROTV2(x) (vec) _mm_shuffle_epi32((__m128i)x, _MM_SHUFFLE(1, 0, 3, 2)) -#define ROTV3(x) (vec) _mm_shuffle_epi32((__m128i)x, _MM_SHUFFLE(2, 1, 0, 3)) -#define ROTW7(x) (vec)(_mm_slli_epi32((__m128i)x, 7) ^ _mm_srli_epi32((__m128i)x, 25)) -#define ROTW12(x) (vec)(_mm_slli_epi32((__m128i)x, 12) ^ _mm_srli_epi32((__m128i)x, 20)) -#if __SSSE3__ -#include <tmmintrin.h> -#define ROTW8(x) (vec) _mm_shuffle_epi8((__m128i)x, _mm_set_epi8(14, 13, 12, 15, 10, 9, 8, 11, 6, 5, 4, 7, 2, 1, 0, 3)) -#define ROTW16(x) (vec) _mm_shuffle_epi8((__m128i)x, _mm_set_epi8(13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2)) -#else -#define ROTW8(x) (vec)(_mm_slli_epi32((__m128i)x, 8) ^ _mm_srli_epi32((__m128i)x, 24)) -#define ROTW16(x) (vec)(_mm_slli_epi32((__m128i)x, 16) ^ _mm_srli_epi32((__m128i)x, 16)) -#endif -#else -#error-- Implementation supports only machines with neon or SSE2 -#endif - -#ifndef REVV_BE -#define REVV_BE(x) (x) -#endif - -#ifndef REVW_BE -#define REVW_BE(x) (x) -#endif - -#define BPI (VBPI + GPR_TOO) /* Blocks computed per loop iteration */ - -#define DQROUND_VECTORS(a, b, c, d) \ - a += b; \ - d ^= a; \ - d = ROTW16(d); \ - c += d; \ - b ^= c; \ - b = ROTW12(b); \ - a += b; \ - d ^= a; \ - d = ROTW8(d); \ - c += d; \ - b ^= c; \ - b = ROTW7(b); \ - b = ROTV1(b); \ - c = ROTV2(c); \ - d = ROTV3(d); \ - a += b; \ - d ^= a; \ - d = ROTW16(d); \ - c += d; \ - b ^= c; \ - b = ROTW12(b); \ - a += b; \ - d ^= a; \ - d = ROTW8(d); \ - c += d; \ - b ^= c; \ - b = ROTW7(b); \ - b = ROTV3(b); \ - c = ROTV2(c); \ - d = ROTV1(d); - -#define QROUND_WORDS(a, b, c, d) \ - a = a + b; \ - d ^= a; \ - d = d << 16 | d >> 16; \ - c = c + d; \ - b ^= c; \ - b = b << 12 | b >> 20; \ - a = a + b; \ - d ^= a; \ - d = d << 8 | d >> 24; \ - c = c + d; \ - b ^= c; \ - b = b << 7 | b >> 25; - -#define WRITE_XOR(in, op, d, v0, v1, v2, v3) \ - STORE(op + d + 0, LOAD(in + d + 0) ^ REVV_BE(v0)); \ - STORE(op + d + 4, LOAD(in + d + 4) ^ REVV_BE(v1)); \ - STORE(op + d + 8, LOAD(in + d + 8) ^ REVV_BE(v2)); \ - STORE(op + d + 12, LOAD(in + d + 12) ^ REVV_BE(v3)); - -void NO_SANITIZE_ALIGNMENT -ChaCha20XOR(unsigned char *out, const unsigned char *in, unsigned int inlen, - const unsigned char key[32], const unsigned char nonce[12], - uint32_t counter) -{ - unsigned iters, i, *op = (unsigned *)out, *ip = (unsigned *)in, *kp; -#if defined(__ARM_NEON__) - unsigned *np; -#endif - vec s0, s1, s2, s3; -#if !defined(__ARM_NEON__) && !defined(__SSE2__) - __attribute__((aligned(16))) unsigned key[8], nonce[4]; -#endif - __attribute__((aligned(16))) unsigned chacha_const[] = - { 0x61707865, 0x3320646E, 0x79622D32, 0x6B206574 }; -#if defined(__ARM_NEON__) || defined(__SSE2__) - kp = (unsigned *)key; -#else - ((vec *)key)[0] = REVV_BE(((vec *)key)[0]); - ((vec *)key)[1] = REVV_BE(((vec *)key)[1]); - ((unsigned *)nonce)[0] = REVW_BE(((unsigned *)nonce)[0]); - ((unsigned *)nonce)[1] = REVW_BE(((unsigned *)nonce)[1]); - ((unsigned *)nonce)[2] = REVW_BE(((unsigned *)nonce)[2]); - ((unsigned *)nonce)[3] = REVW_BE(((unsigned *)nonce)[3]); - kp = (unsigned *)key; - np = (unsigned *)nonce; -#endif -#if defined(__ARM_NEON__) - np = (unsigned *)nonce; -#endif - s0 = LOAD(chacha_const); - s1 = LOAD(&((vec *)kp)[0]); - s2 = LOAD(&((vec *)kp)[1]); - s3 = (vec){ - counter, - ((uint32_t *)nonce)[0], - ((uint32_t *)nonce)[1], - ((uint32_t *)nonce)[2] - }; - - for (iters = 0; iters < inlen / (BPI * 64); iters++) { -#if GPR_TOO - register unsigned x0, x1, x2, x3, x4, x5, x6, x7, x8, - x9, x10, x11, x12, x13, x14, x15; -#endif -#if VBPI > 2 - vec v8, v9, v10, v11; -#endif -#if VBPI > 3 - vec v12, v13, v14, v15; -#endif - - vec v0, v1, v2, v3, v4, v5, v6, v7; - v4 = v0 = s0; - v5 = v1 = s1; - v6 = v2 = s2; - v3 = s3; - v7 = v3 + ONE; -#if VBPI > 2 - v8 = v4; - v9 = v5; - v10 = v6; - v11 = v7 + ONE; -#endif -#if VBPI > 3 - v12 = v8; - v13 = v9; - v14 = v10; - v15 = v11 + ONE; -#endif -#if GPR_TOO - x0 = chacha_const[0]; - x1 = chacha_const[1]; - x2 = chacha_const[2]; - x3 = chacha_const[3]; - x4 = kp[0]; - x5 = kp[1]; - x6 = kp[2]; - x7 = kp[3]; - x8 = kp[4]; - x9 = kp[5]; - x10 = kp[6]; - x11 = kp[7]; - x12 = counter + BPI * iters + (BPI - 1); - x13 = np[0]; - x14 = np[1]; - x15 = np[2]; -#endif - for (i = CHACHA_RNDS / 2; i; i--) { - DQROUND_VECTORS(v0, v1, v2, v3) - DQROUND_VECTORS(v4, v5, v6, v7) -#if VBPI > 2 - DQROUND_VECTORS(v8, v9, v10, v11) -#endif -#if VBPI > 3 - DQROUND_VECTORS(v12, v13, v14, v15) -#endif -#if GPR_TOO - QROUND_WORDS(x0, x4, x8, x12) - QROUND_WORDS(x1, x5, x9, x13) - QROUND_WORDS(x2, x6, x10, x14) - QROUND_WORDS(x3, x7, x11, x15) - QROUND_WORDS(x0, x5, x10, x15) - QROUND_WORDS(x1, x6, x11, x12) - QROUND_WORDS(x2, x7, x8, x13) - QROUND_WORDS(x3, x4, x9, x14) -#endif - } - - WRITE_XOR(ip, op, 0, v0 + s0, v1 + s1, v2 + s2, v3 + s3) - s3 += ONE; - WRITE_XOR(ip, op, 16, v4 + s0, v5 + s1, v6 + s2, v7 + s3) - s3 += ONE; -#if VBPI > 2 - WRITE_XOR(ip, op, 32, v8 + s0, v9 + s1, v10 + s2, v11 + s3) - s3 += ONE; -#endif -#if VBPI > 3 - WRITE_XOR(ip, op, 48, v12 + s0, v13 + s1, v14 + s2, v15 + s3) - s3 += ONE; -#endif - ip += VBPI * 16; - op += VBPI * 16; -#if GPR_TOO - op[0] = REVW_BE(REVW_BE(ip[0]) ^ (x0 + chacha_const[0])); - op[1] = REVW_BE(REVW_BE(ip[1]) ^ (x1 + chacha_const[1])); - op[2] = REVW_BE(REVW_BE(ip[2]) ^ (x2 + chacha_const[2])); - op[3] = REVW_BE(REVW_BE(ip[3]) ^ (x3 + chacha_const[3])); - op[4] = REVW_BE(REVW_BE(ip[4]) ^ (x4 + kp[0])); - op[5] = REVW_BE(REVW_BE(ip[5]) ^ (x5 + kp[1])); - op[6] = REVW_BE(REVW_BE(ip[6]) ^ (x6 + kp[2])); - op[7] = REVW_BE(REVW_BE(ip[7]) ^ (x7 + kp[3])); - op[8] = REVW_BE(REVW_BE(ip[8]) ^ (x8 + kp[4])); - op[9] = REVW_BE(REVW_BE(ip[9]) ^ (x9 + kp[5])); - op[10] = REVW_BE(REVW_BE(ip[10]) ^ (x10 + kp[6])); - op[11] = REVW_BE(REVW_BE(ip[11]) ^ (x11 + kp[7])); - op[12] = REVW_BE(REVW_BE(ip[12]) ^ (x12 + counter + BPI * iters + (BPI - 1))); - op[13] = REVW_BE(REVW_BE(ip[13]) ^ (x13 + np[0])); - op[14] = REVW_BE(REVW_BE(ip[14]) ^ (x14 + np[1])); - op[15] = REVW_BE(REVW_BE(ip[15]) ^ (x15 + np[2])); - s3 += ONE; - ip += 16; - op += 16; -#endif - } - - for (iters = inlen % (BPI * 64) / 64; iters != 0; iters--) { - vec v0 = s0, v1 = s1, v2 = s2, v3 = s3; - for (i = CHACHA_RNDS / 2; i; i--) { - DQROUND_VECTORS(v0, v1, v2, v3); - } - WRITE_XOR(ip, op, 0, v0 + s0, v1 + s1, v2 + s2, v3 + s3) - s3 += ONE; - ip += 16; - op += 16; - } - - inlen = inlen % 64; - if (inlen) { - __attribute__((aligned(16))) vec buf[4]; - vec v0, v1, v2, v3; - v0 = s0; - v1 = s1; - v2 = s2; - v3 = s3; - for (i = CHACHA_RNDS / 2; i; i--) { - DQROUND_VECTORS(v0, v1, v2, v3); - } - - if (inlen >= 16) { - STORE(op + 0, LOAD(ip + 0) ^ REVV_BE(v0 + s0)); - if (inlen >= 32) { - STORE(op + 4, LOAD(ip + 4) ^ REVV_BE(v1 + s1)); - if (inlen >= 48) { - STORE(op + 8, LOAD(ip + 8) ^ REVV_BE(v2 + s2)); - buf[3] = REVV_BE(v3 + s3); - } else { - buf[2] = REVV_BE(v2 + s2); - } - } else { - buf[1] = REVV_BE(v1 + s1); - } - } else { - buf[0] = REVV_BE(v0 + s0); - } - - for (i = inlen & ~15; i < inlen; i++) { - ((char *)op)[i] = ((char *)ip)[i] ^ ((char *)buf)[i]; - } - } -} diff --git a/security/nss/lib/freebl/chacha20poly1305.c b/security/nss/lib/freebl/chacha20poly1305.c index cd265e1ff..859d05316 100644 --- a/security/nss/lib/freebl/chacha20poly1305.c +++ b/security/nss/lib/freebl/chacha20poly1305.c @@ -12,16 +12,69 @@ #include "seccomon.h" #include "secerr.h" #include "blapit.h" +#include "blapii.h" #ifndef NSS_DISABLE_CHACHAPOLY -#include "poly1305.h" -#include "chacha20.h" #include "chacha20poly1305.h" -#endif +// Forward declaration from "Hacl_Chacha20_Vec128.h". +extern void Hacl_Chacha20_Vec128_chacha20(uint8_t *output, uint8_t *plain, + uint32_t len, uint8_t *k, uint8_t *n1, + uint32_t ctr); +// Forward declaration from "Hacl_Chacha20.h". +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|. */ -#ifndef NSS_DISABLE_CHACHAPOLY +#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" + +static void +Poly1305PadUpdate(Hacl_Impl_Poly1305_64_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)); + if (pRemLen > 0) { + memcpy(block, p + (pLen - pRemLen), pRemLen); + Hacl_Poly1305_64_update(state, block, 1); + } +} + +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); + + unsigned char block[16] = { 0 }; + Hacl_Poly1305_64_init(state, (uint8_t *)key); + + Poly1305PadUpdate(state, block, ad, adLen); + memset(block, 0, 16); + Poly1305PadUpdate(state, block, ciphertext, ciphertextLen); + + unsigned int i; + unsigned int j; + for (i = 0, j = adLen; i < 8; i++, j >>= 8) { + block[i] = j; + } + for (i = 8, j = ciphertextLen; i < 16; i++, j >>= 8) { + block[i] = j; + } + + Hacl_Poly1305_64_update(state, block, 1); + Hacl_Poly1305_64_finish(state, out, (uint8_t *)(key + 16)); +} +#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, @@ -56,7 +109,9 @@ Poly1305Do(unsigned char *out, const unsigned char *ad, unsigned int adLen, Poly1305Update(&state, lengthBytes, sizeof(lengthBytes)); Poly1305Finish(&state, out); } -#endif + +#endif /* HAVE_INT128_SUPPORT */ +#endif /* NSS_DISABLE_CHACHAPOLY */ SECStatus ChaCha20Poly1305_InitContext(ChaCha20Poly1305Context *ctx, @@ -116,6 +171,17 @@ ChaCha20Poly1305_DestroyContext(ChaCha20Poly1305Context *ctx, PRBool freeit) #endif } +void +ChaCha20Xor(uint8_t *output, uint8_t *block, uint32_t len, uint8_t *k, + uint8_t *nonce, uint32_t ctr) +{ + if (ssse3_support() || arm_neon_support()) { + Hacl_Chacha20_Vec128_chacha20(output, block, len, k, nonce, ctr); + } else { + Hacl_Chacha20_chacha20(output, block, len, k, nonce, ctr); + } +} + SECStatus ChaCha20Poly1305_Seal(const ChaCha20Poly1305Context *ctx, unsigned char *output, unsigned int *outputLen, unsigned int maxOutputLen, @@ -142,8 +208,10 @@ ChaCha20Poly1305_Seal(const ChaCha20Poly1305Context *ctx, unsigned char *output, PORT_Memset(block, 0, sizeof(block)); // Generate a block of keystream. The first 32 bytes will be the poly1305 // key. The remainder of the block is discarded. - ChaCha20XOR(block, block, sizeof(block), ctx->key, nonce, 0); - ChaCha20XOR(output, input, inputLen, ctx->key, nonce, 1); + ChaCha20Xor(block, (uint8_t *)block, sizeof(block), (uint8_t *)ctx->key, + (uint8_t *)nonce, 0); + ChaCha20Xor(output, (uint8_t *)input, inputLen, (uint8_t *)ctx->key, + (uint8_t *)nonce, 1); Poly1305Do(tag, ad, adLen, output, inputLen, block); PORT_Memcpy(output + inputLen, tag, ctx->tagLen); @@ -184,14 +252,16 @@ ChaCha20Poly1305_Open(const ChaCha20Poly1305Context *ctx, unsigned char *output, PORT_Memset(block, 0, sizeof(block)); // Generate a block of keystream. The first 32 bytes will be the poly1305 // key. The remainder of the block is discarded. - ChaCha20XOR(block, block, sizeof(block), ctx->key, nonce, 0); + ChaCha20Xor(block, (uint8_t *)block, sizeof(block), (uint8_t *)ctx->key, + (uint8_t *)nonce, 0); Poly1305Do(tag, ad, adLen, input, ciphertextLen, block); if (NSS_SecureMemcmp(tag, &input[ciphertextLen], ctx->tagLen) != 0) { PORT_SetError(SEC_ERROR_BAD_DATA); return SECFailure; } - ChaCha20XOR(output, input, ciphertextLen, ctx->key, nonce, 1); + ChaCha20Xor(output, (uint8_t *)input, ciphertextLen, (uint8_t *)ctx->key, + (uint8_t *)nonce, 1); return SECSuccess; #endif diff --git a/security/nss/lib/freebl/config.mk b/security/nss/lib/freebl/config.mk index 918a66363..7ac50db65 100644 --- a/security/nss/lib/freebl/config.mk +++ b/security/nss/lib/freebl/config.mk @@ -90,7 +90,12 @@ EXTRA_SHARED_LIBS += \ endif endif +ifeq (,$(filter-out DragonFly FreeBSD Linux NetBSD OpenBSD, $(OS_TARGET))) +CFLAGS += -std=gnu99 +endif + ifeq ($(OS_ARCH), Darwin) +CFLAGS += -std=gnu99 EXTRA_SHARED_LIBS += -dylib_file @executable_path/libplc4.dylib:$(DIST)/lib/libplc4.dylib -dylib_file @executable_path/libplds4.dylib:$(DIST)/lib/libplds4.dylib endif diff --git a/security/nss/lib/freebl/crypto_primitives.c b/security/nss/lib/freebl/crypto_primitives.c new file mode 100644 index 000000000..49c8ca5ca --- /dev/null +++ b/security/nss/lib/freebl/crypto_primitives.c @@ -0,0 +1,36 @@ +/* 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 FREEBL_NO_DEPEND +#include "stubs.h" +#endif + +/* This file holds useful functions and macros for crypto code. */ +#include "crypto_primitives.h" + +/* + * FREEBL_HTONLL(x): swap bytes in a 64-bit integer. + */ +#if defined(__GNUC__) && (defined(__x86_64__) || defined(__x86_64)) + +__inline__ PRUint64 +swap8b(PRUint64 value) +{ + __asm__("bswapq %0" + : "+r"(value)); + return (value); +} + +#elif !defined(_MSC_VER) + +PRUint64 +swap8b(PRUint64 x) +{ + PRUint64 t1 = x; + t1 = ((t1 & SHA_MASK8) << 8) | ((t1 >> 8) & SHA_MASK8); + t1 = ((t1 & SHA_MASK16) << 16) | ((t1 >> 16) & SHA_MASK16); + return (t1 >> 32) | (t1 << 32); +} + +#endif diff --git a/security/nss/lib/freebl/crypto_primitives.h b/security/nss/lib/freebl/crypto_primitives.h new file mode 100644 index 000000000..f19601f4b --- /dev/null +++ b/security/nss/lib/freebl/crypto_primitives.h @@ -0,0 +1,51 @@ +/* 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 file holds useful functions and macros for crypto code. */ + +#ifdef FREEBL_NO_DEPEND +#include "stubs.h" +#endif + +#include <stdlib.h> +#include "prtypes.h" + +/* Unfortunately this isn't always set when it should be. */ +#if defined(HAVE_LONG_LONG) + +/* + * ROTR64/ROTL64(x, n): rotate a 64-bit integer x by n bites to the right/left. + */ +#if defined(_MSC_VER) +#pragma intrinsic(_rotr64, _rotl64) +#define ROTR64(x, n) _rotr64((x), (n)) +#define ROTL64(x, n) _rotl64((x), (n)) +#else +#define ROTR64(x, n) (((x) >> (n)) | ((x) << (64 - (n)))) +#define ROTL64(x, n) (((x) << (n)) | ((x) >> (64 - (n)))) +#endif + +/* + * FREEBL_HTONLL(x): swap bytes in a 64-bit integer. + */ +#if defined(_MSC_VER) + +#pragma intrinsic(_byteswap_uint64) +#define FREEBL_HTONLL(x) _byteswap_uint64(x) + +#elif defined(__GNUC__) && (defined(__x86_64__) || defined(__x86_64)) + +PRUint64 swap8b(PRUint64 value); +#define FREEBL_HTONLL(x) swap8b(x) + +#else + +#define SHA_MASK16 0x0000FFFF0000FFFFULL +#define SHA_MASK8 0x00FF00FF00FF00FFULL +PRUint64 swap8b(PRUint64 x); +#define FREEBL_HTONLL(x) swap8b(x) + +#endif /* _MSC_VER */ + +#endif /* HAVE_LONG_LONG */
\ No newline at end of file diff --git a/security/nss/lib/freebl/det_rng.c b/security/nss/lib/freebl/det_rng.c index 04fce30e8..56be2d356 100644 --- a/security/nss/lib/freebl/det_rng.c +++ b/security/nss/lib/freebl/det_rng.c @@ -4,23 +4,26 @@ #include "blapi.h" #include "blapit.h" -#include "chacha20.h" +#include "Hacl_Chacha20.h" #include "nssilock.h" #include "seccomon.h" #include "secerr.h" +#include "prinit.h" #define GLOBAL_BYTES_SIZE 100 static PRUint8 globalBytes[GLOBAL_BYTES_SIZE]; static unsigned long globalNumCalls = 0; static PZLock *rng_lock = NULL; +static PRCallOnceType coRNGInit; +static const PRCallOnceType pristineCallOnce; -SECStatus -RNG_RNGInit(void) +static PRStatus +rng_init(void) { rng_lock = PZ_NewLock(nssILockOther); if (!rng_lock) { PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); - return SECFailure; + return PR_FAILURE; } /* --- LOCKED --- */ PZ_Lock(rng_lock); @@ -28,6 +31,17 @@ RNG_RNGInit(void) PZ_Unlock(rng_lock); /* --- UNLOCKED --- */ + return PR_SUCCESS; +} + +SECStatus +RNG_RNGInit(void) +{ + /* Allow only one call to initialize the context */ + if (PR_CallOnce(&coRNGInit, rng_init) != PR_SUCCESS) { + return SECFailure; + } + return SECSuccess; } @@ -85,7 +99,7 @@ RNG_GenerateGlobalRandomBytes(void *dest, size_t len) memset(dest, 0, len); memcpy(dest, globalBytes, PR_MIN(len, GLOBAL_BYTES_SIZE)); - ChaCha20XOR(dest, dest, len, key, nonce, 0); + Hacl_Chacha20_chacha20(dest, (uint8_t *)dest, len, (uint8_t *)key, nonce, 0); ChaCha20Poly1305_DestroyContext(cx, PR_TRUE); PZ_Unlock(rng_lock); @@ -97,8 +111,11 @@ RNG_GenerateGlobalRandomBytes(void *dest, size_t len) void RNG_RNGShutdown(void) { - PZ_DestroyLock(rng_lock); - rng_lock = NULL; + if (rng_lock) { + PZ_DestroyLock(rng_lock); + rng_lock = NULL; + } + coRNGInit = pristineCallOnce; } /* Test functions are not implemented! */ diff --git a/security/nss/lib/freebl/drbg.c b/security/nss/lib/freebl/drbg.c index 224bbe87d..70ae2618e 100644 --- a/security/nss/lib/freebl/drbg.c +++ b/security/nss/lib/freebl/drbg.c @@ -74,8 +74,7 @@ struct RNGContextStr { #define V_type V_Data[0] #define V(rng) (((rng)->V_Data) + 1) #define VSize(rng) ((sizeof(rng)->V_Data) - 1) - PRUint8 C[PRNG_SEEDLEN]; /* internal state variables */ - PRUint8 lastOutput[SHA256_LENGTH]; /* for continuous rng checking */ + PRUint8 C[PRNG_SEEDLEN]; /* internal state variables */ /* If we get calls for the PRNG to return less than the length of our * hash, we extend the request for a full hash (since we'll be doing * the full hash anyway). Future requests for random numbers are fulfilled @@ -286,7 +285,6 @@ prng_Hashgen(RNGContext *rng, PRUint8 *returned_bytes, { PRUint8 data[VSize(rng)]; PRUint8 thisHash[SHA256_LENGTH]; - PRUint8 *lastHash = rng->lastOutput; PORT_Memcpy(data, V(rng), VSize(rng)); while (no_of_returned_bytes) { @@ -297,15 +295,10 @@ prng_Hashgen(RNGContext *rng, PRUint8 *returned_bytes, SHA256_Begin(&ctx); SHA256_Update(&ctx, data, sizeof data); SHA256_End(&ctx, thisHash, &len, SHA256_LENGTH); - if (PORT_Memcmp(lastHash, thisHash, len) == 0) { - rng->isValid = PR_FALSE; - break; - } if (no_of_returned_bytes < SHA256_LENGTH) { len = no_of_returned_bytes; } PORT_Memcpy(returned_bytes, thisHash, len); - lastHash = returned_bytes; returned_bytes += len; no_of_returned_bytes -= len; /* The carry parameter is a bool (increment or not). @@ -313,7 +306,6 @@ prng_Hashgen(RNGContext *rng, PRUint8 *returned_bytes, carry = no_of_returned_bytes; PRNG_ADD_CARRY_ONLY(data, (sizeof data) - 1, carry); } - PORT_Memcpy(rng->lastOutput, thisHash, SHA256_LENGTH); PORT_Memset(data, 0, sizeof data); PORT_Memset(thisHash, 0, sizeof thisHash); } @@ -361,11 +353,6 @@ prng_generateNewBytes(RNGContext *rng, if (no_of_returned_bytes == SHA256_LENGTH) { /* short_cut to hashbuf and a couple of copies and clears */ SHA256_HashBuf(returned_bytes, V(rng), VSize(rng)); - /* continuous rng check */ - if (memcmp(rng->lastOutput, returned_bytes, SHA256_LENGTH) == 0) { - rng->isValid = PR_FALSE; - } - PORT_Memcpy(rng->lastOutput, returned_bytes, sizeof rng->lastOutput); } else { prng_Hashgen(rng, returned_bytes, no_of_returned_bytes); } diff --git a/security/nss/lib/freebl/ec.c b/security/nss/lib/freebl/ec.c index 669c9b147..b28815ade 100644 --- a/security/nss/lib/freebl/ec.c +++ b/security/nss/lib/freebl/ec.c @@ -15,8 +15,6 @@ #include "ec.h" #include "ecl.h" -#ifndef NSS_DISABLE_ECC - static const ECMethod kMethods[] = { { ECCurve25519, ec_Curve25519_pt_mul, @@ -183,7 +181,6 @@ cleanup: return rv; } -#endif /* NSS_DISABLE_ECC */ /* Generates a new EC key pair. The private key is a supplied * value and the public key is the result of performing a scalar @@ -194,7 +191,6 @@ ec_NewKey(ECParams *ecParams, ECPrivateKey **privKey, const unsigned char *privKeyBytes, int privKeyLen) { SECStatus rv = SECFailure; -#ifndef NSS_DISABLE_ECC PLArenaPool *arena; ECPrivateKey *key; mp_int k; @@ -309,9 +305,6 @@ cleanup: printf("ec_NewKey returning %s\n", (rv == SECSuccess) ? "success" : "failure"); #endif -#else - PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG); -#endif /* NSS_DISABLE_ECC */ return rv; } @@ -326,15 +319,10 @@ EC_NewKeyFromSeed(ECParams *ecParams, ECPrivateKey **privKey, const unsigned char *seed, int seedlen) { SECStatus rv = SECFailure; -#ifndef NSS_DISABLE_ECC rv = ec_NewKey(ecParams, privKey, seed, seedlen); -#else - PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG); -#endif /* NSS_DISABLE_ECC */ return rv; } -#ifndef NSS_DISABLE_ECC /* Generate a random private key using the algorithm A.4.1 of ANSI X9.62, * modified a la FIPS 186-2 Change Notice 1 to eliminate the bias in the * random number generator. @@ -391,7 +379,6 @@ cleanup: } return privKeyBytes; } -#endif /* NSS_DISABLE_ECC */ /* Generates a new EC key pair. The private key is a random value and * the public key is the result of performing a scalar point multiplication @@ -401,7 +388,6 @@ SECStatus EC_NewKey(ECParams *ecParams, ECPrivateKey **privKey) { SECStatus rv = SECFailure; -#ifndef NSS_DISABLE_ECC int len; unsigned char *privKeyBytes = NULL; @@ -425,9 +411,6 @@ cleanup: printf("EC_NewKey returning %s\n", (rv == SECSuccess) ? "success" : "failure"); #endif -#else - PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG); -#endif /* NSS_DISABLE_ECC */ return rv; } @@ -441,7 +424,6 @@ cleanup: SECStatus EC_ValidatePublicKey(ECParams *ecParams, SECItem *publicValue) { -#ifndef NSS_DISABLE_ECC mp_int Px, Py; ECGroup *group = NULL; SECStatus rv = SECFailure; @@ -525,10 +507,6 @@ cleanup: rv = SECFailure; } return rv; -#else - PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG); - return SECFailure; -#endif /* NSS_DISABLE_ECC */ } /* @@ -549,7 +527,6 @@ ECDH_Derive(SECItem *publicValue, SECItem *derivedSecret) { SECStatus rv = SECFailure; -#ifndef NSS_DISABLE_ECC unsigned int len = 0; SECItem pointQ = { siBuffer, NULL, 0 }; mp_int k; /* to hold the private value */ @@ -589,7 +566,11 @@ ECDH_Derive(SECItem *publicValue, PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE); return SECFailure; } - return method->mul(derivedSecret, privateValue, publicValue); + rv = method->mul(derivedSecret, privateValue, publicValue); + if (rv != SECSuccess) { + SECITEM_ZfreeItem(derivedSecret, PR_FALSE); + } + return rv; } /* @@ -654,9 +635,6 @@ cleanup: if (pointQ.data) { PORT_ZFree(pointQ.data, pointQ.len); } -#else - PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG); -#endif /* NSS_DISABLE_ECC */ return rv; } @@ -670,7 +648,6 @@ ECDSA_SignDigestWithSeed(ECPrivateKey *key, SECItem *signature, const SECItem *digest, const unsigned char *kb, const int kblen) { SECStatus rv = SECFailure; -#ifndef NSS_DISABLE_ECC mp_int x1; mp_int d, k; /* private key, random integer */ mp_int r, s; /* tuple (r, s) is the signature */ @@ -899,9 +876,6 @@ cleanup: printf("ECDSA signing with seed %s\n", (rv == SECSuccess) ? "succeeded" : "failed"); #endif -#else - PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG); -#endif /* NSS_DISABLE_ECC */ return rv; } @@ -914,7 +888,6 @@ SECStatus ECDSA_SignDigest(ECPrivateKey *key, SECItem *signature, const SECItem *digest) { SECStatus rv = SECFailure; -#ifndef NSS_DISABLE_ECC int len; unsigned char *kBytes = NULL; @@ -941,9 +914,6 @@ cleanup: printf("ECDSA signing %s\n", (rv == SECSuccess) ? "succeeded" : "failed"); #endif -#else - PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG); -#endif /* NSS_DISABLE_ECC */ return rv; } @@ -961,7 +931,6 @@ ECDSA_VerifyDigest(ECPublicKey *key, const SECItem *signature, const SECItem *digest) { SECStatus rv = SECFailure; -#ifndef NSS_DISABLE_ECC mp_int r_, s_; /* tuple (r', s') is received signature) */ mp_int c, u1, u2, v; /* intermediate values used in verification */ mp_int x1; @@ -1161,9 +1130,6 @@ cleanup: printf("ECDSA verification %s\n", (rv == SECSuccess) ? "succeeded" : "failed"); #endif -#else - PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG); -#endif /* NSS_DISABLE_ECC */ return rv; } diff --git a/security/nss/lib/freebl/ecdecode.c b/security/nss/lib/freebl/ecdecode.c index 54b3e111b..652ad42d5 100644 --- a/security/nss/lib/freebl/ecdecode.c +++ b/security/nss/lib/freebl/ecdecode.c @@ -2,8 +2,6 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef NSS_DISABLE_ECC - #ifdef FREEBL_NO_DEPEND #include "stubs.h" #endif @@ -252,5 +250,3 @@ EC_GetPointSize(const ECParams *params) } return curveParams->pointSize - 1; } - -#endif /* NSS_DISABLE_ECC */ diff --git a/security/nss/lib/freebl/ecl/curve25519_64.c b/security/nss/lib/freebl/ecl/curve25519_64.c index 65f6bd41b..a2e4296bb 100644 --- a/security/nss/lib/freebl/ecl/curve25519_64.c +++ b/security/nss/lib/freebl/ecl/curve25519_64.c @@ -2,513 +2,13 @@ * 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/. */ -/* - * Derived from public domain C code by Adan Langley and Daniel J. Bernstein - */ - -#include "uint128.h" - #include "ecl-priv.h" -#include "mpi.h" - -#include <stdint.h> -#include <stdio.h> -#include <string.h> - -typedef uint8_t u8; -typedef uint64_t felem; - -/* Sum two numbers: output += in */ -static void -fsum(felem *output, const felem *in) -{ - unsigned i; - for (i = 0; i < 5; ++i) { - output[i] += in[i]; - } -} - -/* Find the difference of two numbers: output = in - output - * (note the order of the arguments!) - */ -static void -fdifference_backwards(felem *ioutput, const felem *iin) -{ - static const int64_t twotothe51 = ((int64_t)1l << 51); - const int64_t *in = (const int64_t *)iin; - int64_t *out = (int64_t *)ioutput; - - out[0] = in[0] - out[0]; - out[1] = in[1] - out[1]; - out[2] = in[2] - out[2]; - out[3] = in[3] - out[3]; - out[4] = in[4] - out[4]; - - // An arithmetic shift right of 63 places turns a positive number to 0 and a - // negative number to all 1's. This gives us a bitmask that lets us avoid - // side-channel prone branches. - int64_t t; - -#define NEGCHAIN(a, b) \ - t = out[a] >> 63; \ - out[a] += twotothe51 & t; \ - out[b] -= 1 & t; - -#define NEGCHAIN19(a, b) \ - t = out[a] >> 63; \ - out[a] += twotothe51 & t; \ - out[b] -= 19 & t; - - NEGCHAIN(0, 1); - NEGCHAIN(1, 2); - NEGCHAIN(2, 3); - NEGCHAIN(3, 4); - NEGCHAIN19(4, 0); - NEGCHAIN(0, 1); - NEGCHAIN(1, 2); - NEGCHAIN(2, 3); - NEGCHAIN(3, 4); -} - -/* Multiply a number by a scalar: output = in * scalar */ -static void -fscalar_product(felem *output, const felem *in, - const felem scalar) -{ - uint128_t tmp, tmp2; - - tmp = mul6464(in[0], scalar); - output[0] = mask51(tmp); - - tmp2 = mul6464(in[1], scalar); - tmp = add128(tmp2, rshift128(tmp, 51)); - output[1] = mask51(tmp); - - tmp2 = mul6464(in[2], scalar); - tmp = add128(tmp2, rshift128(tmp, 51)); - output[2] = mask51(tmp); - - tmp2 = mul6464(in[3], scalar); - tmp = add128(tmp2, rshift128(tmp, 51)); - output[3] = mask51(tmp); - - tmp2 = mul6464(in[4], scalar); - tmp = add128(tmp2, rshift128(tmp, 51)); - output[4] = mask51(tmp); - - output[0] += mask_lower(rshift128(tmp, 51)) * 19; -} - -/* Multiply two numbers: output = in2 * in - * - * output must be distinct to both inputs. The inputs are reduced coefficient - * form, the output is not. - */ -static void -fmul(felem *output, const felem *in2, const felem *in) -{ - uint128_t t0, t1, t2, t3, t4, t5, t6, t7, t8; - - t0 = mul6464(in[0], in2[0]); - t1 = add128(mul6464(in[1], in2[0]), mul6464(in[0], in2[1])); - t2 = add128(add128(mul6464(in[0], in2[2]), - mul6464(in[2], in2[0])), - mul6464(in[1], in2[1])); - t3 = add128(add128(add128(mul6464(in[0], in2[3]), - mul6464(in[3], in2[0])), - mul6464(in[1], in2[2])), - mul6464(in[2], in2[1])); - t4 = add128(add128(add128(add128(mul6464(in[0], in2[4]), - mul6464(in[4], in2[0])), - mul6464(in[3], in2[1])), - mul6464(in[1], in2[3])), - mul6464(in[2], in2[2])); - t5 = add128(add128(add128(mul6464(in[4], in2[1]), - mul6464(in[1], in2[4])), - mul6464(in[2], in2[3])), - mul6464(in[3], in2[2])); - t6 = add128(add128(mul6464(in[4], in2[2]), - mul6464(in[2], in2[4])), - mul6464(in[3], in2[3])); - t7 = add128(mul6464(in[3], in2[4]), mul6464(in[4], in2[3])); - t8 = mul6464(in[4], in2[4]); - - t0 = add128(t0, mul12819(t5)); - t1 = add128(t1, mul12819(t6)); - t2 = add128(t2, mul12819(t7)); - t3 = add128(t3, mul12819(t8)); - - t1 = add128(t1, rshift128(t0, 51)); - t0 = mask51full(t0); - t2 = add128(t2, rshift128(t1, 51)); - t1 = mask51full(t1); - t3 = add128(t3, rshift128(t2, 51)); - t4 = add128(t4, rshift128(t3, 51)); - t0 = add128(t0, mul12819(rshift128(t4, 51))); - t1 = add128(t1, rshift128(t0, 51)); - t2 = mask51full(t2); - t2 = add128(t2, rshift128(t1, 51)); - - output[0] = mask51(t0); - output[1] = mask51(t1); - output[2] = mask_lower(t2); - output[3] = mask51(t3); - output[4] = mask51(t4); -} - -static void -fsquare(felem *output, const felem *in) -{ - uint128_t t0, t1, t2, t3, t4, t5, t6, t7, t8; - - t0 = mul6464(in[0], in[0]); - t1 = lshift128(mul6464(in[0], in[1]), 1); - t2 = add128(lshift128(mul6464(in[0], in[2]), 1), - mul6464(in[1], in[1])); - t3 = add128(lshift128(mul6464(in[0], in[3]), 1), - lshift128(mul6464(in[1], in[2]), 1)); - t4 = add128(add128(lshift128(mul6464(in[0], in[4]), 1), - lshift128(mul6464(in[3], in[1]), 1)), - mul6464(in[2], in[2])); - t5 = add128(lshift128(mul6464(in[4], in[1]), 1), - lshift128(mul6464(in[2], in[3]), 1)); - t6 = add128(lshift128(mul6464(in[4], in[2]), 1), - mul6464(in[3], in[3])); - t7 = lshift128(mul6464(in[3], in[4]), 1); - t8 = mul6464(in[4], in[4]); - - t0 = add128(t0, mul12819(t5)); - t1 = add128(t1, mul12819(t6)); - t2 = add128(t2, mul12819(t7)); - t3 = add128(t3, mul12819(t8)); - - t1 = add128(t1, rshift128(t0, 51)); - t0 = mask51full(t0); - t2 = add128(t2, rshift128(t1, 51)); - t1 = mask51full(t1); - t3 = add128(t3, rshift128(t2, 51)); - t4 = add128(t4, rshift128(t3, 51)); - t0 = add128(t0, mul12819(rshift128(t4, 51))); - t1 = add128(t1, rshift128(t0, 51)); - - output[0] = mask51(t0); - output[1] = mask_lower(t1); - output[2] = mask51(t2); - output[3] = mask51(t3); - output[4] = mask51(t4); -} - -/* Take a 32-byte number and expand it into polynomial form */ -static void NO_SANITIZE_ALIGNMENT -fexpand(felem *output, const u8 *in) -{ - output[0] = *((const uint64_t *)(in)) & MASK51; - output[1] = (*((const uint64_t *)(in + 6)) >> 3) & MASK51; - output[2] = (*((const uint64_t *)(in + 12)) >> 6) & MASK51; - output[3] = (*((const uint64_t *)(in + 19)) >> 1) & MASK51; - output[4] = (*((const uint64_t *)(in + 24)) >> 12) & MASK51; -} - -/* Take a fully reduced polynomial form number and contract it into a - * 32-byte array - */ -static void -fcontract(u8 *output, const felem *input) -{ - uint128_t t0 = init128x(input[0]); - uint128_t t1 = init128x(input[1]); - uint128_t t2 = init128x(input[2]); - uint128_t t3 = init128x(input[3]); - uint128_t t4 = init128x(input[4]); - uint128_t tmp = init128x(19); - - t1 = add128(t1, rshift128(t0, 51)); - t0 = mask51full(t0); - t2 = add128(t2, rshift128(t1, 51)); - t1 = mask51full(t1); - t3 = add128(t3, rshift128(t2, 51)); - t2 = mask51full(t2); - t4 = add128(t4, rshift128(t3, 51)); - t3 = mask51full(t3); - t0 = add128(t0, mul12819(rshift128(t4, 51))); - t4 = mask51full(t4); - - t1 = add128(t1, rshift128(t0, 51)); - t0 = mask51full(t0); - t2 = add128(t2, rshift128(t1, 51)); - t1 = mask51full(t1); - t3 = add128(t3, rshift128(t2, 51)); - t2 = mask51full(t2); - t4 = add128(t4, rshift128(t3, 51)); - t3 = mask51full(t3); - t0 = add128(t0, mul12819(rshift128(t4, 51))); - t4 = mask51full(t4); - - /* now t is between 0 and 2^255-1, properly carried. */ - /* case 1: between 0 and 2^255-20. case 2: between 2^255-19 and 2^255-1. */ - - t0 = add128(t0, tmp); - - t1 = add128(t1, rshift128(t0, 51)); - t0 = mask51full(t0); - t2 = add128(t2, rshift128(t1, 51)); - t1 = mask51full(t1); - t3 = add128(t3, rshift128(t2, 51)); - t2 = mask51full(t2); - t4 = add128(t4, rshift128(t3, 51)); - t3 = mask51full(t3); - t0 = add128(t0, mul12819(rshift128(t4, 51))); - t4 = mask51full(t4); - - /* now between 19 and 2^255-1 in both cases, and offset by 19. */ - - t0 = add128(t0, init128x(0x8000000000000 - 19)); - tmp = init128x(0x8000000000000 - 1); - t1 = add128(t1, tmp); - t2 = add128(t2, tmp); - t3 = add128(t3, tmp); - t4 = add128(t4, tmp); - - /* now between 2^255 and 2^256-20, and offset by 2^255. */ - - t1 = add128(t1, rshift128(t0, 51)); - t0 = mask51full(t0); - t2 = add128(t2, rshift128(t1, 51)); - t1 = mask51full(t1); - t3 = add128(t3, rshift128(t2, 51)); - t2 = mask51full(t2); - t4 = add128(t4, rshift128(t3, 51)); - t3 = mask51full(t3); - t4 = mask51full(t4); - - *((uint64_t *)(output)) = mask_lower(t0) | mask_lower(t1) << 51; - *((uint64_t *)(output + 8)) = (mask_lower(t1) >> 13) | (mask_lower(t2) << 38); - *((uint64_t *)(output + 16)) = (mask_lower(t2) >> 26) | (mask_lower(t3) << 25); - *((uint64_t *)(output + 24)) = (mask_lower(t3) >> 39) | (mask_lower(t4) << 12); -} - -/* Input: Q, Q', Q-Q' - * Output: 2Q, Q+Q' - * - * x2 z3: long form - * x3 z3: long form - * x z: short form, destroyed - * xprime zprime: short form, destroyed - * qmqp: short form, preserved - */ -static void -fmonty(felem *x2, felem *z2, /* output 2Q */ - felem *x3, felem *z3, /* output Q + Q' */ - felem *x, felem *z, /* input Q */ - felem *xprime, felem *zprime, /* input Q' */ - const felem *qmqp /* input Q - Q' */) -{ - felem origx[5], origxprime[5], zzz[5], xx[5], zz[5], xxprime[5], zzprime[5], - zzzprime[5]; - - memcpy(origx, x, 5 * sizeof(felem)); - fsum(x, z); - fdifference_backwards(z, origx); // does x - z - - memcpy(origxprime, xprime, sizeof(felem) * 5); - fsum(xprime, zprime); - fdifference_backwards(zprime, origxprime); - fmul(xxprime, xprime, z); - fmul(zzprime, x, zprime); - memcpy(origxprime, xxprime, sizeof(felem) * 5); - fsum(xxprime, zzprime); - fdifference_backwards(zzprime, origxprime); - fsquare(x3, xxprime); - fsquare(zzzprime, zzprime); - fmul(z3, zzzprime, qmqp); - - fsquare(xx, x); - fsquare(zz, z); - fmul(x2, xx, zz); - fdifference_backwards(zz, xx); // does zz = xx - zz - fscalar_product(zzz, zz, 121665); - fsum(zzz, xx); - fmul(z2, zz, zzz); -} - -// ----------------------------------------------------------------------------- -// Maybe swap the contents of two felem arrays (@a and @b), each @len elements -// long. Perform the swap iff @swap is non-zero. -// -// This function performs the swap without leaking any side-channel -// information. -// ----------------------------------------------------------------------------- -static void -swap_conditional(felem *a, felem *b, unsigned len, felem iswap) -{ - unsigned i; - const felem swap = 1 + ~iswap; - - for (i = 0; i < len; ++i) { - const felem x = swap & (a[i] ^ b[i]); - a[i] ^= x; - b[i] ^= x; - } -} - -/* Calculates nQ where Q is the x-coordinate of a point on the curve - * - * resultx/resultz: the x coordinate of the resulting curve point (short form) - * n: a 32-byte number - * q: a point of the curve (short form) - */ -static void -cmult(felem *resultx, felem *resultz, const u8 *n, const felem *q) -{ - felem a[5] = { 0 }, b[5] = { 1 }, c[5] = { 1 }, d[5] = { 0 }; - felem *nqpqx = a, *nqpqz = b, *nqx = c, *nqz = d, *t; - felem e[5] = { 0 }, f[5] = { 1 }, g[5] = { 0 }, h[5] = { 1 }; - felem *nqpqx2 = e, *nqpqz2 = f, *nqx2 = g, *nqz2 = h; - - unsigned i, j; - - memcpy(nqpqx, q, sizeof(felem) * 5); - - for (i = 0; i < 32; ++i) { - u8 byte = n[31 - i]; - for (j = 0; j < 8; ++j) { - const felem bit = byte >> 7; - - swap_conditional(nqx, nqpqx, 5, bit); - swap_conditional(nqz, nqpqz, 5, bit); - fmonty(nqx2, nqz2, nqpqx2, nqpqz2, nqx, nqz, nqpqx, nqpqz, q); - swap_conditional(nqx2, nqpqx2, 5, bit); - swap_conditional(nqz2, nqpqz2, 5, bit); - - t = nqx; - nqx = nqx2; - nqx2 = t; - t = nqz; - nqz = nqz2; - nqz2 = t; - t = nqpqx; - nqpqx = nqpqx2; - nqpqx2 = t; - t = nqpqz; - nqpqz = nqpqz2; - nqpqz2 = t; - - byte <<= 1; - } - } - - memcpy(resultx, nqx, sizeof(felem) * 5); - memcpy(resultz, nqz, sizeof(felem) * 5); -} - -// ----------------------------------------------------------------------------- -// Shamelessly copied from djb's code -// ----------------------------------------------------------------------------- -static void -crecip(felem *out, const felem *z) -{ - felem z2[5]; - felem z9[5]; - felem z11[5]; - felem z2_5_0[5]; - felem z2_10_0[5]; - felem z2_20_0[5]; - felem z2_50_0[5]; - felem z2_100_0[5]; - felem t0[5]; - felem t1[5]; - int i; - - /* 2 */ fsquare(z2, z); - /* 4 */ fsquare(t1, z2); - /* 8 */ fsquare(t0, t1); - /* 9 */ fmul(z9, t0, z); - /* 11 */ fmul(z11, z9, z2); - /* 22 */ fsquare(t0, z11); - /* 2^5 - 2^0 = 31 */ fmul(z2_5_0, t0, z9); - - /* 2^6 - 2^1 */ fsquare(t0, z2_5_0); - /* 2^7 - 2^2 */ fsquare(t1, t0); - /* 2^8 - 2^3 */ fsquare(t0, t1); - /* 2^9 - 2^4 */ fsquare(t1, t0); - /* 2^10 - 2^5 */ fsquare(t0, t1); - /* 2^10 - 2^0 */ fmul(z2_10_0, t0, z2_5_0); - - /* 2^11 - 2^1 */ fsquare(t0, z2_10_0); - /* 2^12 - 2^2 */ fsquare(t1, t0); - /* 2^20 - 2^10 */ for (i = 2; i < 10; i += 2) { - fsquare(t0, t1); - fsquare(t1, t0); - } - /* 2^20 - 2^0 */ fmul(z2_20_0, t1, z2_10_0); - - /* 2^21 - 2^1 */ fsquare(t0, z2_20_0); - /* 2^22 - 2^2 */ fsquare(t1, t0); - /* 2^40 - 2^20 */ for (i = 2; i < 20; i += 2) { - fsquare(t0, t1); - fsquare(t1, t0); - } - /* 2^40 - 2^0 */ fmul(t0, t1, z2_20_0); - - /* 2^41 - 2^1 */ fsquare(t1, t0); - /* 2^42 - 2^2 */ fsquare(t0, t1); - /* 2^50 - 2^10 */ for (i = 2; i < 10; i += 2) { - fsquare(t1, t0); - fsquare(t0, t1); - } - /* 2^50 - 2^0 */ fmul(z2_50_0, t0, z2_10_0); - - /* 2^51 - 2^1 */ fsquare(t0, z2_50_0); - /* 2^52 - 2^2 */ fsquare(t1, t0); - /* 2^100 - 2^50 */ for (i = 2; i < 50; i += 2) { - fsquare(t0, t1); - fsquare(t1, t0); - } - /* 2^100 - 2^0 */ fmul(z2_100_0, t1, z2_50_0); - - /* 2^101 - 2^1 */ fsquare(t1, z2_100_0); - /* 2^102 - 2^2 */ fsquare(t0, t1); - /* 2^200 - 2^100 */ for (i = 2; i < 100; i += 2) { - fsquare(t1, t0); - fsquare(t0, t1); - } - /* 2^200 - 2^0 */ fmul(t1, t0, z2_100_0); - - /* 2^201 - 2^1 */ fsquare(t0, t1); - /* 2^202 - 2^2 */ fsquare(t1, t0); - /* 2^250 - 2^50 */ for (i = 2; i < 50; i += 2) { - fsquare(t0, t1); - fsquare(t1, t0); - } - /* 2^250 - 2^0 */ fmul(t0, t1, z2_50_0); - - /* 2^251 - 2^1 */ fsquare(t1, t0); - /* 2^252 - 2^2 */ fsquare(t0, t1); - /* 2^253 - 2^3 */ fsquare(t1, t0); - /* 2^254 - 2^4 */ fsquare(t0, t1); - /* 2^255 - 2^5 */ fsquare(t1, t0); - /* 2^255 - 21 */ fmul(out, t1, z11); -} +#include "../verified/Hacl_Curve25519.h" SECStatus -ec_Curve25519_mul(uint8_t *mypublic, const uint8_t *secret, - const uint8_t *basepoint) +ec_Curve25519_mul(uint8_t *mypublic, const uint8_t *secret, const uint8_t *basepoint) { - felem bp[5], x[5], z[5], zmone[5]; - uint8_t e[32]; - int i; - - for (i = 0; i < 32; ++i) { - e[i] = secret[i]; - } - e[0] &= 248; - e[31] &= 127; - e[31] |= 64; - fexpand(bp, basepoint); - cmult(x, z, e, bp); - crecip(zmone, z); - fmul(z, x, zmone); - fcontract(mypublic, z); - + // Note: this cast is safe because HaCl* state has a post-condition that only "mypublic" changed. + Hacl_Curve25519_crypto_scalarmult(mypublic, (uint8_t *)secret, (uint8_t *)basepoint); return 0; } diff --git a/security/nss/lib/freebl/ecl/ecp_25519.c b/security/nss/lib/freebl/ecl/ecp_25519.c index 1e7875fff..38bd34c50 100644 --- a/security/nss/lib/freebl/ecl/ecp_25519.c +++ b/security/nss/lib/freebl/ecl/ecp_25519.c @@ -115,5 +115,9 @@ ec_Curve25519_pt_mul(SECItem *X, SECItem *k, SECItem *P) px = P->data; } - return ec_Curve25519_mul(X->data, k->data, px); + SECStatus rv = ec_Curve25519_mul(X->data, k->data, px); + if (NSS_SecureMemcmpZero(X->data, X->len) == 0) { + return SECFailure; + } + return rv; } diff --git a/security/nss/lib/freebl/ecl/uint128.c b/security/nss/lib/freebl/ecl/uint128.c deleted file mode 100644 index 5465875ad..000000000 --- a/security/nss/lib/freebl/ecl/uint128.c +++ /dev/null @@ -1,90 +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 "uint128.h" - -/* helper functions */ -uint64_t -mask51(uint128_t x) -{ - return x.lo & MASK51; -} - -uint64_t -mask_lower(uint128_t x) -{ - return x.lo; -} - -uint128_t -mask51full(uint128_t x) -{ - uint128_t ret = { x.lo & MASK51, 0 }; - return ret; -} - -uint128_t -init128x(uint64_t x) -{ - uint128_t ret = { x, 0 }; - return ret; -} - -#define CONSTANT_TIME_CARRY(a, b) \ - ((a ^ ((a ^ b) | ((a - b) ^ b))) >> (sizeof(a) * 8 - 1)) - -/* arithmetic */ - -uint128_t -add128(uint128_t a, uint128_t b) -{ - uint128_t ret; - ret.lo = a.lo + b.lo; - ret.hi = a.hi + b.hi + CONSTANT_TIME_CARRY(ret.lo, b.lo); - return ret; -} - -/* out = 19 * a */ -uint128_t -mul12819(uint128_t a) -{ - uint128_t ret = lshift128(a, 4); - ret = add128(ret, a); - ret = add128(ret, a); - ret = add128(ret, a); - return ret; -} - -uint128_t -mul6464(uint64_t a, uint64_t b) -{ - uint128_t ret; - uint64_t t0 = ((uint64_t)(uint32_t)a) * ((uint64_t)(uint32_t)b); - uint64_t t1 = (a >> 32) * ((uint64_t)(uint32_t)b) + (t0 >> 32); - uint64_t t2 = (b >> 32) * ((uint64_t)(uint32_t)a) + ((uint32_t)t1); - ret.lo = (((uint64_t)((uint32_t)t2)) << 32) + ((uint32_t)t0); - ret.hi = (a >> 32) * (b >> 32); - ret.hi += (t2 >> 32) + (t1 >> 32); - return ret; -} - -/* only defined for n < 64 */ -uint128_t -rshift128(uint128_t x, uint8_t n) -{ - uint128_t ret; - ret.lo = (x.lo >> n) + (x.hi << (64 - n)); - ret.hi = x.hi >> n; - return ret; -} - -/* only defined for n < 64 */ -uint128_t -lshift128(uint128_t x, uint8_t n) -{ - uint128_t ret; - ret.hi = (x.hi << n) + (x.lo >> (64 - n)); - ret.lo = x.lo << n; - return ret; -} diff --git a/security/nss/lib/freebl/ecl/uint128.h b/security/nss/lib/freebl/ecl/uint128.h deleted file mode 100644 index a3a71e6e7..000000000 --- a/security/nss/lib/freebl/ecl/uint128.h +++ /dev/null @@ -1,35 +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 <stdint.h> - -#define MASK51 0x7ffffffffffffULL - -#ifdef HAVE_INT128_SUPPORT -typedef unsigned __int128 uint128_t; -#define add128(a, b) (a) + (b) -#define mul6464(a, b) (uint128_t)(a) * (uint128_t)(b) -#define mul12819(a) (uint128_t)(a) * 19 -#define rshift128(x, n) (x) >> (n) -#define lshift128(x, n) (x) << (n) -#define mask51(x) (x) & 0x7ffffffffffff -#define mask_lower(x) (uint64_t)(x) -#define mask51full(x) (x) & 0x7ffffffffffff -#define init128x(x) (x) -#else /* uint128_t for Windows and 32 bit intel systems */ -struct uint128_t_str { - uint64_t lo; - uint64_t hi; -}; -typedef struct uint128_t_str uint128_t; -uint128_t add128(uint128_t a, uint128_t b); -uint128_t mul6464(uint64_t a, uint64_t b); -uint128_t mul12819(uint128_t a); -uint128_t rshift128(uint128_t x, uint8_t n); -uint128_t lshift128(uint128_t x, uint8_t n); -uint64_t mask51(uint128_t x); -uint64_t mask_lower(uint128_t x); -uint128_t mask51full(uint128_t x); -uint128_t init128x(uint64_t x); -#endif diff --git a/security/nss/lib/freebl/exports.gyp b/security/nss/lib/freebl/exports.gyp index aded6bfb6..ca0b6dafd 100644 --- a/security/nss/lib/freebl/exports.gyp +++ b/security/nss/lib/freebl/exports.gyp @@ -29,6 +29,7 @@ 'files': [ 'alghmac.h', 'blapi.h', + 'blake2b.h', 'chacha20poly1305.h', 'ec.h', 'ecl/ecl-curve.h', diff --git a/security/nss/lib/freebl/fipsfreebl.c b/security/nss/lib/freebl/fipsfreebl.c index 094513560..2328a677f 100644 --- a/security/nss/lib/freebl/fipsfreebl.c +++ b/security/nss/lib/freebl/fipsfreebl.c @@ -6,6 +6,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* $Id: fipstest.c,v 1.31 2012/06/28 17:55:06 rrelyea%redhat.com Exp $ */ +#ifndef NSS_FIPS_DISABLED #ifdef FREEBL_NO_DEPEND #include "stubs.h" #endif @@ -15,9 +16,7 @@ #include "secerr.h" #include "prtypes.h" -#ifdef NSS_ENABLE_ECC #include "ec.h" /* Required for ECDSA */ -#endif /* * different platforms have different ways of calling and initial entry point @@ -1077,8 +1076,6 @@ rsa_loser: return (SECFailure); } -#ifdef NSS_ENABLE_ECC - static SECStatus freebl_fips_ECDSA_Test(ECParams *ecparams, const PRUint8 *knownSignature, @@ -1275,8 +1272,6 @@ freebl_fips_ECDSA_PowerUpSelfTest() return (SECSuccess); } -#endif /* NSS_ENABLE_ECC */ - static SECStatus freebl_fips_DSA_PowerUpSelfTest(void) { @@ -1559,13 +1554,11 @@ freebl_fipsPowerUpSelfTest(unsigned int tests) if (rv != SECSuccess) return rv; -#ifdef NSS_ENABLE_ECC /* ECDSA Power-Up SelfTest(s). */ rv = freebl_fips_ECDSA_PowerUpSelfTest(); if (rv != SECSuccess) return rv; -#endif } /* Passed Power-Up SelfTest(s). */ return (SECSuccess); @@ -1589,9 +1582,6 @@ static PRBool self_tests_freebl_ran = PR_FALSE; static PRBool self_tests_ran = PR_FALSE; static PRBool self_tests_freebl_success = PR_FALSE; static PRBool self_tests_success = PR_FALSE; -#if defined(DEBUG) -static PRBool fips_mode_available = PR_FALSE; -#endif /* * accessors for freebl @@ -1644,7 +1634,6 @@ bl_startup_tests(void) PORT_Assert(self_tests_freebl_ran == PR_FALSE); PORT_Assert(self_tests_success == PR_FALSE); - PORT_Assert(fips_mode_available == PR_FALSE); self_tests_freebl_ran = PR_TRUE; /* we are running the tests */ self_tests_success = PR_FALSE; /* force it just in case */ self_tests_freebl_success = PR_FALSE; /* force it just in case */ @@ -1713,3 +1702,4 @@ BL_FIPSEntryOK(PRBool freebl_only) PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); return SECFailure; } +#endif diff --git a/security/nss/lib/freebl/freebl.gyp b/security/nss/lib/freebl/freebl.gyp index 8c0d0dcd5..fae56f709 100644 --- a/security/nss/lib/freebl/freebl.gyp +++ b/security/nss/lib/freebl/freebl.gyp @@ -10,7 +10,7 @@ 'target_name': 'intel-gcm-wrap_c_lib', 'type': 'static_library', 'sources': [ - 'intel-gcm-wrap.c' + 'intel-gcm-wrap.c', ], 'dependencies': [ '<(DEPTH)/exports.gyp:nss_exports' @@ -23,6 +23,69 @@ ] }, { + # TODO: make this so that all hardware accelerated code is in here. + 'target_name': 'hw-acc-crypto', + 'type': 'static_library', + 'sources': [ + 'verified/Hacl_Chacha20_Vec128.c', + ], + 'dependencies': [ + '<(DEPTH)/exports.gyp:nss_exports' + ], + 'conditions': [ + [ 'target_arch=="ia32" or target_arch=="x64"', { + 'cflags': [ + '-mssse3' + ], + 'cflags_mozilla': [ + '-mssse3' + ], + # GCC doesn't define this. + 'defines': [ + '__SSSE3__', + ], + }], + [ 'OS=="android"', { + # On Android we can't use any of the hardware acceleration :( + 'defines!': [ + '__ARM_NEON__', + '__ARM_NEON', + ], + }], + ], + }, + { + 'target_name': 'gcm-aes-x86_c_lib', + 'type': 'static_library', + 'sources': [ + 'gcm-x86.c', 'aes-x86.c' + ], + 'dependencies': [ + '<(DEPTH)/exports.gyp:nss_exports' + ], + # Enable isa option for pclmul and aes-ni; supported since gcc 4.4. + # This is only supported by x84/x64. It's not needed for Windows, + # unless clang-cl is used. + 'cflags_mozilla': [ + '-mpclmul', '-maes' + ], + 'conditions': [ + [ 'OS=="linux" or OS=="android" or OS=="dragonfly" or OS=="freebsd" or OS=="netbsd" or OS=="openbsd"', { + 'cflags': [ + '-mpclmul', '-maes' + ], + }], + # macOS build doesn't use cflags. + [ 'OS=="mac"', { + 'xcode_settings': { + 'OTHER_CFLAGS': [ + '-mpclmul', '-maes' + ], + }, + }] + ] + }, + { 'target_name': 'freebl', 'type': 'static_library', 'sources': [ @@ -43,8 +106,14 @@ ], 'dependencies': [ '<(DEPTH)/exports.gyp:nss_exports', + 'hw-acc-crypto', ], 'conditions': [ + [ 'target_arch=="ia32" or target_arch=="x64"', { + 'dependencies': [ + 'gcm-aes-x86_c_lib', + ], + }], [ 'OS=="linux"', { 'defines!': [ 'FREEBL_NO_DEPEND', @@ -74,8 +143,14 @@ ], 'dependencies': [ '<(DEPTH)/exports.gyp:nss_exports', + 'hw-acc-crypto', ], 'conditions': [ + [ 'target_arch=="ia32" or target_arch=="x64"', { + 'dependencies': [ + 'gcm-aes-x86_c_lib', + ] + }], [ 'OS!="linux" and OS!="android"', { 'conditions': [ [ 'moz_fold_libs==0', { @@ -142,7 +217,8 @@ 'target_defaults': { 'include_dirs': [ 'mpi', - 'ecl' + 'ecl', + 'verified', ], 'defines': [ 'SHLIB_SUFFIX=\"<(dll_suffix)\"', @@ -153,19 +229,12 @@ 'MP_API_COMPATIBLE' ], 'conditions': [ - [ 'target_arch=="ia32" or target_arch=="x64"', { - 'cflags_mozilla': [ - '-mpclmul', - '-maes', - ], - }], [ 'OS=="mac"', { 'xcode_settings': { # I'm not sure since when this is supported. # But I hope that doesn't matter. We also assume this is x86/x64. 'OTHER_CFLAGS': [ - '-mpclmul', - '-maes', + '-std=gnu99', ], }, }], @@ -221,17 +290,29 @@ 'HAVE_INT128_SUPPORT', ], }, { - 'sources': [ - 'ecl/uint128.c', + 'defines': [ + 'KRML_NOUINT128', ], }], ], + }, { + 'defines': [ + 'KRML_NOUINT128', + ], }], [ 'OS=="linux"', { 'defines': [ 'FREEBL_LOWHASH', 'FREEBL_NO_DEPEND', ], + 'cflags': [ + '-std=gnu99', + ], + }], + [ 'OS=="dragonfly" or OS=="freebsd" or OS=="netbsd" or OS=="openbsd"', { + 'cflags': [ + '-std=gnu99', + ], }], [ 'OS=="linux" or OS=="android"', { 'conditions': [ @@ -259,14 +340,6 @@ 'MP_USE_UINT_DIGIT', ], }], - [ 'target_arch=="ia32" or target_arch=="x64"', { - 'cflags': [ - # enable isa option for pclmul am aes-ni; supported since gcc 4.4 - # This is only support by x84/x64. It's not needed for Windows. - '-mpclmul', - '-maes', - ], - }], [ 'target_arch=="arm"', { 'defines': [ 'MP_ASSEMBLY_MULTIPLY', diff --git a/security/nss/lib/freebl/freebl_base.gypi b/security/nss/lib/freebl/freebl_base.gypi index 027aa2702..ebd1018d8 100644 --- a/security/nss/lib/freebl/freebl_base.gypi +++ b/security/nss/lib/freebl/freebl_base.gypi @@ -8,8 +8,10 @@ 'alghmac.c', 'arcfive.c', 'arcfour.c', + 'blake2b.c', 'camellia.c', 'chacha20poly1305.c', + 'crypto_primitives.c', 'ctr.c', 'cts.c', 'des.c', @@ -98,10 +100,6 @@ ], }], [ 'OS=="win"', { - 'sources': [ - #TODO: building with mingw should not need this. - 'ecl/uint128.c', - ], 'libraries': [ 'advapi32.lib', ], @@ -132,29 +130,52 @@ }], ], }], - ['target_arch=="ia32" or target_arch=="x64"', { + ['target_arch=="ia32" or target_arch=="x64" or target_arch=="arm64" or target_arch=="aarch64"', { 'sources': [ - # All intel architectures get the 64 bit version + # All intel and 64-bit ARM architectures get the 64 bit version. 'ecl/curve25519_64.c', + 'verified/Hacl_Curve25519.c', + 'verified/FStar.c', ], }, { 'sources': [ - # All non intel architectures get the generic 32 bit implementation (slow!) + # All other architectures get the generic 32 bit implementation (slow!) 'ecl/curve25519_32.c', ], }], - #TODO uint128.c [ 'disable_chachapoly==0', { + # The ChaCha20 code is linked in through the static ssse3-crypto lib on + # all platforms that support SSSE3. There are runtime checks in place to + # choose the correct ChaCha implementation at runtime. + 'sources': [ + 'verified/Hacl_Chacha20.c', + ], 'conditions': [ - [ 'OS!="win" and target_arch=="x64"', { - 'sources': [ - 'chacha20_vec.c', - 'poly1305-donna-x64-sse2-incremental-source.c', + [ 'OS!="win"', { + 'conditions': [ + [ 'target_arch=="x64"', { + 'sources': [ + 'verified/Hacl_Poly1305_64.c', + ], + }, { + # !Windows & !x64 + 'conditions': [ + [ 'target_arch=="arm64" or target_arch=="aarch64"', { + 'sources': [ + 'verified/Hacl_Poly1305_64.c', + ], + }, { + # !Windows & !x64 & !arm64 & !aarch64 + 'sources': [ + 'poly1305.c', + ], + }], + ], + }], ], }, { - # not x64 + # Windows 'sources': [ - 'chacha20.c', 'poly1305.c', ], }], diff --git a/security/nss/lib/freebl/gcm-x86.c b/security/nss/lib/freebl/gcm-x86.c new file mode 100644 index 000000000..e34d63394 --- /dev/null +++ b/security/nss/lib/freebl/gcm-x86.c @@ -0,0 +1,127 @@ +/* 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 FREEBL_NO_DEPEND +#include "stubs.h" +#endif +#include "gcm.h" +#include "secerr.h" + +#include <wmmintrin.h> /* clmul */ + +#define WRITE64(x, bytes) \ + (bytes)[0] = (x) >> 56; \ + (bytes)[1] = (x) >> 48; \ + (bytes)[2] = (x) >> 40; \ + (bytes)[3] = (x) >> 32; \ + (bytes)[4] = (x) >> 24; \ + (bytes)[5] = (x) >> 16; \ + (bytes)[6] = (x) >> 8; \ + (bytes)[7] = (x); + +SECStatus +gcm_HashWrite_hw(gcmHashContext *ghash, unsigned char *outbuf) +{ + uint64_t tmp_out[2]; + _mm_storeu_si128((__m128i *)tmp_out, ghash->x); + /* maxout must be larger than 16 byte (checked by the caller). */ + WRITE64(tmp_out[0], outbuf + 8); + WRITE64(tmp_out[1], outbuf); + return SECSuccess; +} + +SECStatus +gcm_HashMult_hw(gcmHashContext *ghash, const unsigned char *buf, + unsigned int count) +{ + size_t i; + pre_align __m128i z_high post_align; + pre_align __m128i z_low post_align; + pre_align __m128i C post_align; + pre_align __m128i D post_align; + pre_align __m128i E post_align; + pre_align __m128i F post_align; + pre_align __m128i bin post_align; + pre_align __m128i Ci post_align; + pre_align __m128i tmp post_align; + + for (i = 0; i < count; i++, buf += 16) { + bin = _mm_set_epi16(((uint16_t)buf[0] << 8) | buf[1], + ((uint16_t)buf[2] << 8) | buf[3], + ((uint16_t)buf[4] << 8) | buf[5], + ((uint16_t)buf[6] << 8) | buf[7], + ((uint16_t)buf[8] << 8) | buf[9], + ((uint16_t)buf[10] << 8) | buf[11], + ((uint16_t)buf[12] << 8) | buf[13], + ((uint16_t)buf[14] << 8) | buf[15]); + Ci = _mm_xor_si128(bin, ghash->x); + + /* Do binary mult ghash->X = Ci * ghash->H. */ + C = _mm_clmulepi64_si128(Ci, ghash->h, 0x00); + D = _mm_clmulepi64_si128(Ci, ghash->h, 0x11); + E = _mm_clmulepi64_si128(Ci, ghash->h, 0x01); + F = _mm_clmulepi64_si128(Ci, ghash->h, 0x10); + tmp = _mm_xor_si128(E, F); + z_high = _mm_xor_si128(tmp, _mm_slli_si128(D, 8)); + z_high = _mm_unpackhi_epi64(z_high, D); + z_low = _mm_xor_si128(_mm_slli_si128(tmp, 8), C); + z_low = _mm_unpackhi_epi64(_mm_slli_si128(C, 8), z_low); + + /* Shift one to the left (multiply by x) as gcm spec is stupid. */ + C = _mm_slli_si128(z_low, 8); + E = _mm_srli_epi64(C, 63); + D = _mm_slli_si128(z_high, 8); + F = _mm_srli_epi64(D, 63); + /* Carry over */ + C = _mm_srli_si128(z_low, 8); + D = _mm_srli_epi64(C, 63); + z_low = _mm_or_si128(_mm_slli_epi64(z_low, 1), E); + z_high = _mm_or_si128(_mm_or_si128(_mm_slli_epi64(z_high, 1), F), D); + + /* Reduce */ + C = _mm_slli_si128(z_low, 8); + /* D = z_low << 127 */ + D = _mm_slli_epi64(C, 63); + /* E = z_low << 126 */ + E = _mm_slli_epi64(C, 62); + /* F = z_low << 121 */ + F = _mm_slli_epi64(C, 57); + /* z_low ^= (z_low << 127) ^ (z_low << 126) ^ (z_low << 121); */ + z_low = _mm_xor_si128(_mm_xor_si128(_mm_xor_si128(z_low, D), E), F); + C = _mm_srli_si128(z_low, 8); + /* D = z_low >> 1 */ + D = _mm_slli_epi64(C, 63); + D = _mm_or_si128(_mm_srli_epi64(z_low, 1), D); + /* E = z_low >> 2 */ + E = _mm_slli_epi64(C, 62); + E = _mm_or_si128(_mm_srli_epi64(z_low, 2), E); + /* F = z_low >> 7 */ + F = _mm_slli_epi64(C, 57); + F = _mm_or_si128(_mm_srli_epi64(z_low, 7), F); + /* ghash->x ^= z_low ^ (z_low >> 1) ^ (z_low >> 2) ^ (z_low >> 7); */ + ghash->x = _mm_xor_si128(_mm_xor_si128( + _mm_xor_si128(_mm_xor_si128(z_high, z_low), D), E), + F); + } + return SECSuccess; +} + +SECStatus +gcm_HashInit_hw(gcmHashContext *ghash) +{ + ghash->ghash_mul = gcm_HashMult_hw; + ghash->x = _mm_setzero_si128(); + /* MSVC requires __m64 to load epi64. */ + ghash->h = _mm_set_epi32(ghash->h_high >> 32, (uint32_t)ghash->h_high, + ghash->h_low >> 32, (uint32_t)ghash->h_low); + ghash->hw = PR_TRUE; + return SECSuccess; +} + +SECStatus +gcm_HashZeroX_hw(gcmHashContext *ghash) +{ + ghash->x = _mm_setzero_si128(); + return SECSuccess; +} diff --git a/security/nss/lib/freebl/gcm.c b/security/nss/lib/freebl/gcm.c index 0fdb0fd48..f1e16da78 100644 --- a/security/nss/lib/freebl/gcm.c +++ b/security/nss/lib/freebl/gcm.c @@ -17,18 +17,50 @@ #include <limits.h> -#ifdef NSS_X86_OR_X64 -#include <wmmintrin.h> /* clmul */ -#endif - /* Forward declarations */ +SECStatus gcm_HashInit_hw(gcmHashContext *ghash); +SECStatus gcm_HashWrite_hw(gcmHashContext *ghash, unsigned char *outbuf); SECStatus gcm_HashMult_hw(gcmHashContext *ghash, const unsigned char *buf, unsigned int count); +SECStatus gcm_HashZeroX_hw(gcmHashContext *ghash); SECStatus gcm_HashMult_sftw(gcmHashContext *ghash, const unsigned char *buf, unsigned int count); SECStatus gcm_HashMult_sftw32(gcmHashContext *ghash, const unsigned char *buf, unsigned int count); +/* Stub definitions for the above *_hw functions, which shouldn't be + * used unless NSS_X86_OR_X64 is defined */ +#ifndef NSS_X86_OR_X64 +SECStatus +gcm_HashWrite_hw(gcmHashContext *ghash, unsigned char *outbuf) +{ + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; +} + +SECStatus +gcm_HashMult_hw(gcmHashContext *ghash, const unsigned char *buf, + unsigned int count) +{ + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; +} + +SECStatus +gcm_HashInit_hw(gcmHashContext *ghash) +{ + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; +} + +SECStatus +gcm_HashZeroX_hw(gcmHashContext *ghash) +{ + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; +} +#endif /* NSS_X86_OR_X64 */ + uint64_t get64(const unsigned char *bytes) { @@ -46,6 +78,8 @@ get64(const unsigned char *bytes) SECStatus gcmHash_InitContext(gcmHashContext *ghash, const unsigned char *H, PRBool sw) { + SECStatus rv = SECSuccess; + ghash->cLen = 0; ghash->bufLen = 0; PORT_Memset(ghash->counterBuf, 0, sizeof(ghash->counterBuf)); @@ -53,17 +87,7 @@ gcmHash_InitContext(gcmHashContext *ghash, const unsigned char *H, PRBool sw) ghash->h_low = get64(H + 8); ghash->h_high = get64(H); if (clmul_support() && !sw) { -#ifdef NSS_X86_OR_X64 - ghash->ghash_mul = gcm_HashMult_hw; - ghash->x = _mm_setzero_si128(); - /* MSVC requires __m64 to load epi64. */ - ghash->h = _mm_set_epi32(ghash->h_high >> 32, (uint32_t)ghash->h_high, - ghash->h_low >> 32, (uint32_t)ghash->h_low); - ghash->hw = PR_TRUE; -#else - PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); - return SECFailure; -#endif /* NSS_X86_OR_X64 */ + rv = gcm_HashInit_hw(ghash); } else { /* We fall back to the software implementation if we can't use / don't * want to use pclmul. */ @@ -75,7 +99,7 @@ gcmHash_InitContext(gcmHashContext *ghash, const unsigned char *H, PRBool sw) ghash->x_high = ghash->x_low = 0; ghash->hw = PR_FALSE; } - return SECSuccess; + return rv; } #ifdef HAVE_INT128_SUPPORT @@ -283,102 +307,17 @@ gcm_HashMult_sftw32(gcmHashContext *ghash, const unsigned char *buf, } #endif /* HAVE_INT128_SUPPORT */ -SECStatus -gcm_HashMult_hw(gcmHashContext *ghash, const unsigned char *buf, - unsigned int count) -{ -#ifdef NSS_X86_OR_X64 - size_t i; - pre_align __m128i z_high post_align; - pre_align __m128i z_low post_align; - pre_align __m128i C post_align; - pre_align __m128i D post_align; - pre_align __m128i E post_align; - pre_align __m128i F post_align; - pre_align __m128i bin post_align; - pre_align __m128i Ci post_align; - pre_align __m128i tmp post_align; - - for (i = 0; i < count; i++, buf += 16) { - bin = _mm_set_epi16(((uint16_t)buf[0] << 8) | buf[1], - ((uint16_t)buf[2] << 8) | buf[3], - ((uint16_t)buf[4] << 8) | buf[5], - ((uint16_t)buf[6] << 8) | buf[7], - ((uint16_t)buf[8] << 8) | buf[9], - ((uint16_t)buf[10] << 8) | buf[11], - ((uint16_t)buf[12] << 8) | buf[13], - ((uint16_t)buf[14] << 8) | buf[15]); - Ci = _mm_xor_si128(bin, ghash->x); - - /* Do binary mult ghash->X = Ci * ghash->H. */ - C = _mm_clmulepi64_si128(Ci, ghash->h, 0x00); - D = _mm_clmulepi64_si128(Ci, ghash->h, 0x11); - E = _mm_clmulepi64_si128(Ci, ghash->h, 0x01); - F = _mm_clmulepi64_si128(Ci, ghash->h, 0x10); - tmp = _mm_xor_si128(E, F); - z_high = _mm_xor_si128(tmp, _mm_slli_si128(D, 8)); - z_high = _mm_unpackhi_epi64(z_high, D); - z_low = _mm_xor_si128(_mm_slli_si128(tmp, 8), C); - z_low = _mm_unpackhi_epi64(_mm_slli_si128(C, 8), z_low); - - /* Shift one to the left (multiply by x) as gcm spec is stupid. */ - C = _mm_slli_si128(z_low, 8); - E = _mm_srli_epi64(C, 63); - D = _mm_slli_si128(z_high, 8); - F = _mm_srli_epi64(D, 63); - /* Carry over */ - C = _mm_srli_si128(z_low, 8); - D = _mm_srli_epi64(C, 63); - z_low = _mm_or_si128(_mm_slli_epi64(z_low, 1), E); - z_high = _mm_or_si128(_mm_or_si128(_mm_slli_epi64(z_high, 1), F), D); - - /* Reduce */ - C = _mm_slli_si128(z_low, 8); - /* D = z_low << 127 */ - D = _mm_slli_epi64(C, 63); - /* E = z_low << 126 */ - E = _mm_slli_epi64(C, 62); - /* F = z_low << 121 */ - F = _mm_slli_epi64(C, 57); - /* z_low ^= (z_low << 127) ^ (z_low << 126) ^ (z_low << 121); */ - z_low = _mm_xor_si128(_mm_xor_si128(_mm_xor_si128(z_low, D), E), F); - C = _mm_srli_si128(z_low, 8); - /* D = z_low >> 1 */ - D = _mm_slli_epi64(C, 63); - D = _mm_or_si128(_mm_srli_epi64(z_low, 1), D); - /* E = z_low >> 2 */ - E = _mm_slli_epi64(C, 62); - E = _mm_or_si128(_mm_srli_epi64(z_low, 2), E); - /* F = z_low >> 7 */ - F = _mm_slli_epi64(C, 57); - F = _mm_or_si128(_mm_srli_epi64(z_low, 7), F); - /* ghash->x ^= z_low ^ (z_low >> 1) ^ (z_low >> 2) ^ (z_low >> 7); */ - ghash->x = _mm_xor_si128(_mm_xor_si128( - _mm_xor_si128(_mm_xor_si128(z_high, z_low), D), E), - F); - } - return SECSuccess; -#else - PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); - return SECFailure; -#endif /* NSS_X86_OR_X64 */ -} - static SECStatus gcm_zeroX(gcmHashContext *ghash) { + SECStatus rv = SECSuccess; + if (ghash->hw) { -#ifdef NSS_X86_OR_X64 - ghash->x = _mm_setzero_si128(); - return SECSuccess; -#else - PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); - return SECFailure; -#endif /* NSS_X86_OR_X64 */ + rv = gcm_HashZeroX_hw(ghash); } ghash->x_high = ghash->x_low = 0; - return SECSuccess; + return rv; } /* @@ -503,15 +442,10 @@ gcmHash_Final(gcmHashContext *ghash, unsigned char *outbuf, } if (ghash->hw) { -#ifdef NSS_X86_OR_X64 - uint64_t tmp_out[2]; - _mm_storeu_si128((__m128i *)tmp_out, ghash->x); - WRITE64(tmp_out[0], T + 8); - WRITE64(tmp_out[1], T); -#else - PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); - return SECFailure; -#endif /* NSS_X86_OR_X64 */ + rv = gcm_HashWrite_hw(ghash, T); + if (rv != SECSuccess) { + goto cleanup; + } } else { WRITE64(ghash->x_low, T + 8); WRITE64(ghash->x_high, T); @@ -595,14 +529,7 @@ GCM_CreateContext(void *context, freeblCipherFunc cipher, if (gcm == NULL) { return NULL; } - /* aligned_alloc is C11 so we have to do it the old way. */ - ghash = PORT_ZAlloc(sizeof(gcmHashContext) + 15); - if (ghash == NULL) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - ghash->mem = ghash; - ghash = (gcmHashContext *)(((uintptr_t)ghash + 15) & ~(uintptr_t)0x0F); + ghash = PORT_ZNewAligned(gcmHashContext, 16, mem); /* first plug in the ghash context */ gcm->ghash_context = ghash; diff --git a/security/nss/lib/freebl/gcm.h b/security/nss/lib/freebl/gcm.h index 0c707a081..42ef0f717 100644 --- a/security/nss/lib/freebl/gcm.h +++ b/security/nss/lib/freebl/gcm.h @@ -9,7 +9,21 @@ #include <stdint.h> #ifdef NSS_X86_OR_X64 +/* GCC <= 4.8 doesn't support including emmintrin.h without enabling SSE2 */ +#if !defined(__clang__) && defined(__GNUC__) && defined(__GNUC_MINOR__) && \ + (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ <= 8)) +#pragma GCC push_options +#pragma GCC target("sse2") +#undef NSS_DISABLE_SSE2 +#define NSS_DISABLE_SSE2 1 +#endif /* GCC <= 4.8 */ + #include <emmintrin.h> /* __m128i */ + +#ifdef NSS_DISABLE_SSE2 +#undef NSS_DISABLE_SSE2 +#pragma GCC pop_options +#endif /* NSS_DISABLE_SSE2 */ #endif SEC_BEGIN_PROTOS diff --git a/security/nss/lib/freebl/ldvector.c b/security/nss/lib/freebl/ldvector.c index 2447a0c9f..d39965256 100644 --- a/security/nss/lib/freebl/ldvector.c +++ b/security/nss/lib/freebl/ldvector.c @@ -298,9 +298,25 @@ static const struct FREEBLVectorStr vector = /* End of Version 3.018 */ - EC_GetPointSize + EC_GetPointSize, /* End of Version 3.019 */ + + BLAKE2B_Hash, + BLAKE2B_HashBuf, + BLAKE2B_MAC_HashBuf, + BLAKE2B_NewContext, + BLAKE2B_DestroyContext, + BLAKE2B_Begin, + BLAKE2B_MAC_Begin, + BLAKE2B_Update, + BLAKE2B_End, + BLAKE2B_FlattenSize, + BLAKE2B_Flatten, + BLAKE2B_Resurrect + + /* End of Version 3.020 */ + }; const FREEBLVector* @@ -320,8 +336,12 @@ FREEBL_GetVector(void) return NULL; } #endif - /* make sure the Full self tests have been run before continuing */ + +#ifndef NSS_FIPS_DISABLED + /* In FIPS mode make sure the Full self tests have been run before + * continuing. */ BL_POSTRan(PR_FALSE); +#endif return &vector; } diff --git a/security/nss/lib/freebl/loader.c b/security/nss/lib/freebl/loader.c index 792171b08..fe5e0a668 100644 --- a/security/nss/lib/freebl/loader.c +++ b/security/nss/lib/freebl/loader.c @@ -2124,3 +2124,114 @@ EC_GetPointSize(const ECParams *params) return SECFailure; return (vector->p_EC_GetPointSize)(params); } + +SECStatus +BLAKE2B_Hash(unsigned char *dest, const char *src) +{ + if (!vector && PR_SUCCESS != freebl_RunLoaderOnce()) { + return SECFailure; + } + return (vector->p_BLAKE2B_Hash)(dest, src); +} + +SECStatus +BLAKE2B_HashBuf(unsigned char *output, const unsigned char *input, PRUint32 inlen) +{ + if (!vector && PR_SUCCESS != freebl_RunLoaderOnce()) { + return SECFailure; + } + return (vector->p_BLAKE2B_HashBuf)(output, input, inlen); +} + +SECStatus +BLAKE2B_MAC_HashBuf(unsigned char *output, const unsigned char *input, + unsigned int inlen, const unsigned char *key, + unsigned int keylen) +{ + if (!vector && PR_SUCCESS != freebl_RunLoaderOnce()) { + return SECFailure; + } + return (vector->p_BLAKE2B_MAC_HashBuf)(output, input, inlen, key, keylen); +} + +BLAKE2BContext * +BLAKE2B_NewContext(void) +{ + if (!vector && PR_SUCCESS != freebl_RunLoaderOnce()) { + return NULL; + } + return (vector->p_BLAKE2B_NewContext)(); +} + +void +BLAKE2B_DestroyContext(BLAKE2BContext *BLAKE2BContext, PRBool freeit) +{ + if (!vector && PR_SUCCESS != freebl_RunLoaderOnce()) { + return; + } + (vector->p_BLAKE2B_DestroyContext)(BLAKE2BContext, freeit); +} + +SECStatus +BLAKE2B_Begin(BLAKE2BContext *ctx) +{ + if (!vector && PR_SUCCESS != freebl_RunLoaderOnce()) { + return SECFailure; + } + return (vector->p_BLAKE2B_Begin)(ctx); +} + +SECStatus +BLAKE2B_MAC_Begin(BLAKE2BContext *ctx, const PRUint8 *key, const size_t keylen) +{ + if (!vector && PR_SUCCESS != freebl_RunLoaderOnce()) { + return SECFailure; + } + return (vector->p_BLAKE2B_MAC_Begin)(ctx, key, keylen); +} + +SECStatus +BLAKE2B_Update(BLAKE2BContext *ctx, const unsigned char *in, unsigned int inlen) +{ + if (!vector && PR_SUCCESS != freebl_RunLoaderOnce()) { + return SECFailure; + } + return (vector->p_BLAKE2B_Update)(ctx, in, inlen); +} + +SECStatus +BLAKE2B_End(BLAKE2BContext *ctx, unsigned char *out, + unsigned int *digestLen, size_t maxDigestLen) +{ + if (!vector && PR_SUCCESS != freebl_RunLoaderOnce()) { + return SECFailure; + } + return (vector->p_BLAKE2B_End)(ctx, out, digestLen, maxDigestLen); +} + +unsigned int +BLAKE2B_FlattenSize(BLAKE2BContext *ctx) +{ + if (!vector && PR_SUCCESS != freebl_RunLoaderOnce()) { + return 0; + } + return (vector->p_BLAKE2B_FlattenSize)(ctx); +} + +SECStatus +BLAKE2B_Flatten(BLAKE2BContext *ctx, unsigned char *space) +{ + if (!vector && PR_SUCCESS != freebl_RunLoaderOnce()) { + return SECFailure; + } + return (vector->p_BLAKE2B_Flatten)(ctx, space); +} + +BLAKE2BContext * +BLAKE2B_Resurrect(unsigned char *space, void *arg) +{ + if (!vector && PR_SUCCESS != freebl_RunLoaderOnce()) { + return NULL; + } + return (vector->p_BLAKE2B_Resurrect)(space, arg); +} diff --git a/security/nss/lib/freebl/loader.h b/security/nss/lib/freebl/loader.h index ed392cc47..ff10cf9ba 100644 --- a/security/nss/lib/freebl/loader.h +++ b/security/nss/lib/freebl/loader.h @@ -10,7 +10,7 @@ #include "blapi.h" -#define FREEBL_VERSION 0x0313 +#define FREEBL_VERSION 0x0314 struct FREEBLVectorStr { @@ -736,6 +736,29 @@ struct FREEBLVectorStr { /* Version 3.019 came to here */ + SECStatus (*p_BLAKE2B_Hash)(unsigned char *dest, const char *src); + SECStatus (*p_BLAKE2B_HashBuf)(unsigned char *output, + const unsigned char *input, PRUint32 inlen); + SECStatus (*p_BLAKE2B_MAC_HashBuf)(unsigned char *output, + const unsigned char *input, + unsigned int inlen, + const unsigned char *key, + unsigned int keylen); + BLAKE2BContext *(*p_BLAKE2B_NewContext)(); + void (*p_BLAKE2B_DestroyContext)(BLAKE2BContext *ctx, PRBool freeit); + SECStatus (*p_BLAKE2B_Begin)(BLAKE2BContext *ctx); + SECStatus (*p_BLAKE2B_MAC_Begin)(BLAKE2BContext *ctx, const PRUint8 *key, + const size_t keylen); + SECStatus (*p_BLAKE2B_Update)(BLAKE2BContext *ctx, const unsigned char *in, + unsigned int inlen); + SECStatus (*p_BLAKE2B_End)(BLAKE2BContext *ctx, unsigned char *out, + unsigned int *digestLen, size_t maxDigestLen); + unsigned int (*p_BLAKE2B_FlattenSize)(BLAKE2BContext *ctx); + SECStatus (*p_BLAKE2B_Flatten)(BLAKE2BContext *ctx, unsigned char *space); + BLAKE2BContext *(*p_BLAKE2B_Resurrect)(unsigned char *space, void *arg); + + /* Version 3.020 came to here */ + /* Add new function pointers at the end of this struct and bump * FREEBL_VERSION at the beginning of this file. */ }; diff --git a/security/nss/lib/freebl/lowhash_vector.c b/security/nss/lib/freebl/lowhash_vector.c index 7690c98da..be53bbdc6 100644 --- a/security/nss/lib/freebl/lowhash_vector.c +++ b/security/nss/lib/freebl/lowhash_vector.c @@ -102,13 +102,13 @@ freebl_LoadDSO(void) static PRCallOnceType loadFreeBLOnce; -static PRStatus +static void freebl_RunLoaderOnce(void) { /* Don't have NSPR, so can use the real PR_CallOnce, implement a stripped * down version. */ if (loadFreeBLOnce.initialized) { - return loadFreeBLOnce.status; + return; } if (__sync_lock_test_and_set(&loadFreeBLOnce.inProgress, 1) == 0) { loadFreeBLOnce.status = freebl_LoadDSO(); @@ -122,17 +122,21 @@ freebl_RunLoaderOnce(void) sleep(1); /* don't have condition variables, just give up the CPU */ } } +} - return loadFreeBLOnce.status; +static const NSSLOWVector * +freebl_InitVector(void) +{ + if (!vector) { + freebl_RunLoaderOnce(); + } + return vector; } const FREEBLVector * FREEBL_GetVector(void) { - if (!vector && PR_SUCCESS != freebl_RunLoaderOnce()) { - return NULL; - } - if (vector) { + if (freebl_InitVector()) { return (vector->p_FREEBL_GetVector)(); } return NULL; @@ -141,25 +145,26 @@ FREEBL_GetVector(void) NSSLOWInitContext * NSSLOW_Init(void) { - if (!vector && PR_SUCCESS != freebl_RunLoaderOnce()) - return NULL; - return (vector->p_NSSLOW_Init)(); + if (freebl_InitVector()) { + return (vector->p_NSSLOW_Init)(); + } + return NULL; } void NSSLOW_Shutdown(NSSLOWInitContext *context) { - if (!vector && PR_SUCCESS != freebl_RunLoaderOnce()) - return; - (vector->p_NSSLOW_Shutdown)(context); + if (freebl_InitVector()) { + (vector->p_NSSLOW_Shutdown)(context); + } } void NSSLOW_Reset(NSSLOWInitContext *context) { - if (!vector && PR_SUCCESS != freebl_RunLoaderOnce()) - return; - (vector->p_NSSLOW_Reset)(context); + if (freebl_InitVector()) { + (vector->p_NSSLOW_Reset)(context); + } } NSSLOWHASHContext * @@ -167,17 +172,18 @@ NSSLOWHASH_NewContext( NSSLOWInitContext *initContext, HASH_HashType hashType) { - if (!vector && PR_SUCCESS != freebl_RunLoaderOnce()) - return NULL; - return (vector->p_NSSLOWHASH_NewContext)(initContext, hashType); + if (freebl_InitVector()) { + return (vector->p_NSSLOWHASH_NewContext)(initContext, hashType); + } + return NULL; } void NSSLOWHASH_Begin(NSSLOWHASHContext *context) { - if (!vector && PR_SUCCESS != freebl_RunLoaderOnce()) - return; - (vector->p_NSSLOWHASH_Begin)(context); + if (freebl_InitVector()) { + (vector->p_NSSLOWHASH_Begin)(context); + } } void @@ -185,9 +191,9 @@ NSSLOWHASH_Update(NSSLOWHASHContext *context, const unsigned char *buf, unsigned int len) { - if (!vector && PR_SUCCESS != freebl_RunLoaderOnce()) - return; - (vector->p_NSSLOWHASH_Update)(context, buf, len); + if (freebl_InitVector()) { + (vector->p_NSSLOWHASH_Update)(context, buf, len); + } } void @@ -195,23 +201,24 @@ NSSLOWHASH_End(NSSLOWHASHContext *context, unsigned char *buf, unsigned int *ret, unsigned int len) { - if (!vector && PR_SUCCESS != freebl_RunLoaderOnce()) - return; - (vector->p_NSSLOWHASH_End)(context, buf, ret, len); + if (freebl_InitVector()) { + (vector->p_NSSLOWHASH_End)(context, buf, ret, len); + } } void NSSLOWHASH_Destroy(NSSLOWHASHContext *context) { - if (!vector && PR_SUCCESS != freebl_RunLoaderOnce()) - return; - (vector->p_NSSLOWHASH_Destroy)(context); + if (freebl_InitVector()) { + (vector->p_NSSLOWHASH_Destroy)(context); + } } unsigned int NSSLOWHASH_Length(NSSLOWHASHContext *context) { - if (!vector && PR_SUCCESS != freebl_RunLoaderOnce()) - return -1; - return (vector->p_NSSLOWHASH_Length)(context); + if (freebl_InitVector()) { + return (vector->p_NSSLOWHASH_Length)(context); + } + return -1; } diff --git a/security/nss/lib/freebl/manifest.mn b/security/nss/lib/freebl/manifest.mn index bf8144218..e4c9ab0b7 100644 --- a/security/nss/lib/freebl/manifest.mn +++ b/security/nss/lib/freebl/manifest.mn @@ -1,10 +1,10 @@ -# +# # 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/. # NOTE: any ifdefs in this file must be defined on the gmake command line -# (if anywhere). They cannot come from Makefile or config.mk +# (if anywhere). They cannot come from Makefile or config.mk CORE_DEPTH = ../.. @@ -75,7 +75,7 @@ DEFINES += -DSHLIB_SUFFIX=\"$(DLL_SUFFIX)\" -DSHLIB_PREFIX=\"$(DLL_PREFIX)\" \ -DSHLIB_VERSION=\"$(LIBRARY_VERSION)\" \ -DSOFTOKEN_SHLIB_VERSION=\"$(SOFTOKEN_LIBRARY_VERSION)\" -REQUIRES = +REQUIRES = EXPORTS = \ blapit.h \ @@ -86,6 +86,7 @@ EXPORTS = \ PRIVATE_EXPORTS = \ alghmac.h \ + blake2b.h \ blapi.h \ chacha20poly1305.h \ hmacct.h \ @@ -102,16 +103,13 @@ MPI_SRCS = mpprime.c mpmontg.c mplogic.c mpi.c mp_gf2m.c ECL_HDRS = ecl-exp.h ecl.h ecp.h ecl-priv.h -ifndef NSS_DISABLE_ECC ECL_SRCS = ecl.c ecl_mult.c ecl_gf.c \ ecp_aff.c ecp_jac.c ecp_mont.c \ ec_naf.c ecp_jm.c ecp_256.c ecp_384.c ecp_521.c \ ecp_256_32.c ecp_25519.c -else -ECL_SRCS = $(NULL) -endif SHA_SRCS = sha_fast.c MPCPU_SRCS = mpcpucache.c +VERIFIED_SRCS = $(NULL) CSRCS = \ freeblver.c \ @@ -126,6 +124,8 @@ CSRCS = \ alg2268.c \ arcfour.c \ arcfive.c \ + crypto_primitives.c \ + blake2b.c \ desblapi.c \ des.c \ drbg.c \ @@ -153,6 +153,7 @@ CSRCS = \ $(MPI_SRCS) \ $(MPCPU_SRCS) \ $(ECL_SRCS) \ + $(VERIFIED_SRCS) \ $(STUBS_SRCS) \ $(LOWHASH_SRCS) \ $(EXTRA_SRCS) \ @@ -162,6 +163,7 @@ ALL_CSRCS := $(CSRCS) ALL_HDRS = \ alghmac.h \ + blake2b.h \ blapi.h \ blapit.h \ des.h \ @@ -178,12 +180,6 @@ ALL_HDRS = \ $(NULL) -ifdef AES_GEN_TBL -DEFINES += -DRIJNDAEL_GENERATE_TABLES -else -ifdef AES_GEN_TBL_M -DEFINES += -DRIJNDAEL_GENERATE_TABLES_MACRO -else ifdef AES_GEN_VAL DEFINES += -DRIJNDAEL_GENERATE_VALUES else @@ -193,5 +189,3 @@ else DEFINES += -DRIJNDAEL_INCLUDE_TABLES endif endif -endif -endif diff --git a/security/nss/lib/freebl/mpi/README b/security/nss/lib/freebl/mpi/README index 776ba713a..cf4302758 100644 --- a/security/nss/lib/freebl/mpi/README +++ b/security/nss/lib/freebl/mpi/README @@ -53,7 +53,7 @@ to change are: single digit. This is just a printf() format string, so you can adjust it appropriately. -(3) The macros DIGIT_MAX and MP_WORD_MAX, which specify the +(3) The macros DIGIT_MAX and MP_WORD_MAX, which specify the largest value expressible in an mp_digit and an mp_word, respectively. @@ -345,7 +345,7 @@ returns values of x and y satisfying Bezout's identity. This is used by mp_invmod() to find modular inverses. However, if you do not need these values, you will find that mp_gcd() is MUCH more efficient, since it doesn't need all the intermediate values that mp_xgcd() -requires in order to compute x and y. +requires in order to compute x and y. The mp_gcd() (and mp_xgcd()) functions use the binary (extended) GCD algorithm due to Josef Stein. @@ -361,7 +361,7 @@ mp_read_radix(mp, str, r) - convert a string in radix r to an mp_int mp_read_raw(mp, s, len) - convert a string of bytes to an mp_int mp_radix_size(mp, r) - return length of buffer needed by mp_toradix() mp_raw_size(mp) - return length of buffer needed by mp_toraw() -mp_toradix(mp, str, r) - convert an mp_int to a string of radix r +mp_toradix(mp, str, r) - convert an mp_int to a string of radix r digits mp_toraw(mp, str) - convert an mp_int to a string of bytes mp_tovalue(ch, r) - convert ch to its value when taken as @@ -387,7 +387,7 @@ The mp_read_radix() and mp_toradix() functions support bases from 2 to than this, you will need to write them yourself (that's why mp_div_d() is provided, after all). -Note: mp_read_radix() will accept as digits either capital or +Note: mp_read_radix() will accept as digits either capital or ---- lower-case letters. However, the current implementation of mp_toradix() only outputs upper-case letters, when writing bases betwee 10 and 36. The underlying code supports using @@ -448,14 +448,14 @@ Note: The mpp_random() and mpp_random_size() functions use the C to change. mpp_divis_vector(a, v, s, w) - is a divisible by any of the s digits - in v? If so, let w be the index of + in v? If so, let w be the index of that digit mpp_divis_primes(a, np) - is a divisible by any of the first np - primes? If so, set np to the prime + primes? If so, set np to the prime which divided a. -mpp_fermat(a, d) - test if w^a = w (mod a). If so, +mpp_fermat(a, d) - test if w^a = w (mod a). If so, returns MP_YES, otherwise MP_NO. mpp_pprime(a, nt) - perform nt iterations of the Rabin- @@ -486,7 +486,7 @@ The file 'mpi-config.h' defines several configurable parameters for the library, which you can adjust to suit your application. At the time of this writing, the available options are: -MP_IOFUNC - Define true to include the mp_print() function, +MP_IOFUNC - Define true to include the mp_print() function, which is moderately useful for debugging. This implicitly includes <stdio.h>. @@ -502,21 +502,14 @@ MP_LOGTAB - If true, the file "logtab.h" is included, which the library includes <math.h> and uses log(). This typically forces you to link against math libraries. -MP_MEMSET - If true, use memset() to zero buffers. If you run - into weird alignment related bugs, set this to zero - and an explicit loop will be used. - -MP_MEMCPY - If true, use memcpy() to copy buffers. If you run - into weird alignment bugs, set this to zero and an - explicit loop will be used. MP_ARGCHK - Set to 0, 1, or 2. This defines how the argument - checking macro, ARGCHK(), gets expanded. If this - is set to zero, ARGCHK() expands to nothing; no + checking macro, ARGCHK(), gets expanded. If this + is set to zero, ARGCHK() expands to nothing; no argument checks are performed. If this is 1, the ARGCHK() macro expands to code that returns MP_BADARG - or similar at runtime. If it is 2, ARGCHK() expands - to an assert() call that aborts the program on a + or similar at runtime. If it is 2, ARGCHK() expands + to an assert() call that aborts the program on a bad input. MP_DEBUG - Turns on debugging output. This is probably not at @@ -528,14 +521,14 @@ MP_DEFPREC - The default precision of a newly-created mp_int, in the mp_set_prec() function, but this is its initial value. -MP_SQUARE - If this is set to a nonzero value, the mp_sqr() +MP_SQUARE - If this is set to a nonzero value, the mp_sqr() function will use an alternate algorithm that takes advantage of the redundant inner product computation when both multiplicands are identical. Unfortunately, with some compilers this is actually SLOWER than just calling mp_mul() with the same argument twice. So if you set MP_SQUARE to zero, mp_sqr() will be expan- - ded into a call to mp_mul(). This applies to all + ded into a call to mp_mul(). This applies to all the uses of mp_sqr(), including mp_sqrmod() and the internal calls to s_mp_sqr() inside mpi.c @@ -568,7 +561,7 @@ CFLAGS=-ansi -pedantic -Wall -O2 If all goes well, the library should compile without warnings using this combination. You should, of course, make whatever adjustments -you find necessary. +you find necessary. The MPI library distribution comes with several additional programs which are intended to demonstrate the use of the library, and provide @@ -580,7 +573,7 @@ directory) for manipulating large numbers. These include: basecvt.c A radix-conversion program, supporting bases from 2 to 64 inclusive. -bbsrand.c A BBS (quadratic residue) pseudo-random number +bbsrand.c A BBS (quadratic residue) pseudo-random number generator. The file 'bbsrand.c' is just the driver for the program; the real code lives in the files 'bbs_rand.h' and 'bbs_rand.c' @@ -626,7 +619,7 @@ Acknowledgements: ---------------- The algorithms used in this library were drawn primarily from Volume -2 of Donald Knuth's magnum opus, _The Art of Computer Programming_, +2 of Donald Knuth's magnum opus, _The Art of Computer Programming_, "Semi-Numerical Methods". Barrett's algorithm for modular reduction came from Menezes, Oorschot, and Vanstone's _Handbook of Applied Cryptography_, Chapter 14. diff --git a/security/nss/lib/freebl/mpi/mpi-config.h b/security/nss/lib/freebl/mpi/mpi-config.h index c6f72b206..0cc868a14 100644 --- a/security/nss/lib/freebl/mpi/mpi-config.h +++ b/security/nss/lib/freebl/mpi/mpi-config.h @@ -28,14 +28,6 @@ #define MP_LOGTAB 1 /* use table of logs instead of log()? */ #endif -#ifndef MP_MEMSET -#define MP_MEMSET 1 /* use memset() to zero buffers? */ -#endif - -#ifndef MP_MEMCPY -#define MP_MEMCPY 1 /* use memcpy() to copy buffers? */ -#endif - #ifndef MP_ARGCHK /* 0 = no parameter checks diff --git a/security/nss/lib/freebl/mpi/mpi.c b/security/nss/lib/freebl/mpi/mpi.c index f7784c8d9..ae404019d 100644 --- a/security/nss/lib/freebl/mpi/mpi.c +++ b/security/nss/lib/freebl/mpi/mpi.c @@ -2782,15 +2782,7 @@ s_mp_pad(mp_int *mp, mp_size min) void s_mp_setz(mp_digit *dp, mp_size count) { -#if MP_MEMSET == 0 - int ix; - - for (ix = 0; ix < count; ix++) - dp[ix] = 0; -#else memset(dp, 0, count * sizeof(mp_digit)); -#endif - } /* end s_mp_setz() */ /* }}} */ @@ -2801,14 +2793,7 @@ s_mp_setz(mp_digit *dp, mp_size count) void s_mp_copy(const mp_digit *sp, mp_digit *dp, mp_size count) { -#if MP_MEMCPY == 0 - int ix; - - for (ix = 0; ix < count; ix++) - dp[ix] = sp[ix]; -#else memcpy(dp, sp, count * sizeof(mp_digit)); -#endif } /* end s_mp_copy() */ /* }}} */ diff --git a/security/nss/lib/freebl/nsslowhash.c b/security/nss/lib/freebl/nsslowhash.c index 5ed039689..22f97810f 100644 --- a/security/nss/lib/freebl/nsslowhash.c +++ b/security/nss/lib/freebl/nsslowhash.c @@ -22,6 +22,7 @@ struct NSSLOWHASHContextStr { void *hashCtxt; }; +#ifndef NSS_FIPS_DISABLED static int nsslow_GetFIPSEnabled(void) { @@ -40,9 +41,10 @@ nsslow_GetFIPSEnabled(void) return 0; if (d != '1') return 0; -#endif +#endif /* LINUX */ return 1; } +#endif /* NSS_FIPS_DISABLED */ static NSSLOWInitContext dummyContext = { 0 }; static PRBool post_failed = PR_TRUE; @@ -54,6 +56,7 @@ NSSLOW_Init(void) (void)FREEBL_InitStubs(); #endif +#ifndef NSS_FIPS_DISABLED /* make sure the FIPS product is installed if we are trying to * go into FIPS mode */ if (nsslow_GetFIPSEnabled()) { @@ -63,6 +66,7 @@ NSSLOW_Init(void) return NULL; } } +#endif post_failed = PR_FALSE; return &dummyContext; diff --git a/security/nss/lib/freebl/poly1305.h b/security/nss/lib/freebl/poly1305.h index 0a463483f..125f49b3b 100644 --- a/security/nss/lib/freebl/poly1305.h +++ b/security/nss/lib/freebl/poly1305.h @@ -8,6 +8,8 @@ #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 diff --git a/security/nss/lib/freebl/rijndael.c b/security/nss/lib/freebl/rijndael.c index e4ad60388..5de27de9c 100644 --- a/security/nss/lib/freebl/rijndael.c +++ b/security/nss/lib/freebl/rijndael.c @@ -27,16 +27,39 @@ #include "intel-gcm.h" #endif /* INTEL_GCM */ +/* Forward declarations */ +void rijndael_native_key_expansion(AESContext *cx, const unsigned char *key, + unsigned int Nk); +void rijndael_native_encryptBlock(AESContext *cx, + unsigned char *output, + const unsigned char *input); + +/* Stub definitions for the above rijndael_native_* functions, which + * shouldn't be used unless NSS_X86_OR_X64 is defined */ +#ifndef NSS_X86_OR_X64 +void +rijndael_native_key_expansion(AESContext *cx, const unsigned char *key, + unsigned int Nk) +{ + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + PORT_Assert(0); +} + +void +rijndael_native_encryptBlock(AESContext *cx, + unsigned char *output, + const unsigned char *input) +{ + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + PORT_Assert(0); +} +#endif /* NSS_X86_OR_X64 */ + /* - * There are currently five ways to build this code, varying in performance + * There are currently three ways to build this code, varying in performance * and code size. * * RIJNDAEL_INCLUDE_TABLES Include all tables from rijndael32.tab - * RIJNDAEL_GENERATE_TABLES Generate tables on first - * encryption/decryption, then store them; - * use the function gfm - * RIJNDAEL_GENERATE_TABLES_MACRO Same as above, but use macros to do - * the generation * RIJNDAEL_GENERATE_VALUES Do not store tables, generate the table * values "on-the-fly", using gfm * RIJNDAEL_GENERATE_VALUES_MACRO Same as above, but use macros @@ -108,8 +131,7 @@ ((a & 0x80) ? ((a << 1) ^ 0x1b) : (a << 1)) /* Choose GFM method (macros or function) */ -#if defined(RIJNDAEL_GENERATE_TABLES_MACRO) || \ - defined(RIJNDAEL_GENERATE_VALUES_MACRO) +#if defined(RIJNDAEL_GENERATE_VALUES_MACRO) /* * Galois field GF(2**8) multipliers, in macro form @@ -133,7 +155,7 @@ #define GFM0E(a) \ (GFM02(a) ^ GFM04(a) ^ GFM08(a)) /* a * 0E = a * (02 + 04 + 08) */ -#else /* RIJNDAEL_GENERATE_TABLES or RIJNDAEL_GENERATE_VALUES */ +#else /* RIJNDAEL_GENERATE_VALUES */ /* GF_MULTIPLY * @@ -244,7 +266,7 @@ gen_TInvXi(PRUint8 tx, PRUint8 i) #define IMXC1(b) G_IMXC1(b) #define IMXC2(b) G_IMXC2(b) #define IMXC3(b) G_IMXC3(b) -#elif defined(RIJNDAEL_GENERATE_VALUES_MACRO) +#else /* RIJNDAEL_GENERATE_VALUES_MACRO */ /* generate values for the tables with macros */ #define T0(i) G_T0(i) #define T1(i) G_T1(i) @@ -258,84 +280,10 @@ gen_TInvXi(PRUint8 tx, PRUint8 i) #define IMXC1(b) G_IMXC1(b) #define IMXC2(b) G_IMXC2(b) #define IMXC3(b) G_IMXC3(b) -#else /* RIJNDAEL_GENERATE_TABLES or RIJNDAEL_GENERATE_TABLES_MACRO */ -/* Generate T and T**-1 table values and store, then index */ -/* The inverse mix column tables are still generated */ -#define T0(i) rijndaelTables->T0[i] -#define T1(i) rijndaelTables->T1[i] -#define T2(i) rijndaelTables->T2[i] -#define T3(i) rijndaelTables->T3[i] -#define TInv0(i) rijndaelTables->TInv0[i] -#define TInv1(i) rijndaelTables->TInv1[i] -#define TInv2(i) rijndaelTables->TInv2[i] -#define TInv3(i) rijndaelTables->TInv3[i] -#define IMXC0(b) G_IMXC0(b) -#define IMXC1(b) G_IMXC1(b) -#define IMXC2(b) G_IMXC2(b) -#define IMXC3(b) G_IMXC3(b) #endif /* choose T-table indexing method */ #endif /* not RIJNDAEL_INCLUDE_TABLES */ -#if defined(RIJNDAEL_GENERATE_TABLES) || \ - defined(RIJNDAEL_GENERATE_TABLES_MACRO) - -/* Code to generate and store the tables */ - -struct rijndael_tables_str { - PRUint32 T0[256]; - PRUint32 T1[256]; - PRUint32 T2[256]; - PRUint32 T3[256]; - PRUint32 TInv0[256]; - PRUint32 TInv1[256]; - PRUint32 TInv2[256]; - PRUint32 TInv3[256]; -}; - -static struct rijndael_tables_str *rijndaelTables = NULL; -static PRCallOnceType coRTInit = { 0, 0, 0 }; -static PRStatus -init_rijndael_tables(void) -{ - PRUint32 i; - PRUint8 si01, si02, si03, si04, si08, si09, si0B, si0D, si0E; - struct rijndael_tables_str *rts; - rts = (struct rijndael_tables_str *) - PORT_Alloc(sizeof(struct rijndael_tables_str)); - if (!rts) - return PR_FAILURE; - for (i = 0; i < 256; i++) { - /* The forward values */ - si01 = SBOX(i); - si02 = XTIME(si01); - si03 = si02 ^ si01; - rts->T0[i] = WORD4(si02, si01, si01, si03); - rts->T1[i] = WORD4(si03, si02, si01, si01); - rts->T2[i] = WORD4(si01, si03, si02, si01); - rts->T3[i] = WORD4(si01, si01, si03, si02); - /* The inverse values */ - si01 = SINV(i); - si02 = XTIME(si01); - si04 = XTIME(si02); - si08 = XTIME(si04); - si03 = si02 ^ si01; - si09 = si08 ^ si01; - si0B = si08 ^ si03; - si0D = si09 ^ si04; - si0E = si08 ^ si04 ^ si02; - rts->TInv0[i] = WORD4(si0E, si09, si0D, si0B); - rts->TInv1[i] = WORD4(si0B, si0E, si09, si0D); - rts->TInv2[i] = WORD4(si0D, si0B, si0E, si09); - rts->TInv3[i] = WORD4(si09, si0D, si0B, si0E); - } - /* wait until all the values are in to set */ - rijndaelTables = rts; - return PR_SUCCESS; -} - -#endif /* code to generate tables */ - /************************************************************************** * * Stuff related to the Rijndael key schedule @@ -389,162 +337,6 @@ rijndael_key_expansion7(AESContext *cx, const unsigned char *key, unsigned int N } } -#if defined(NSS_X86_OR_X64) -#define EXPAND_KEY128(k, rcon, res) \ - tmp_key = _mm_aeskeygenassist_si128(k, rcon); \ - tmp_key = _mm_shuffle_epi32(tmp_key, 0xFF); \ - tmp = _mm_xor_si128(k, _mm_slli_si128(k, 4)); \ - tmp = _mm_xor_si128(tmp, _mm_slli_si128(tmp, 4)); \ - tmp = _mm_xor_si128(tmp, _mm_slli_si128(tmp, 4)); \ - res = _mm_xor_si128(tmp, tmp_key) - -static void -native_key_expansion128(AESContext *cx, const unsigned char *key) -{ - __m128i *keySchedule = cx->keySchedule; - pre_align __m128i tmp_key post_align; - pre_align __m128i tmp post_align; - keySchedule[0] = _mm_loadu_si128((__m128i *)key); - EXPAND_KEY128(keySchedule[0], 0x01, keySchedule[1]); - EXPAND_KEY128(keySchedule[1], 0x02, keySchedule[2]); - EXPAND_KEY128(keySchedule[2], 0x04, keySchedule[3]); - EXPAND_KEY128(keySchedule[3], 0x08, keySchedule[4]); - EXPAND_KEY128(keySchedule[4], 0x10, keySchedule[5]); - EXPAND_KEY128(keySchedule[5], 0x20, keySchedule[6]); - EXPAND_KEY128(keySchedule[6], 0x40, keySchedule[7]); - EXPAND_KEY128(keySchedule[7], 0x80, keySchedule[8]); - EXPAND_KEY128(keySchedule[8], 0x1B, keySchedule[9]); - EXPAND_KEY128(keySchedule[9], 0x36, keySchedule[10]); -} - -#define EXPAND_KEY192_PART1(res, k0, kt, rcon) \ - tmp2 = _mm_slli_si128(k0, 4); \ - tmp1 = _mm_xor_si128(k0, tmp2); \ - tmp2 = _mm_slli_si128(tmp2, 4); \ - tmp1 = _mm_xor_si128(_mm_xor_si128(tmp1, tmp2), _mm_slli_si128(tmp2, 4)); \ - tmp2 = _mm_aeskeygenassist_si128(kt, rcon); \ - res = _mm_xor_si128(tmp1, _mm_shuffle_epi32(tmp2, 0x55)) - -#define EXPAND_KEY192_PART2(res, k1, k2) \ - tmp2 = _mm_xor_si128(k1, _mm_slli_si128(k1, 4)); \ - res = _mm_xor_si128(tmp2, _mm_shuffle_epi32(k2, 0xFF)) - -#define EXPAND_KEY192(k0, res1, res2, res3, carry, rcon1, rcon2) \ - EXPAND_KEY192_PART1(tmp3, k0, res1, rcon1); \ - EXPAND_KEY192_PART2(carry, res1, tmp3); \ - res1 = _mm_castpd_si128(_mm_shuffle_pd(_mm_castsi128_pd(res1), \ - _mm_castsi128_pd(tmp3), 0)); \ - res2 = _mm_castpd_si128(_mm_shuffle_pd(_mm_castsi128_pd(tmp3), \ - _mm_castsi128_pd(carry), 1)); \ - EXPAND_KEY192_PART1(res3, tmp3, carry, rcon2) - -static void -native_key_expansion192(AESContext *cx, const unsigned char *key) -{ - __m128i *keySchedule = cx->keySchedule; - pre_align __m128i tmp1 post_align; - pre_align __m128i tmp2 post_align; - pre_align __m128i tmp3 post_align; - pre_align __m128i carry post_align; - keySchedule[0] = _mm_loadu_si128((__m128i *)key); - keySchedule[1] = _mm_loadu_si128((__m128i *)(key + 16)); - EXPAND_KEY192(keySchedule[0], keySchedule[1], keySchedule[2], - keySchedule[3], carry, 0x1, 0x2); - EXPAND_KEY192_PART2(keySchedule[4], carry, keySchedule[3]); - EXPAND_KEY192(keySchedule[3], keySchedule[4], keySchedule[5], - keySchedule[6], carry, 0x4, 0x8); - EXPAND_KEY192_PART2(keySchedule[7], carry, keySchedule[6]); - EXPAND_KEY192(keySchedule[6], keySchedule[7], keySchedule[8], - keySchedule[9], carry, 0x10, 0x20); - EXPAND_KEY192_PART2(keySchedule[10], carry, keySchedule[9]); - EXPAND_KEY192(keySchedule[9], keySchedule[10], keySchedule[11], - keySchedule[12], carry, 0x40, 0x80); -} - -#define EXPAND_KEY256_PART(res, rconx, k1x, k2x, X) \ - tmp_key = _mm_shuffle_epi32(_mm_aeskeygenassist_si128(k2x, rconx), X); \ - tmp2 = _mm_slli_si128(k1x, 4); \ - tmp1 = _mm_xor_si128(k1x, tmp2); \ - tmp2 = _mm_slli_si128(tmp2, 4); \ - tmp1 = _mm_xor_si128(_mm_xor_si128(tmp1, tmp2), _mm_slli_si128(tmp2, 4)); \ - res = _mm_xor_si128(tmp1, tmp_key); - -#define EXPAND_KEY256(res1, res2, k1, k2, rcon) \ - EXPAND_KEY256_PART(res1, rcon, k1, k2, 0xFF); \ - EXPAND_KEY256_PART(res2, 0x00, k2, res1, 0xAA) - -static void -native_key_expansion256(AESContext *cx, const unsigned char *key) -{ - __m128i *keySchedule = cx->keySchedule; - pre_align __m128i tmp_key post_align; - pre_align __m128i tmp1 post_align; - pre_align __m128i tmp2 post_align; - keySchedule[0] = _mm_loadu_si128((__m128i *)key); - keySchedule[1] = _mm_loadu_si128((__m128i *)(key + 16)); - EXPAND_KEY256(keySchedule[2], keySchedule[3], keySchedule[0], - keySchedule[1], 0x01); - EXPAND_KEY256(keySchedule[4], keySchedule[5], keySchedule[2], - keySchedule[3], 0x02); - EXPAND_KEY256(keySchedule[6], keySchedule[7], keySchedule[4], - keySchedule[5], 0x04); - EXPAND_KEY256(keySchedule[8], keySchedule[9], keySchedule[6], - keySchedule[7], 0x08); - EXPAND_KEY256(keySchedule[10], keySchedule[11], keySchedule[8], - keySchedule[9], 0x10); - EXPAND_KEY256(keySchedule[12], keySchedule[13], keySchedule[10], - keySchedule[11], 0x20); - EXPAND_KEY256_PART(keySchedule[14], 0x40, keySchedule[12], - keySchedule[13], 0xFF); -} - -#endif /* NSS_X86_OR_X64 */ - -/* - * AES key expansion using aes-ni instructions. - */ -static void -native_key_expansion(AESContext *cx, const unsigned char *key, unsigned int Nk) -{ -#ifdef NSS_X86_OR_X64 - switch (Nk) { - case 4: - native_key_expansion128(cx, key); - return; - case 6: - native_key_expansion192(cx, key); - return; - case 8: - native_key_expansion256(cx, key); - return; - default: - /* This shouldn't happen. */ - PORT_Assert(0); - } -#else - PORT_Assert(0); -#endif /* NSS_X86_OR_X64 */ -} - -static void -native_encryptBlock(AESContext *cx, - unsigned char *output, - const unsigned char *input) -{ -#ifdef NSS_X86_OR_X64 - int i; - pre_align __m128i m post_align = _mm_loadu_si128((__m128i *)input); - m = _mm_xor_si128(m, cx->keySchedule[0]); - for (i = 1; i < cx->Nr; ++i) { - m = _mm_aesenc_si128(m, cx->keySchedule[i]); - } - m = _mm_aesenclast_si128(m, cx->keySchedule[cx->Nr]); - _mm_storeu_si128((__m128i *)output, m); -#else - PORT_Assert(0); -#endif /* NSS_X86_OR_X64 */ -} - /* rijndael_key_expansion * * Generate the expanded key from the key input by the user. @@ -910,7 +702,7 @@ rijndael_encryptECB(AESContext *cx, unsigned char *output, if (aesni_support()) { /* Use hardware acceleration for normal AES parameters. */ - encryptor = &native_encryptBlock; + encryptor = &rijndael_native_encryptBlock; } else { encryptor = &rijndael_encryptBlock128; } @@ -1017,14 +809,7 @@ rijndael_decryptCBC(AESContext *cx, unsigned char *output, AESContext * AES_AllocateContext(void) { - /* aligned_alloc is C11 so we have to do it the old way. */ - AESContext *ctx = PORT_ZAlloc(sizeof(AESContext) + 15); - if (ctx == NULL) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - return NULL; - } - ctx->mem = ctx; - return (AESContext *)(((uintptr_t)ctx + 15) & ~(uintptr_t)0x0F); + return PORT_ZNewAligned(AESContext, 16, mem); } /* @@ -1107,22 +892,13 @@ aes_InitContext(AESContext *cx, const unsigned char *key, unsigned int keysize, } else #endif { - -#if defined(RIJNDAEL_GENERATE_TABLES) || \ - defined(RIJNDAEL_GENERATE_TABLES_MACRO) - if (rijndaelTables == NULL) { - if (PR_CallOnce(&coRTInit, init_rijndael_tables) != PR_SUCCESS) { - return SECFailure; - } - } -#endif /* Generate expanded key */ if (encrypt) { if (use_hw_aes && (cx->mode == NSS_AES_GCM || cx->mode == NSS_AES || cx->mode == NSS_AES_CTR)) { PORT_Assert(keysize == 16 || keysize == 24 || keysize == 32); /* Prepare hardware key for normal AES parameters. */ - native_key_expansion(cx, key, Nk); + rijndael_native_key_expansion(cx, key, Nk); } else { rijndael_key_expansion(cx, key, Nk); } diff --git a/security/nss/lib/freebl/rijndael.h b/security/nss/lib/freebl/rijndael.h index 1f4a8a9f7..1b63a323d 100644 --- a/security/nss/lib/freebl/rijndael.h +++ b/security/nss/lib/freebl/rijndael.h @@ -8,8 +8,22 @@ #include "blapii.h" #include <stdint.h> -#ifdef NSS_X86_OR_X64 -#include <wmmintrin.h> /* aes-ni */ +#if defined(NSS_X86_OR_X64) +/* GCC <= 4.8 doesn't support including emmintrin.h without enabling SSE2 */ +#if !defined(__clang__) && defined(__GNUC__) && defined(__GNUC_MINOR__) && \ + (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ <= 8)) +#pragma GCC push_options +#pragma GCC target("sse2") +#undef NSS_DISABLE_SSE2 +#define NSS_DISABLE_SSE2 1 +#endif /* GCC <= 4.8 */ + +#include <emmintrin.h> /* __m128i */ + +#ifdef NSS_DISABLE_SSE2 +#undef NSS_DISABLE_SSE2 +#pragma GCC pop_options +#endif /* NSS_DISABLE_SSE2 */ #endif typedef void AESBlockFunc(AESContext *cx, diff --git a/security/nss/lib/freebl/rsa.c b/security/nss/lib/freebl/rsa.c index 7354d9317..a08636de6 100644 --- a/security/nss/lib/freebl/rsa.c +++ b/security/nss/lib/freebl/rsa.c @@ -276,7 +276,10 @@ RSAPrivateKey * RSA_NewKey(int keySizeInBits, SECItem *publicExponent) { unsigned int primeLen; - mp_int p, q, e, d; + mp_int p = { 0, 0, 0, NULL }; + mp_int q = { 0, 0, 0, NULL }; + mp_int e = { 0, 0, 0, NULL }; + mp_int d = { 0, 0, 0, NULL }; int kiter; int max_attempts; mp_err err = MP_OKAY; @@ -290,34 +293,46 @@ RSA_NewKey(int keySizeInBits, SECItem *publicExponent) PORT_SetError(SEC_ERROR_INVALID_ARGS); return NULL; } - /* 1. Allocate arena & key */ + /* 1. Set the public exponent and check if it's uneven and greater than 2.*/ + MP_DIGITS(&e) = 0; + CHECK_MPI_OK(mp_init(&e)); + SECITEM_TO_MPINT(*publicExponent, &e); + if (mp_iseven(&e) || !(mp_cmp_d(&e, 2) > 0)) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + goto cleanup; + } +#ifndef NSS_FIPS_DISABLED + /* Check that the exponent is not smaller than 65537 */ + if (mp_cmp_d(&e, 0x10001) < 0) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + goto cleanup; + } +#endif + + /* 2. Allocate arena & key */ arena = PORT_NewArena(NSS_FREEBL_DEFAULT_CHUNKSIZE); if (!arena) { PORT_SetError(SEC_ERROR_NO_MEMORY); - return NULL; + goto cleanup; } key = PORT_ArenaZNew(arena, RSAPrivateKey); if (!key) { PORT_SetError(SEC_ERROR_NO_MEMORY); - PORT_FreeArena(arena, PR_TRUE); - return NULL; + goto cleanup; } key->arena = arena; /* length of primes p and q (in bytes) */ primeLen = keySizeInBits / (2 * PR_BITS_PER_BYTE); MP_DIGITS(&p) = 0; MP_DIGITS(&q) = 0; - MP_DIGITS(&e) = 0; MP_DIGITS(&d) = 0; CHECK_MPI_OK(mp_init(&p)); CHECK_MPI_OK(mp_init(&q)); - CHECK_MPI_OK(mp_init(&e)); CHECK_MPI_OK(mp_init(&d)); - /* 2. Set the version number (PKCS1 v1.5 says it should be zero) */ + /* 3. Set the version number (PKCS1 v1.5 says it should be zero) */ SECITEM_AllocItem(arena, &key->version, 1); key->version.data[0] = 0; - /* 3. Set the public exponent */ - SECITEM_TO_MPINT(*publicExponent, &e); + kiter = 0; max_attempts = 5 * (keySizeInBits / 2); /* FIPS 186-4 B.3.3 steps 4.7 and 5.8 */ do { diff --git a/security/nss/lib/freebl/sha512.c b/security/nss/lib/freebl/sha512.c index 528f884b2..c1cfb7376 100644 --- a/security/nss/lib/freebl/sha512.c +++ b/security/nss/lib/freebl/sha512.c @@ -19,6 +19,7 @@ #include "secport.h" /* for PORT_XXX */ #include "blapi.h" #include "sha256.h" /* for struct SHA256ContextStr */ +#include "crypto_primitives.h" /* ============= Common constants and defines ======================= */ @@ -648,15 +649,6 @@ SHA224_Clone(SHA224Context *dest, SHA224Context *src) /* common #defines for SHA512 and SHA384 */ #if defined(HAVE_LONG_LONG) -#if defined(_MSC_VER) -#pragma intrinsic(_rotr64, _rotl64) -#define ROTR64(x, n) _rotr64(x, n) -#define ROTL64(x, n) _rotl64(x, n) -#else -#define ROTR64(x, n) ((x >> n) | (x << (64 - n))) -#define ROTL64(x, n) ((x << n) | (x >> (64 - n))) -#endif - #define S0(x) (ROTR64(x, 28) ^ ROTR64(x, 34) ^ ROTR64(x, 39)) #define S1(x) (ROTR64(x, 14) ^ ROTR64(x, 18) ^ ROTR64(x, 41)) #define s0(x) (ROTR64(x, 1) ^ ROTR64(x, 8) ^ SHR(x, 7)) @@ -670,36 +662,7 @@ SHA224_Clone(SHA224Context *dest, SHA224Context *src) #define ULLC(hi, lo) 0x##hi##lo##ULL #endif -#if defined(IS_LITTLE_ENDIAN) -#if defined(_MSC_VER) -#pragma intrinsic(_byteswap_uint64) -#define SHA_HTONLL(x) _byteswap_uint64(x) - -#elif defined(__GNUC__) && (defined(__x86_64__) || defined(__x86_64)) -static __inline__ PRUint64 -swap8b(PRUint64 value) -{ - __asm__("bswapq %0" - : "+r"(value)); - return (value); -} -#define SHA_HTONLL(x) swap8b(x) - -#else -#define SHA_MASK16 ULLC(0000FFFF, 0000FFFF) -#define SHA_MASK8 ULLC(00FF00FF, 00FF00FF) -static PRUint64 -swap8b(PRUint64 x) -{ - PRUint64 t1 = x; - t1 = ((t1 & SHA_MASK8) << 8) | ((t1 >> 8) & SHA_MASK8); - t1 = ((t1 & SHA_MASK16) << 16) | ((t1 >> 16) & SHA_MASK16); - return (t1 >> 32) | (t1 << 32); -} -#define SHA_HTONLL(x) swap8b(x) -#endif -#define BYTESWAP8(x) x = SHA_HTONLL(x) -#endif /* defined(IS_LITTLE_ENDIAN) */ +#define BYTESWAP8(x) x = FREEBL_HTONLL(x) #else /* no long long */ @@ -708,8 +671,8 @@ swap8b(PRUint64 x) { \ 0x##lo##U, 0x##hi##U \ } -#define SHA_HTONLL(x) (BYTESWAP4(x.lo), BYTESWAP4(x.hi), \ - x.hi ^= x.lo ^= x.hi ^= x.lo, x) +#define FREEBL_HTONLL(x) (BYTESWAP4(x.lo), BYTESWAP4(x.hi), \ + x.hi ^= x.lo ^= x.hi ^= x.lo, x) #define BYTESWAP8(x) \ do { \ PRUint32 tmp; \ diff --git a/security/nss/lib/freebl/shvfy.c b/security/nss/lib/freebl/shvfy.c index bd9cd1c94..98db4614b 100644 --- a/security/nss/lib/freebl/shvfy.c +++ b/security/nss/lib/freebl/shvfy.c @@ -19,6 +19,8 @@ #include "pqg.h" #include "blapii.h" +#ifndef NSS_FIPS_DISABLED + /* * Most modern version of Linux support a speed optimization scheme where an * application called prelink modifies programs and shared libraries to quickly @@ -537,3 +539,23 @@ BLAPI_VerifySelf(const char *name) } return blapi_SHVerify(name, (PRFuncPtr)decodeInt, PR_TRUE); } + +#else /* NSS_FIPS_DISABLED */ + +PRBool +BLAPI_SHVerifyFile(const char *shName) +{ + return PR_FALSE; +} +PRBool +BLAPI_SHVerify(const char *name, PRFuncPtr addr) +{ + return PR_FALSE; +} +PRBool +BLAPI_VerifySelf(const char *name) +{ + return PR_FALSE; +} + +#endif /* NSS_FIPS_DISABLED */ diff --git a/security/nss/lib/freebl/stubs.c b/security/nss/lib/freebl/stubs.c index 8e0784935..c42f694d7 100644 --- a/security/nss/lib/freebl/stubs.c +++ b/security/nss/lib/freebl/stubs.c @@ -36,8 +36,14 @@ #include <secport.h> #include <secitem.h> #include <blapi.h> +#include <assert.h> #include <private/pprio.h> +/* Android API < 21 doesn't define RTLD_NOLOAD */ +#ifndef RTLD_NOLOAD +#define RTLD_NOLOAD 0 +#endif + #define FREEBL_NO_WEAK 1 #define WEAK __attribute__((weak)) @@ -136,6 +142,11 @@ STUB_DECLARE(int, PORT_GetError_Util, (void)); STUB_DECLARE(PLArenaPool *, PORT_NewArena_Util, (unsigned long chunksize)); STUB_DECLARE(void, PORT_SetError_Util, (int value)); STUB_DECLARE(void *, PORT_ZAlloc_Util, (size_t len)); +STUB_DECLARE(void *, PORT_ZAllocAligned_Util, (size_t bytes, size_t alignment, + void **mem)); +STUB_DECLARE(void *, PORT_ZAllocAlignedOffset_Util, (size_t bytes, + size_t alignment, + size_t offset)); STUB_DECLARE(void, PORT_ZFree_Util, (void *ptr, size_t len)); STUB_DECLARE(void, PR_Assert, (const char *s, const char *file, PRIntn ln)); @@ -174,11 +185,14 @@ STUB_DECLARE(void, SECITEM_FreeItem_Util, (SECItem * zap, PRBool freeit)); STUB_DECLARE(void, SECITEM_ZfreeItem_Util, (SECItem * zap, PRBool freeit)); STUB_DECLARE(SECOidTag, SECOID_FindOIDTag_Util, (const SECItem *oid)); STUB_DECLARE(int, NSS_SecureMemcmp, (const void *a, const void *b, size_t n)); +STUB_DECLARE(unsigned int, NSS_SecureMemcmpZero, (const void *mem, size_t n)); #define PORT_ZNew_stub(type) (type *)PORT_ZAlloc_stub(sizeof(type)) #define PORT_New_stub(type) (type *)PORT_Alloc_stub(sizeof(type)) #define PORT_ZNewArray_stub(type, num) \ (type *)PORT_ZAlloc_stub(sizeof(type) * (num)) +#define PORT_ZNewAligned_stub(type, alignment, mem) \ + (type *)PORT_ZAllocAlignedOffset_stub(sizeof(type), alignment, offsetof(type, mem)) /* * NOTE: in order to support hashing only the memory allocation stubs, @@ -214,6 +228,57 @@ PORT_ZAlloc_stub(size_t len) return ptr; } +/* aligned_alloc is C11. This is an alternative to get aligned memory. */ +extern void * +PORT_ZAllocAligned_stub(size_t bytes, size_t alignment, void **mem) +{ + STUB_SAFE_CALL3(PORT_ZAllocAligned_Util, bytes, alignment, mem); + + /* This only works if alignement is a power of 2. */ + if ((alignment == 0) || (alignment & (alignment - 1))) { + return NULL; + } + + size_t x = alignment - 1; + size_t len = (bytes ? bytes : 1) + x; + + if (!mem) { + return NULL; + } + + /* Always allocate a non-zero amount of bytes */ + *mem = malloc(len); + if (!*mem) { + return NULL; + } + + memset(*mem, 0, len); + + /* We're pretty sure this is non-zero, but let's assure scan-build too. */ + void *ret = (void *)(((uintptr_t)*mem + x) & ~(uintptr_t)x); + assert(ret); + + return ret; +} + +extern void * +PORT_ZAllocAlignedOffset_stub(size_t size, size_t alignment, size_t offset) +{ + STUB_SAFE_CALL3(PORT_ZAllocAlignedOffset_Util, size, alignment, offset); + if (offset > size) { + return NULL; + } + + void *mem = NULL; + void *v = PORT_ZAllocAligned_stub(size, alignment, &mem); + if (!v) { + return NULL; + } + + *((void **)((uintptr_t)v + offset)) = mem; + return v; +} + extern void PORT_ZFree_stub(void *ptr, size_t len) { @@ -590,6 +655,13 @@ NSS_SecureMemcmp_stub(const void *a, const void *b, size_t n) abort(); } +extern unsigned int +NSS_SecureMemcmpZero_stub(const void *mem, size_t n) +{ + STUB_SAFE_CALL2(NSS_SecureMemcmpZero, mem, n); + abort(); +} + #ifdef FREEBL_NO_WEAK static const char *nsprLibName = SHLIB_PREFIX "nspr4." SHLIB_SUFFIX; @@ -642,6 +714,7 @@ freebl_InitNSSUtil(void *lib) STUB_FETCH_FUNCTION(SECITEM_ZfreeItem_Util); STUB_FETCH_FUNCTION(SECOID_FindOIDTag_Util); STUB_FETCH_FUNCTION(NSS_SecureMemcmp); + STUB_FETCH_FUNCTION(NSS_SecureMemcmpZero); return SECSuccess; } diff --git a/security/nss/lib/freebl/stubs.h b/security/nss/lib/freebl/stubs.h index 25ec394ec..e63cf7a5d 100644 --- a/security/nss/lib/freebl/stubs.h +++ b/security/nss/lib/freebl/stubs.h @@ -30,6 +30,8 @@ #define PORT_SetError PORT_SetError_stub #define PORT_ZAlloc PORT_ZAlloc_stub #define PORT_ZFree PORT_ZFree_stub +#define PORT_ZAllocAligned PORT_ZAllocAligned_stub +#define PORT_ZAllocAlignedOffset PORT_ZAllocAlignedOffset_stub #define SECITEM_AllocItem SECITEM_AllocItem_stub #define SECITEM_CompareItem SECITEM_CompareItem_stub @@ -38,6 +40,7 @@ #define SECITEM_ZfreeItem SECITEM_ZfreeItem_stub #define SECOID_FindOIDTag SECOID_FindOIDTag_stub #define NSS_SecureMemcmp NSS_SecureMemcmp_stub +#define NSS_SecureMemcmpZero NSS_SecureMemcmpZero_stub #define PR_Assert PR_Assert_stub #define PR_Access PR_Access_stub diff --git a/security/nss/lib/freebl/verified/FStar.c b/security/nss/lib/freebl/verified/FStar.c new file mode 100644 index 000000000..4e5f6d50d --- /dev/null +++ b/security/nss/lib/freebl/verified/FStar.c @@ -0,0 +1,255 @@ +/* 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. + */ + +/* This file was auto-generated by KreMLin! */ + +#include "FStar.h" + +static uint64_t +FStar_UInt128_constant_time_carry(uint64_t a, uint64_t b) +{ + return (a ^ ((a ^ b) | ((a - b) ^ b))) >> (uint32_t)63U; +} + +static uint64_t +FStar_UInt128_carry(uint64_t a, uint64_t b) +{ + return FStar_UInt128_constant_time_carry(a, b); +} + +FStar_UInt128_uint128 +FStar_UInt128_add(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b) +{ + return ( + (FStar_UInt128_uint128){ + .low = a.low + b.low, + .high = a.high + b.high + FStar_UInt128_carry(a.low + b.low, b.low) }); +} + +FStar_UInt128_uint128 +FStar_UInt128_add_mod(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b) +{ + return ( + (FStar_UInt128_uint128){ + .low = a.low + b.low, + .high = a.high + b.high + FStar_UInt128_carry(a.low + b.low, b.low) }); +} + +FStar_UInt128_uint128 +FStar_UInt128_sub(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b) +{ + return ( + (FStar_UInt128_uint128){ + .low = a.low - b.low, + .high = a.high - b.high - FStar_UInt128_carry(a.low, a.low - b.low) }); +} + +static FStar_UInt128_uint128 +FStar_UInt128_sub_mod_impl(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b) +{ + return ( + (FStar_UInt128_uint128){ + .low = a.low - b.low, + .high = a.high - b.high - FStar_UInt128_carry(a.low, a.low - b.low) }); +} + +FStar_UInt128_uint128 +FStar_UInt128_sub_mod(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b) +{ + return FStar_UInt128_sub_mod_impl(a, b); +} + +FStar_UInt128_uint128 +FStar_UInt128_logand(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b) +{ + return ((FStar_UInt128_uint128){.low = a.low & b.low, .high = a.high & b.high }); +} + +FStar_UInt128_uint128 +FStar_UInt128_logxor(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b) +{ + return ((FStar_UInt128_uint128){.low = a.low ^ b.low, .high = a.high ^ b.high }); +} + +FStar_UInt128_uint128 +FStar_UInt128_logor(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b) +{ + return ((FStar_UInt128_uint128){.low = a.low | b.low, .high = a.high | b.high }); +} + +FStar_UInt128_uint128 +FStar_UInt128_lognot(FStar_UInt128_uint128 a) +{ + return ((FStar_UInt128_uint128){.low = ~a.low, .high = ~a.high }); +} + +static uint32_t FStar_UInt128_u32_64 = (uint32_t)64U; + +static uint64_t +FStar_UInt128_add_u64_shift_left(uint64_t hi, uint64_t lo, uint32_t s) +{ + return (hi << s) + (lo >> (FStar_UInt128_u32_64 - s)); +} + +static uint64_t +FStar_UInt128_add_u64_shift_left_respec(uint64_t hi, uint64_t lo, uint32_t s) +{ + return FStar_UInt128_add_u64_shift_left(hi, lo, s); +} + +static FStar_UInt128_uint128 +FStar_UInt128_shift_left_small(FStar_UInt128_uint128 a, uint32_t s) +{ + if (s == (uint32_t)0U) + return a; + else + return ( + (FStar_UInt128_uint128){ + .low = a.low << s, + .high = FStar_UInt128_add_u64_shift_left_respec(a.high, a.low, s) }); +} + +static FStar_UInt128_uint128 +FStar_UInt128_shift_left_large(FStar_UInt128_uint128 a, uint32_t s) +{ + return ((FStar_UInt128_uint128){.low = (uint64_t)0U, .high = a.low << (s - FStar_UInt128_u32_64) }); +} + +FStar_UInt128_uint128 +FStar_UInt128_shift_left(FStar_UInt128_uint128 a, uint32_t s) +{ + if (s < FStar_UInt128_u32_64) + return FStar_UInt128_shift_left_small(a, s); + else + return FStar_UInt128_shift_left_large(a, s); +} + +static uint64_t +FStar_UInt128_add_u64_shift_right(uint64_t hi, uint64_t lo, uint32_t s) +{ + return (lo >> s) + (hi << (FStar_UInt128_u32_64 - s)); +} + +static uint64_t +FStar_UInt128_add_u64_shift_right_respec(uint64_t hi, uint64_t lo, uint32_t s) +{ + return FStar_UInt128_add_u64_shift_right(hi, lo, s); +} + +static FStar_UInt128_uint128 +FStar_UInt128_shift_right_small(FStar_UInt128_uint128 a, uint32_t s) +{ + if (s == (uint32_t)0U) + return a; + else + return ( + (FStar_UInt128_uint128){ + .low = FStar_UInt128_add_u64_shift_right_respec(a.high, a.low, s), + .high = a.high >> s }); +} + +static FStar_UInt128_uint128 +FStar_UInt128_shift_right_large(FStar_UInt128_uint128 a, uint32_t s) +{ + return ((FStar_UInt128_uint128){.low = a.high >> (s - FStar_UInt128_u32_64), .high = (uint64_t)0U }); +} + +FStar_UInt128_uint128 +FStar_UInt128_shift_right(FStar_UInt128_uint128 a, uint32_t s) +{ + if (s < FStar_UInt128_u32_64) + return FStar_UInt128_shift_right_small(a, s); + else + return FStar_UInt128_shift_right_large(a, s); +} + +FStar_UInt128_uint128 +FStar_UInt128_eq_mask(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b) +{ + return ( + (FStar_UInt128_uint128){ + .low = FStar_UInt64_eq_mask(a.low, b.low) & FStar_UInt64_eq_mask(a.high, b.high), + .high = FStar_UInt64_eq_mask(a.low, b.low) & FStar_UInt64_eq_mask(a.high, b.high) }); +} + +FStar_UInt128_uint128 +FStar_UInt128_gte_mask(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b) +{ + return ( + (FStar_UInt128_uint128){ + .low = (FStar_UInt64_gte_mask(a.high, b.high) & ~FStar_UInt64_eq_mask(a.high, b.high)) | (FStar_UInt64_eq_mask(a.high, b.high) & FStar_UInt64_gte_mask(a.low, b.low)), + .high = (FStar_UInt64_gte_mask(a.high, b.high) & ~FStar_UInt64_eq_mask(a.high, b.high)) | (FStar_UInt64_eq_mask(a.high, b.high) & FStar_UInt64_gte_mask(a.low, b.low)) }); +} + +FStar_UInt128_uint128 +FStar_UInt128_uint64_to_uint128(uint64_t a) +{ + return ((FStar_UInt128_uint128){.low = a, .high = (uint64_t)0U }); +} + +uint64_t +FStar_UInt128_uint128_to_uint64(FStar_UInt128_uint128 a) +{ + return a.low; +} + +static uint64_t FStar_UInt128_u64_l32_mask = (uint64_t)0xffffffffU; + +static uint64_t +FStar_UInt128_u64_mod_32(uint64_t a) +{ + return a & FStar_UInt128_u64_l32_mask; +} + +static uint32_t FStar_UInt128_u32_32 = (uint32_t)32U; + +static K___uint64_t_uint64_t_uint64_t_uint64_t +FStar_UInt128_mul_wide_impl_t_(uint64_t x, uint64_t y) +{ + return ( + (K___uint64_t_uint64_t_uint64_t_uint64_t){ + .fst = FStar_UInt128_u64_mod_32(x), + .snd = FStar_UInt128_u64_mod_32(FStar_UInt128_u64_mod_32(x) * FStar_UInt128_u64_mod_32(y)), + .thd = x >> FStar_UInt128_u32_32, + .f3 = (x >> FStar_UInt128_u32_32) * FStar_UInt128_u64_mod_32(y) + (FStar_UInt128_u64_mod_32(x) * FStar_UInt128_u64_mod_32(y) >> FStar_UInt128_u32_32) }); +} + +static uint64_t +FStar_UInt128_u32_combine_(uint64_t hi, uint64_t lo) +{ + return lo + (hi << FStar_UInt128_u32_32); +} + +static FStar_UInt128_uint128 +FStar_UInt128_mul_wide_impl(uint64_t x, uint64_t y) +{ + K___uint64_t_uint64_t_uint64_t_uint64_t scrut = FStar_UInt128_mul_wide_impl_t_(x, y); + uint64_t u1 = scrut.fst; + uint64_t w3 = scrut.snd; + uint64_t x_ = scrut.thd; + uint64_t t_ = scrut.f3; + return ( + (FStar_UInt128_uint128){ + .low = FStar_UInt128_u32_combine_(u1 * (y >> FStar_UInt128_u32_32) + FStar_UInt128_u64_mod_32(t_), + w3), + .high = x_ * (y >> FStar_UInt128_u32_32) + (t_ >> FStar_UInt128_u32_32) + + ((u1 * (y >> FStar_UInt128_u32_32) + FStar_UInt128_u64_mod_32(t_)) >> FStar_UInt128_u32_32) }); +} + +FStar_UInt128_uint128 +FStar_UInt128_mul_wide(uint64_t x, uint64_t y) +{ + return FStar_UInt128_mul_wide_impl(x, y); +} diff --git a/security/nss/lib/freebl/verified/FStar.h b/security/nss/lib/freebl/verified/FStar.h new file mode 100644 index 000000000..7b105b8f2 --- /dev/null +++ b/security/nss/lib/freebl/verified/FStar.h @@ -0,0 +1,69 @@ +/* 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. + */ + +/* This file was auto-generated by KreMLin! */ +#ifndef __FStar_H +#define __FStar_H + +#include "kremlib_base.h" + +typedef struct +{ + uint64_t low; + uint64_t high; +} FStar_UInt128_uint128; + +typedef FStar_UInt128_uint128 FStar_UInt128_t; + +extern void FStar_UInt128_constant_time_carry_ok(uint64_t x0, uint64_t x1); + +FStar_UInt128_uint128 FStar_UInt128_add(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b); + +FStar_UInt128_uint128 FStar_UInt128_add_mod(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b); + +FStar_UInt128_uint128 FStar_UInt128_sub(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b); + +FStar_UInt128_uint128 FStar_UInt128_sub_mod(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b); + +FStar_UInt128_uint128 FStar_UInt128_logand(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b); + +FStar_UInt128_uint128 FStar_UInt128_logxor(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b); + +FStar_UInt128_uint128 FStar_UInt128_logor(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b); + +FStar_UInt128_uint128 FStar_UInt128_lognot(FStar_UInt128_uint128 a); + +FStar_UInt128_uint128 FStar_UInt128_shift_left(FStar_UInt128_uint128 a, uint32_t s); + +FStar_UInt128_uint128 FStar_UInt128_shift_right(FStar_UInt128_uint128 a, uint32_t s); + +FStar_UInt128_uint128 FStar_UInt128_eq_mask(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b); + +FStar_UInt128_uint128 FStar_UInt128_gte_mask(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b); + +FStar_UInt128_uint128 FStar_UInt128_uint64_to_uint128(uint64_t a); + +uint64_t FStar_UInt128_uint128_to_uint64(FStar_UInt128_uint128 a); + +typedef struct +{ + uint64_t fst; + uint64_t snd; + uint64_t thd; + uint64_t f3; +} K___uint64_t_uint64_t_uint64_t_uint64_t; + +FStar_UInt128_uint128 FStar_UInt128_mul_wide(uint64_t x, uint64_t y); +#endif diff --git a/security/nss/lib/freebl/verified/Hacl_Chacha20.c b/security/nss/lib/freebl/verified/Hacl_Chacha20.c new file mode 100644 index 000000000..45a743035 --- /dev/null +++ b/security/nss/lib/freebl/verified/Hacl_Chacha20.c @@ -0,0 +1,270 @@ +/* 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_Chacha20.h" + +static void +Hacl_Lib_LoadStore32_uint32s_from_le_bytes(uint32_t *output, uint8_t *input, uint32_t len) +{ + for (uint32_t i = (uint32_t)0U; i < len; i = i + (uint32_t)1U) { + uint8_t *x0 = input + (uint32_t)4U * i; + uint32_t inputi = load32_le(x0); + output[i] = inputi; + } +} + +static void +Hacl_Lib_LoadStore32_uint32s_to_le_bytes(uint8_t *output, uint32_t *input, uint32_t len) +{ + for (uint32_t i = (uint32_t)0U; i < len; i = i + (uint32_t)1U) { + uint32_t hd1 = input[i]; + uint8_t *x0 = output + (uint32_t)4U * i; + store32_le(x0, hd1); + } +} + +inline static uint32_t +Hacl_Impl_Chacha20_rotate_left(uint32_t a, uint32_t s) +{ + return a << s | a >> ((uint32_t)32U - s); +} + +inline static void +Hacl_Impl_Chacha20_quarter_round(uint32_t *st, uint32_t a, uint32_t b, uint32_t c, uint32_t d) +{ + uint32_t sa = st[a]; + uint32_t sb0 = st[b]; + st[a] = sa + sb0; + uint32_t sd = st[d]; + uint32_t sa10 = st[a]; + uint32_t sda = sd ^ sa10; + st[d] = Hacl_Impl_Chacha20_rotate_left(sda, (uint32_t)16U); + uint32_t sa0 = st[c]; + uint32_t sb1 = st[d]; + st[c] = sa0 + sb1; + uint32_t sd0 = st[b]; + uint32_t sa11 = st[c]; + uint32_t sda0 = sd0 ^ sa11; + st[b] = Hacl_Impl_Chacha20_rotate_left(sda0, (uint32_t)12U); + uint32_t sa2 = st[a]; + uint32_t sb2 = st[b]; + st[a] = sa2 + sb2; + uint32_t sd1 = st[d]; + uint32_t sa12 = st[a]; + uint32_t sda1 = sd1 ^ sa12; + st[d] = Hacl_Impl_Chacha20_rotate_left(sda1, (uint32_t)8U); + uint32_t sa3 = st[c]; + uint32_t sb = st[d]; + st[c] = sa3 + sb; + uint32_t sd2 = st[b]; + uint32_t sa1 = st[c]; + uint32_t sda2 = sd2 ^ sa1; + st[b] = Hacl_Impl_Chacha20_rotate_left(sda2, (uint32_t)7U); +} + +inline static void +Hacl_Impl_Chacha20_double_round(uint32_t *st) +{ + Hacl_Impl_Chacha20_quarter_round(st, (uint32_t)0U, (uint32_t)4U, (uint32_t)8U, (uint32_t)12U); + Hacl_Impl_Chacha20_quarter_round(st, (uint32_t)1U, (uint32_t)5U, (uint32_t)9U, (uint32_t)13U); + Hacl_Impl_Chacha20_quarter_round(st, (uint32_t)2U, (uint32_t)6U, (uint32_t)10U, (uint32_t)14U); + Hacl_Impl_Chacha20_quarter_round(st, (uint32_t)3U, (uint32_t)7U, (uint32_t)11U, (uint32_t)15U); + Hacl_Impl_Chacha20_quarter_round(st, (uint32_t)0U, (uint32_t)5U, (uint32_t)10U, (uint32_t)15U); + Hacl_Impl_Chacha20_quarter_round(st, (uint32_t)1U, (uint32_t)6U, (uint32_t)11U, (uint32_t)12U); + Hacl_Impl_Chacha20_quarter_round(st, (uint32_t)2U, (uint32_t)7U, (uint32_t)8U, (uint32_t)13U); + Hacl_Impl_Chacha20_quarter_round(st, (uint32_t)3U, (uint32_t)4U, (uint32_t)9U, (uint32_t)14U); +} + +inline static void +Hacl_Impl_Chacha20_rounds(uint32_t *st) +{ + for (uint32_t i = (uint32_t)0U; i < (uint32_t)10U; i = i + (uint32_t)1U) + Hacl_Impl_Chacha20_double_round(st); +} + +inline static void +Hacl_Impl_Chacha20_sum_states(uint32_t *st, uint32_t *st_) +{ + for (uint32_t i = (uint32_t)0U; i < (uint32_t)16U; i = i + (uint32_t)1U) { + uint32_t xi = st[i]; + uint32_t yi = st_[i]; + st[i] = xi + yi; + } +} + +inline static void +Hacl_Impl_Chacha20_copy_state(uint32_t *st, uint32_t *st_) +{ + memcpy(st, st_, (uint32_t)16U * sizeof st_[0U]); +} + +inline static void +Hacl_Impl_Chacha20_chacha20_core(uint32_t *k, uint32_t *st, uint32_t ctr) +{ + st[12U] = ctr; + Hacl_Impl_Chacha20_copy_state(k, st); + Hacl_Impl_Chacha20_rounds(k); + Hacl_Impl_Chacha20_sum_states(k, st); +} + +inline static void +Hacl_Impl_Chacha20_chacha20_block(uint8_t *stream_block, uint32_t *st, uint32_t ctr) +{ + uint32_t st_[16U] = { 0U }; + Hacl_Impl_Chacha20_chacha20_core(st_, st, ctr); + Hacl_Lib_LoadStore32_uint32s_to_le_bytes(stream_block, st_, (uint32_t)16U); +} + +inline static void +Hacl_Impl_Chacha20_init(uint32_t *st, uint8_t *k, uint8_t *n1) +{ + uint32_t *stcst = st; + uint32_t *stk = st + (uint32_t)4U; + uint32_t *stc = st + (uint32_t)12U; + uint32_t *stn = st + (uint32_t)13U; + stcst[0U] = (uint32_t)0x61707865U; + stcst[1U] = (uint32_t)0x3320646eU; + stcst[2U] = (uint32_t)0x79622d32U; + stcst[3U] = (uint32_t)0x6b206574U; + Hacl_Lib_LoadStore32_uint32s_from_le_bytes(stk, k, (uint32_t)8U); + stc[0U] = (uint32_t)0U; + Hacl_Lib_LoadStore32_uint32s_from_le_bytes(stn, n1, (uint32_t)3U); +} + +static void +Hacl_Impl_Chacha20_update(uint8_t *output, uint8_t *plain, uint32_t *st, uint32_t ctr) +{ + uint32_t b[48U] = { 0U }; + uint32_t *k = b; + uint32_t *ib = b + (uint32_t)16U; + uint32_t *ob = b + (uint32_t)32U; + Hacl_Impl_Chacha20_chacha20_core(k, st, ctr); + Hacl_Lib_LoadStore32_uint32s_from_le_bytes(ib, plain, (uint32_t)16U); + for (uint32_t i = (uint32_t)0U; i < (uint32_t)16U; i = i + (uint32_t)1U) { + uint32_t xi = ib[i]; + uint32_t yi = k[i]; + ob[i] = xi ^ yi; + } + Hacl_Lib_LoadStore32_uint32s_to_le_bytes(output, ob, (uint32_t)16U); +} + +static void +Hacl_Impl_Chacha20_update_last( + uint8_t *output, + uint8_t *plain, + uint32_t len, + uint32_t *st, + uint32_t ctr) +{ + uint8_t block[64U] = { 0U }; + Hacl_Impl_Chacha20_chacha20_block(block, st, ctr); + uint8_t *mask = block; + for (uint32_t i = (uint32_t)0U; i < len; i = i + (uint32_t)1U) { + uint8_t xi = plain[i]; + uint8_t yi = mask[i]; + output[i] = xi ^ yi; + } +} + +static void +Hacl_Impl_Chacha20_chacha20_counter_mode_blocks( + uint8_t *output, + uint8_t *plain, + uint32_t num_blocks, + uint32_t *st, + uint32_t ctr) +{ + for (uint32_t i = (uint32_t)0U; i < num_blocks; i = i + (uint32_t)1U) { + uint8_t *b = plain + (uint32_t)64U * i; + uint8_t *o = output + (uint32_t)64U * i; + Hacl_Impl_Chacha20_update(o, b, st, ctr + i); + } +} + +static void +Hacl_Impl_Chacha20_chacha20_counter_mode( + uint8_t *output, + uint8_t *plain, + uint32_t len, + uint32_t *st, + uint32_t ctr) +{ + uint32_t blocks_len = len >> (uint32_t)6U; + uint32_t part_len = len & (uint32_t)0x3fU; + uint8_t *output_ = output; + uint8_t *plain_ = plain; + uint8_t *output__ = output + (uint32_t)64U * blocks_len; + uint8_t *plain__ = plain + (uint32_t)64U * blocks_len; + Hacl_Impl_Chacha20_chacha20_counter_mode_blocks(output_, plain_, blocks_len, st, ctr); + if (part_len > (uint32_t)0U) + Hacl_Impl_Chacha20_update_last(output__, plain__, part_len, st, ctr + blocks_len); +} + +static void +Hacl_Impl_Chacha20_chacha20( + uint8_t *output, + uint8_t *plain, + uint32_t len, + uint8_t *k, + uint8_t *n1, + uint32_t ctr) +{ + uint32_t buf[16U] = { 0U }; + uint32_t *st = buf; + Hacl_Impl_Chacha20_init(st, k, n1); + Hacl_Impl_Chacha20_chacha20_counter_mode(output, plain, len, st, ctr); +} + +void +Hacl_Chacha20_chacha20_key_block(uint8_t *block, uint8_t *k, uint8_t *n1, uint32_t ctr) +{ + uint32_t buf[16U] = { 0U }; + uint32_t *st = buf; + Hacl_Impl_Chacha20_init(st, k, n1); + Hacl_Impl_Chacha20_chacha20_block(block, st, ctr); +} + +/* + This function implements Chacha20 + + val chacha20 : + output:uint8_p -> + plain:uint8_p{ disjoint output plain } -> + len:uint32_t{ v len = length output /\ v len = length plain } -> + key:uint8_p{ length key = 32 } -> + nonce:uint8_p{ length nonce = 12 } -> + ctr:uint32_t{ v ctr + length plain / 64 < pow2 32 } -> + Stack unit + (requires + fun h -> live h output /\ live h plain /\ live h nonce /\ live h key) + (ensures + fun h0 _ h1 -> + live h1 output /\ live h0 plain /\ modifies_1 output h0 h1 /\ + live h0 nonce /\ + live h0 key /\ + h1.[ output ] == + chacha20_encrypt_bytes h0.[ key ] h0.[ nonce ] (v ctr) h0.[ plain ]) +*/ +void +Hacl_Chacha20_chacha20( + uint8_t *output, + uint8_t *plain, + uint32_t len, + uint8_t *k, + uint8_t *n1, + uint32_t ctr) +{ + Hacl_Impl_Chacha20_chacha20(output, plain, len, k, n1, ctr); +} diff --git a/security/nss/lib/freebl/verified/Hacl_Chacha20.h b/security/nss/lib/freebl/verified/Hacl_Chacha20.h new file mode 100644 index 000000000..f97e44b74 --- /dev/null +++ b/security/nss/lib/freebl/verified/Hacl_Chacha20.h @@ -0,0 +1,81 @@ +/* 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_Chacha20_H +#define __Hacl_Chacha20_H + +typedef uint32_t Hacl_Impl_Xor_Lemmas_u32; + +typedef uint8_t Hacl_Impl_Xor_Lemmas_u8; + +typedef uint8_t *Hacl_Lib_LoadStore32_uint8_p; + +typedef uint32_t Hacl_Impl_Chacha20_u32; + +typedef uint32_t Hacl_Impl_Chacha20_h32; + +typedef uint8_t *Hacl_Impl_Chacha20_uint8_p; + +typedef uint32_t *Hacl_Impl_Chacha20_state; + +typedef uint32_t Hacl_Impl_Chacha20_idx; + +typedef struct +{ + void *k; + void *n; +} Hacl_Impl_Chacha20_log_t_; + +typedef void *Hacl_Impl_Chacha20_log_t; + +typedef uint32_t Hacl_Lib_Create_h32; + +typedef uint8_t *Hacl_Chacha20_uint8_p; + +typedef uint32_t Hacl_Chacha20_uint32_t; + +void Hacl_Chacha20_chacha20_key_block(uint8_t *block, uint8_t *k, uint8_t *n1, uint32_t ctr); + +/* + This function implements Chacha20 + + val chacha20 : + output:uint8_p -> + plain:uint8_p{ disjoint output plain } -> + len:uint32_t{ v len = length output /\ v len = length plain } -> + key:uint8_p{ length key = 32 } -> + nonce:uint8_p{ length nonce = 12 } -> + ctr:uint32_t{ v ctr + length plain / 64 < pow2 32 } -> + Stack unit + (requires + fun h -> live h output /\ live h plain /\ live h nonce /\ live h key) + (ensures + fun h0 _ h1 -> + live h1 output /\ live h0 plain /\ modifies_1 output h0 h1 /\ + live h0 nonce /\ + live h0 key /\ + h1.[ output ] == + chacha20_encrypt_bytes h0.[ key ] h0.[ nonce ] (v ctr) h0.[ plain ]) +*/ +void +Hacl_Chacha20_chacha20( + uint8_t *output, + uint8_t *plain, + uint32_t len, + uint8_t *k, + uint8_t *n1, + uint32_t ctr); +#endif diff --git a/security/nss/lib/freebl/verified/Hacl_Chacha20_Vec128.c b/security/nss/lib/freebl/verified/Hacl_Chacha20_Vec128.c new file mode 100644 index 000000000..4eba49f47 --- /dev/null +++ b/security/nss/lib/freebl/verified/Hacl_Chacha20_Vec128.c @@ -0,0 +1,390 @@ +/* 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_Chacha20_Vec128.h" + +inline static void +Hacl_Impl_Chacha20_Vec128_State_state_incr(vec *k) +{ + vec k3 = k[3U]; + k[3U] = vec_increment(k3); +} + +inline static void +Hacl_Impl_Chacha20_Vec128_State_state_to_key_block(uint8_t *stream_block, vec *k) +{ + vec k0 = k[0U]; + vec k1 = k[1U]; + vec k2 = k[2U]; + vec k3 = k[3U]; + uint8_t *a = stream_block; + uint8_t *b = stream_block + (uint32_t)16U; + uint8_t *c = stream_block + (uint32_t)32U; + uint8_t *d = stream_block + (uint32_t)48U; + vec_store_le(a, k0); + vec_store_le(b, k1); + vec_store_le(c, k2); + vec_store_le(d, k3); +} + +inline static void +Hacl_Impl_Chacha20_Vec128_State_state_setup(vec *st, uint8_t *k, uint8_t *n1, uint32_t c) +{ + st[0U] = + vec_load_32x4((uint32_t)0x61707865U, + (uint32_t)0x3320646eU, + (uint32_t)0x79622d32U, + (uint32_t)0x6b206574U); + vec k0 = vec_load128_le(k); + vec k1 = vec_load128_le(k + (uint32_t)16U); + st[1U] = k0; + st[2U] = k1; + uint32_t n0 = load32_le(n1); + uint8_t *x00 = n1 + (uint32_t)4U; + uint32_t n10 = load32_le(x00); + uint8_t *x0 = n1 + (uint32_t)8U; + uint32_t n2 = load32_le(x0); + vec v1 = vec_load_32x4(c, n0, n10, n2); + st[3U] = v1; +} + +inline static void +Hacl_Impl_Chacha20_Vec128_round(vec *st) +{ + vec sa = st[0U]; + vec sb0 = st[1U]; + vec sd0 = st[3U]; + vec sa10 = vec_add(sa, sb0); + vec sd10 = vec_rotate_left(vec_xor(sd0, sa10), (uint32_t)16U); + st[0U] = sa10; + st[3U] = sd10; + vec sa0 = st[2U]; + vec sb1 = st[3U]; + vec sd2 = st[1U]; + vec sa11 = vec_add(sa0, sb1); + vec sd11 = vec_rotate_left(vec_xor(sd2, sa11), (uint32_t)12U); + st[2U] = sa11; + st[1U] = sd11; + vec sa2 = st[0U]; + vec sb2 = st[1U]; + vec sd3 = st[3U]; + vec sa12 = vec_add(sa2, sb2); + vec sd12 = vec_rotate_left(vec_xor(sd3, sa12), (uint32_t)8U); + st[0U] = sa12; + st[3U] = sd12; + vec sa3 = st[2U]; + vec sb = st[3U]; + vec sd = st[1U]; + vec sa1 = vec_add(sa3, sb); + vec sd1 = vec_rotate_left(vec_xor(sd, sa1), (uint32_t)7U); + st[2U] = sa1; + st[1U] = sd1; +} + +inline static void +Hacl_Impl_Chacha20_Vec128_double_round(vec *st) +{ + Hacl_Impl_Chacha20_Vec128_round(st); + vec r1 = st[1U]; + vec r20 = st[2U]; + vec r30 = st[3U]; + st[1U] = vec_shuffle_right(r1, (uint32_t)1U); + st[2U] = vec_shuffle_right(r20, (uint32_t)2U); + st[3U] = vec_shuffle_right(r30, (uint32_t)3U); + Hacl_Impl_Chacha20_Vec128_round(st); + vec r10 = st[1U]; + vec r2 = st[2U]; + vec r3 = st[3U]; + st[1U] = vec_shuffle_right(r10, (uint32_t)3U); + st[2U] = vec_shuffle_right(r2, (uint32_t)2U); + st[3U] = vec_shuffle_right(r3, (uint32_t)1U); +} + +inline static void +Hacl_Impl_Chacha20_Vec128_double_round3(vec *st, vec *st_, vec *st__) +{ + Hacl_Impl_Chacha20_Vec128_double_round(st); + Hacl_Impl_Chacha20_Vec128_double_round(st_); + Hacl_Impl_Chacha20_Vec128_double_round(st__); +} + +inline static void +Hacl_Impl_Chacha20_Vec128_sum_states(vec *st_, vec *st) +{ + vec s0 = st[0U]; + vec s1 = st[1U]; + vec s2 = st[2U]; + vec s3 = st[3U]; + vec s0_ = st_[0U]; + vec s1_ = st_[1U]; + vec s2_ = st_[2U]; + vec s3_ = st_[3U]; + st_[0U] = vec_add(s0_, s0); + st_[1U] = vec_add(s1_, s1); + st_[2U] = vec_add(s2_, s2); + st_[3U] = vec_add(s3_, s3); +} + +inline static void +Hacl_Impl_Chacha20_Vec128_copy_state(vec *st_, vec *st) +{ + vec st0 = st[0U]; + vec st1 = st[1U]; + vec st2 = st[2U]; + vec st3 = st[3U]; + st_[0U] = st0; + st_[1U] = st1; + st_[2U] = st2; + st_[3U] = st3; +} + +inline static void +Hacl_Impl_Chacha20_Vec128_chacha20_core(vec *k, vec *st) +{ + Hacl_Impl_Chacha20_Vec128_copy_state(k, st); + for (uint32_t i = (uint32_t)0U; i < (uint32_t)10U; i = i + (uint32_t)1U) + Hacl_Impl_Chacha20_Vec128_double_round(k); + Hacl_Impl_Chacha20_Vec128_sum_states(k, st); +} + +static void +Hacl_Impl_Chacha20_Vec128_state_incr(vec *st) +{ + Hacl_Impl_Chacha20_Vec128_State_state_incr(st); +} + +inline static void +Hacl_Impl_Chacha20_Vec128_chacha20_incr3(vec *k0, vec *k1, vec *k2, vec *st) +{ + Hacl_Impl_Chacha20_Vec128_copy_state(k0, st); + Hacl_Impl_Chacha20_Vec128_copy_state(k1, st); + Hacl_Impl_Chacha20_Vec128_state_incr(k1); + Hacl_Impl_Chacha20_Vec128_copy_state(k2, k1); + Hacl_Impl_Chacha20_Vec128_state_incr(k2); +} + +inline static void +Hacl_Impl_Chacha20_Vec128_chacha20_sum3(vec *k0, vec *k1, vec *k2, vec *st) +{ + Hacl_Impl_Chacha20_Vec128_sum_states(k0, st); + Hacl_Impl_Chacha20_Vec128_state_incr(st); + Hacl_Impl_Chacha20_Vec128_sum_states(k1, st); + Hacl_Impl_Chacha20_Vec128_state_incr(st); + Hacl_Impl_Chacha20_Vec128_sum_states(k2, st); +} + +inline static void +Hacl_Impl_Chacha20_Vec128_chacha20_core3(vec *k0, vec *k1, vec *k2, vec *st) +{ + Hacl_Impl_Chacha20_Vec128_chacha20_incr3(k0, k1, k2, st); + for (uint32_t i = (uint32_t)0U; i < (uint32_t)10U; i = i + (uint32_t)1U) + Hacl_Impl_Chacha20_Vec128_double_round3(k0, k1, k2); + Hacl_Impl_Chacha20_Vec128_chacha20_sum3(k0, k1, k2, st); +} + +inline static void +Hacl_Impl_Chacha20_Vec128_chacha20_block(uint8_t *stream_block, vec *st) +{ + KRML_CHECK_SIZE(vec_zero(), (uint32_t)4U); + vec k[4U]; + for (uint32_t _i = 0U; _i < (uint32_t)4U; ++_i) + k[_i] = vec_zero(); + Hacl_Impl_Chacha20_Vec128_chacha20_core(k, st); + Hacl_Impl_Chacha20_Vec128_State_state_to_key_block(stream_block, k); +} + +inline static void +Hacl_Impl_Chacha20_Vec128_init(vec *st, uint8_t *k, uint8_t *n1, uint32_t ctr) +{ + Hacl_Impl_Chacha20_Vec128_State_state_setup(st, k, n1, ctr); +} + +static void +Hacl_Impl_Chacha20_Vec128_update_last(uint8_t *output, uint8_t *plain, uint32_t len, vec *st) +{ + uint8_t block[64U] = { 0U }; + Hacl_Impl_Chacha20_Vec128_chacha20_block(block, st); + uint8_t *mask = block; + for (uint32_t i = (uint32_t)0U; i < len; i = i + (uint32_t)1U) { + uint8_t xi = plain[i]; + uint8_t yi = mask[i]; + output[i] = xi ^ yi; + } +} + +static void +Hacl_Impl_Chacha20_Vec128_xor_block(uint8_t *output, uint8_t *plain, vec *st) +{ + vec p0 = vec_load_le(plain); + vec p1 = vec_load_le(plain + (uint32_t)16U); + vec p2 = vec_load_le(plain + (uint32_t)32U); + vec p3 = vec_load_le(plain + (uint32_t)48U); + vec k0 = st[0U]; + vec k1 = st[1U]; + vec k2 = st[2U]; + vec k3 = st[3U]; + vec o00 = vec_xor(p0, k0); + vec o10 = vec_xor(p1, k1); + vec o20 = vec_xor(p2, k2); + vec o30 = vec_xor(p3, k3); + uint8_t *o0 = output; + uint8_t *o1 = output + (uint32_t)16U; + uint8_t *o2 = output + (uint32_t)32U; + uint8_t *o3 = output + (uint32_t)48U; + vec_store_le(o0, o00); + vec_store_le(o1, o10); + vec_store_le(o2, o20); + vec_store_le(o3, o30); +} + +static void +Hacl_Impl_Chacha20_Vec128_update(uint8_t *output, uint8_t *plain, vec *st) +{ + KRML_CHECK_SIZE(vec_zero(), (uint32_t)4U); + vec k[4U]; + for (uint32_t _i = 0U; _i < (uint32_t)4U; ++_i) + k[_i] = vec_zero(); + Hacl_Impl_Chacha20_Vec128_chacha20_core(k, st); + Hacl_Impl_Chacha20_Vec128_xor_block(output, plain, k); +} + +static void +Hacl_Impl_Chacha20_Vec128_update3(uint8_t *output, uint8_t *plain, vec *st) +{ + KRML_CHECK_SIZE(vec_zero(), (uint32_t)4U); + vec k0[4U]; + for (uint32_t _i = 0U; _i < (uint32_t)4U; ++_i) + k0[_i] = vec_zero(); + KRML_CHECK_SIZE(vec_zero(), (uint32_t)4U); + vec k1[4U]; + for (uint32_t _i = 0U; _i < (uint32_t)4U; ++_i) + k1[_i] = vec_zero(); + KRML_CHECK_SIZE(vec_zero(), (uint32_t)4U); + vec k2[4U]; + for (uint32_t _i = 0U; _i < (uint32_t)4U; ++_i) + k2[_i] = vec_zero(); + Hacl_Impl_Chacha20_Vec128_chacha20_core3(k0, k1, k2, st); + uint8_t *p0 = plain; + uint8_t *p1 = plain + (uint32_t)64U; + uint8_t *p2 = plain + (uint32_t)128U; + uint8_t *o0 = output; + uint8_t *o1 = output + (uint32_t)64U; + uint8_t *o2 = output + (uint32_t)128U; + Hacl_Impl_Chacha20_Vec128_xor_block(o0, p0, k0); + Hacl_Impl_Chacha20_Vec128_xor_block(o1, p1, k1); + Hacl_Impl_Chacha20_Vec128_xor_block(o2, p2, k2); +} + +static void +Hacl_Impl_Chacha20_Vec128_update3_( + uint8_t *output, + uint8_t *plain, + uint32_t len, + vec *st, + uint32_t i) +{ + uint8_t *out_block = output + (uint32_t)192U * i; + uint8_t *plain_block = plain + (uint32_t)192U * i; + Hacl_Impl_Chacha20_Vec128_update3(out_block, plain_block, st); + Hacl_Impl_Chacha20_Vec128_state_incr(st); +} + +static void +Hacl_Impl_Chacha20_Vec128_chacha20_counter_mode_blocks3( + uint8_t *output, + uint8_t *plain, + uint32_t len, + vec *st) +{ + for (uint32_t i = (uint32_t)0U; i < len; i = i + (uint32_t)1U) + Hacl_Impl_Chacha20_Vec128_update3_(output, plain, len, st, i); +} + +static void +Hacl_Impl_Chacha20_Vec128_chacha20_counter_mode_blocks( + uint8_t *output, + uint8_t *plain, + uint32_t len, + vec *st) +{ + uint32_t len3 = len / (uint32_t)3U; + uint32_t rest3 = len % (uint32_t)3U; + uint8_t *plain_ = plain; + uint8_t *blocks1 = plain + (uint32_t)192U * len3; + uint8_t *output_ = output; + uint8_t *outs = output + (uint32_t)192U * len3; + Hacl_Impl_Chacha20_Vec128_chacha20_counter_mode_blocks3(output_, plain_, len3, st); + if (rest3 == (uint32_t)2U) { + uint8_t *block0 = blocks1; + uint8_t *block1 = blocks1 + (uint32_t)64U; + uint8_t *out0 = outs; + uint8_t *out1 = outs + (uint32_t)64U; + Hacl_Impl_Chacha20_Vec128_update(out0, block0, st); + Hacl_Impl_Chacha20_Vec128_state_incr(st); + Hacl_Impl_Chacha20_Vec128_update(out1, block1, st); + Hacl_Impl_Chacha20_Vec128_state_incr(st); + } else if (rest3 == (uint32_t)1U) { + Hacl_Impl_Chacha20_Vec128_update(outs, blocks1, st); + Hacl_Impl_Chacha20_Vec128_state_incr(st); + } +} + +static void +Hacl_Impl_Chacha20_Vec128_chacha20_counter_mode( + uint8_t *output, + uint8_t *plain, + uint32_t len, + vec *st) +{ + uint32_t blocks_len = len >> (uint32_t)6U; + uint32_t part_len = len & (uint32_t)0x3fU; + uint8_t *output_ = output; + uint8_t *plain_ = plain; + uint8_t *output__ = output + (uint32_t)64U * blocks_len; + uint8_t *plain__ = plain + (uint32_t)64U * blocks_len; + Hacl_Impl_Chacha20_Vec128_chacha20_counter_mode_blocks(output_, plain_, blocks_len, st); + if (part_len > (uint32_t)0U) + Hacl_Impl_Chacha20_Vec128_update_last(output__, plain__, part_len, st); +} + +static void +Hacl_Impl_Chacha20_Vec128_chacha20( + uint8_t *output, + uint8_t *plain, + uint32_t len, + uint8_t *k, + uint8_t *n1, + uint32_t ctr) +{ + KRML_CHECK_SIZE(vec_zero(), (uint32_t)4U); + vec buf[4U]; + for (uint32_t _i = 0U; _i < (uint32_t)4U; ++_i) + buf[_i] = vec_zero(); + vec *st = buf; + Hacl_Impl_Chacha20_Vec128_init(st, k, n1, ctr); + Hacl_Impl_Chacha20_Vec128_chacha20_counter_mode(output, plain, len, st); +} + +void +Hacl_Chacha20_Vec128_chacha20( + uint8_t *output, + uint8_t *plain, + uint32_t len, + uint8_t *k, + uint8_t *n1, + uint32_t ctr) +{ + Hacl_Impl_Chacha20_Vec128_chacha20(output, plain, len, k, n1, ctr); +} diff --git a/security/nss/lib/freebl/verified/Hacl_Chacha20_Vec128.h b/security/nss/lib/freebl/verified/Hacl_Chacha20_Vec128.h new file mode 100644 index 000000000..57942093d --- /dev/null +++ b/security/nss/lib/freebl/verified/Hacl_Chacha20_Vec128.h @@ -0,0 +1,61 @@ +/* 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_Chacha20_Vec128_H +#define __Hacl_Chacha20_Vec128_H + +#include "vec128.h" + +typedef uint32_t Hacl_Impl_Xor_Lemmas_u32; + +typedef uint8_t Hacl_Impl_Xor_Lemmas_u8; + +typedef uint32_t Hacl_Impl_Chacha20_Vec128_State_u32; + +typedef uint32_t Hacl_Impl_Chacha20_Vec128_State_h32; + +typedef uint8_t *Hacl_Impl_Chacha20_Vec128_State_uint8_p; + +typedef vec *Hacl_Impl_Chacha20_Vec128_State_state; + +typedef uint32_t Hacl_Impl_Chacha20_Vec128_u32; + +typedef uint32_t Hacl_Impl_Chacha20_Vec128_h32; + +typedef uint8_t *Hacl_Impl_Chacha20_Vec128_uint8_p; + +typedef uint32_t Hacl_Impl_Chacha20_Vec128_idx; + +typedef struct +{ + void *k; + void *n; + uint32_t ctr; +} Hacl_Impl_Chacha20_Vec128_log_t_; + +typedef void *Hacl_Impl_Chacha20_Vec128_log_t; + +typedef uint8_t *Hacl_Chacha20_Vec128_uint8_p; + +void +Hacl_Chacha20_Vec128_chacha20( + uint8_t *output, + uint8_t *plain, + uint32_t len, + uint8_t *k, + uint8_t *n1, + uint32_t ctr); +#endif diff --git a/security/nss/lib/freebl/verified/Hacl_Curve25519.c b/security/nss/lib/freebl/verified/Hacl_Curve25519.c new file mode 100644 index 000000000..f2dcddc57 --- /dev/null +++ b/security/nss/lib/freebl/verified/Hacl_Curve25519.c @@ -0,0 +1,845 @@ +/* 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_Curve25519.h" + +static void +Hacl_Bignum_Modulo_carry_top(uint64_t *b) +{ + uint64_t b4 = b[4U]; + uint64_t b0 = b[0U]; + uint64_t b4_ = b4 & (uint64_t)0x7ffffffffffffU; + uint64_t b0_ = b0 + (uint64_t)19U * (b4 >> (uint32_t)51U); + b[4U] = b4_; + b[0U] = b0_; +} + +inline static void +Hacl_Bignum_Fproduct_copy_from_wide_(uint64_t *output, FStar_UInt128_t *input) +{ + { + FStar_UInt128_t xi = input[0U]; + output[0U] = FStar_UInt128_uint128_to_uint64(xi); + } + { + FStar_UInt128_t xi = input[1U]; + output[1U] = FStar_UInt128_uint128_to_uint64(xi); + } + { + FStar_UInt128_t xi = input[2U]; + output[2U] = FStar_UInt128_uint128_to_uint64(xi); + } + { + FStar_UInt128_t xi = input[3U]; + output[3U] = FStar_UInt128_uint128_to_uint64(xi); + } + { + FStar_UInt128_t xi = input[4U]; + output[4U] = FStar_UInt128_uint128_to_uint64(xi); + } +} + +inline static void +Hacl_Bignum_Fproduct_sum_scalar_multiplication_( + FStar_UInt128_t *output, + uint64_t *input, + uint64_t s) +{ + { + FStar_UInt128_t xi = output[0U]; + uint64_t yi = input[0U]; + output[0U] = FStar_UInt128_add_mod(xi, FStar_UInt128_mul_wide(yi, s)); + } + { + FStar_UInt128_t xi = output[1U]; + uint64_t yi = input[1U]; + output[1U] = FStar_UInt128_add_mod(xi, FStar_UInt128_mul_wide(yi, s)); + } + { + FStar_UInt128_t xi = output[2U]; + uint64_t yi = input[2U]; + output[2U] = FStar_UInt128_add_mod(xi, FStar_UInt128_mul_wide(yi, s)); + } + { + FStar_UInt128_t xi = output[3U]; + uint64_t yi = input[3U]; + output[3U] = FStar_UInt128_add_mod(xi, FStar_UInt128_mul_wide(yi, s)); + } + { + FStar_UInt128_t xi = output[4U]; + uint64_t yi = input[4U]; + output[4U] = FStar_UInt128_add_mod(xi, FStar_UInt128_mul_wide(yi, s)); + } +} + +inline static void +Hacl_Bignum_Fproduct_carry_wide_(FStar_UInt128_t *tmp) +{ + { + uint32_t ctr = (uint32_t)0U; + FStar_UInt128_t tctr = tmp[ctr]; + FStar_UInt128_t tctrp1 = tmp[ctr + (uint32_t)1U]; + uint64_t r0 = FStar_UInt128_uint128_to_uint64(tctr) & (uint64_t)0x7ffffffffffffU; + FStar_UInt128_t c = FStar_UInt128_shift_right(tctr, (uint32_t)51U); + tmp[ctr] = FStar_UInt128_uint64_to_uint128(r0); + tmp[ctr + (uint32_t)1U] = FStar_UInt128_add(tctrp1, c); + } + { + uint32_t ctr = (uint32_t)1U; + FStar_UInt128_t tctr = tmp[ctr]; + FStar_UInt128_t tctrp1 = tmp[ctr + (uint32_t)1U]; + uint64_t r0 = FStar_UInt128_uint128_to_uint64(tctr) & (uint64_t)0x7ffffffffffffU; + FStar_UInt128_t c = FStar_UInt128_shift_right(tctr, (uint32_t)51U); + tmp[ctr] = FStar_UInt128_uint64_to_uint128(r0); + tmp[ctr + (uint32_t)1U] = FStar_UInt128_add(tctrp1, c); + } + { + uint32_t ctr = (uint32_t)2U; + FStar_UInt128_t tctr = tmp[ctr]; + FStar_UInt128_t tctrp1 = tmp[ctr + (uint32_t)1U]; + uint64_t r0 = FStar_UInt128_uint128_to_uint64(tctr) & (uint64_t)0x7ffffffffffffU; + FStar_UInt128_t c = FStar_UInt128_shift_right(tctr, (uint32_t)51U); + tmp[ctr] = FStar_UInt128_uint64_to_uint128(r0); + tmp[ctr + (uint32_t)1U] = FStar_UInt128_add(tctrp1, c); + } + { + uint32_t ctr = (uint32_t)3U; + FStar_UInt128_t tctr = tmp[ctr]; + FStar_UInt128_t tctrp1 = tmp[ctr + (uint32_t)1U]; + uint64_t r0 = FStar_UInt128_uint128_to_uint64(tctr) & (uint64_t)0x7ffffffffffffU; + FStar_UInt128_t c = FStar_UInt128_shift_right(tctr, (uint32_t)51U); + tmp[ctr] = FStar_UInt128_uint64_to_uint128(r0); + tmp[ctr + (uint32_t)1U] = FStar_UInt128_add(tctrp1, c); + } +} + +inline static void +Hacl_Bignum_Fmul_shift_reduce(uint64_t *output) +{ + uint64_t tmp = output[4U]; + { + uint32_t ctr = (uint32_t)5U - (uint32_t)0U - (uint32_t)1U; + uint64_t z = output[ctr - (uint32_t)1U]; + output[ctr] = z; + } + { + uint32_t ctr = (uint32_t)5U - (uint32_t)1U - (uint32_t)1U; + uint64_t z = output[ctr - (uint32_t)1U]; + output[ctr] = z; + } + { + uint32_t ctr = (uint32_t)5U - (uint32_t)2U - (uint32_t)1U; + uint64_t z = output[ctr - (uint32_t)1U]; + output[ctr] = z; + } + { + uint32_t ctr = (uint32_t)5U - (uint32_t)3U - (uint32_t)1U; + uint64_t z = output[ctr - (uint32_t)1U]; + output[ctr] = z; + } + output[0U] = tmp; + uint64_t b0 = output[0U]; + output[0U] = (uint64_t)19U * b0; +} + +static void +Hacl_Bignum_Fmul_mul_shift_reduce_(FStar_UInt128_t *output, uint64_t *input, uint64_t *input21) +{ + { + uint64_t input2i = input21[0U]; + Hacl_Bignum_Fproduct_sum_scalar_multiplication_(output, input, input2i); + Hacl_Bignum_Fmul_shift_reduce(input); + } + { + uint64_t input2i = input21[1U]; + Hacl_Bignum_Fproduct_sum_scalar_multiplication_(output, input, input2i); + Hacl_Bignum_Fmul_shift_reduce(input); + } + { + uint64_t input2i = input21[2U]; + Hacl_Bignum_Fproduct_sum_scalar_multiplication_(output, input, input2i); + Hacl_Bignum_Fmul_shift_reduce(input); + } + { + uint64_t input2i = input21[3U]; + Hacl_Bignum_Fproduct_sum_scalar_multiplication_(output, input, input2i); + Hacl_Bignum_Fmul_shift_reduce(input); + } + uint32_t i = (uint32_t)4U; + uint64_t input2i = input21[i]; + Hacl_Bignum_Fproduct_sum_scalar_multiplication_(output, input, input2i); +} + +inline static void +Hacl_Bignum_Fmul_fmul(uint64_t *output, uint64_t *input, uint64_t *input21) +{ + uint64_t tmp[5U] = { 0U }; + memcpy(tmp, input, (uint32_t)5U * sizeof input[0U]); + KRML_CHECK_SIZE(FStar_UInt128_uint64_to_uint128((uint64_t)0U), (uint32_t)5U); + FStar_UInt128_t t[5U]; + for (uint32_t _i = 0U; _i < (uint32_t)5U; ++_i) + t[_i] = FStar_UInt128_uint64_to_uint128((uint64_t)0U); + Hacl_Bignum_Fmul_mul_shift_reduce_(t, tmp, input21); + Hacl_Bignum_Fproduct_carry_wide_(t); + FStar_UInt128_t b4 = t[4U]; + FStar_UInt128_t b0 = t[0U]; + FStar_UInt128_t + b4_ = FStar_UInt128_logand(b4, FStar_UInt128_uint64_to_uint128((uint64_t)0x7ffffffffffffU)); + FStar_UInt128_t + b0_ = + FStar_UInt128_add(b0, + FStar_UInt128_mul_wide((uint64_t)19U, + FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(b4, (uint32_t)51U)))); + t[4U] = b4_; + t[0U] = b0_; + Hacl_Bignum_Fproduct_copy_from_wide_(output, t); + uint64_t i0 = output[0U]; + uint64_t i1 = output[1U]; + uint64_t i0_ = i0 & (uint64_t)0x7ffffffffffffU; + uint64_t i1_ = i1 + (i0 >> (uint32_t)51U); + output[0U] = i0_; + output[1U] = i1_; +} + +inline static void +Hacl_Bignum_Fsquare_fsquare__(FStar_UInt128_t *tmp, uint64_t *output) +{ + uint64_t r0 = output[0U]; + uint64_t r1 = output[1U]; + uint64_t r2 = output[2U]; + uint64_t r3 = output[3U]; + uint64_t r4 = output[4U]; + uint64_t d0 = r0 * (uint64_t)2U; + uint64_t d1 = r1 * (uint64_t)2U; + uint64_t d2 = r2 * (uint64_t)2U * (uint64_t)19U; + uint64_t d419 = r4 * (uint64_t)19U; + uint64_t d4 = d419 * (uint64_t)2U; + FStar_UInt128_t + s0 = + FStar_UInt128_add(FStar_UInt128_add(FStar_UInt128_mul_wide(r0, r0), + FStar_UInt128_mul_wide(d4, r1)), + FStar_UInt128_mul_wide(d2, r3)); + FStar_UInt128_t + s1 = + FStar_UInt128_add(FStar_UInt128_add(FStar_UInt128_mul_wide(d0, r1), + FStar_UInt128_mul_wide(d4, r2)), + FStar_UInt128_mul_wide(r3 * (uint64_t)19U, r3)); + FStar_UInt128_t + s2 = + FStar_UInt128_add(FStar_UInt128_add(FStar_UInt128_mul_wide(d0, r2), + FStar_UInt128_mul_wide(r1, r1)), + FStar_UInt128_mul_wide(d4, r3)); + FStar_UInt128_t + s3 = + FStar_UInt128_add(FStar_UInt128_add(FStar_UInt128_mul_wide(d0, r3), + FStar_UInt128_mul_wide(d1, r2)), + FStar_UInt128_mul_wide(r4, d419)); + FStar_UInt128_t + s4 = + FStar_UInt128_add(FStar_UInt128_add(FStar_UInt128_mul_wide(d0, r4), + FStar_UInt128_mul_wide(d1, r3)), + FStar_UInt128_mul_wide(r2, r2)); + tmp[0U] = s0; + tmp[1U] = s1; + tmp[2U] = s2; + tmp[3U] = s3; + tmp[4U] = s4; +} + +inline static void +Hacl_Bignum_Fsquare_fsquare_(FStar_UInt128_t *tmp, uint64_t *output) +{ + Hacl_Bignum_Fsquare_fsquare__(tmp, output); + Hacl_Bignum_Fproduct_carry_wide_(tmp); + FStar_UInt128_t b4 = tmp[4U]; + FStar_UInt128_t b0 = tmp[0U]; + FStar_UInt128_t + b4_ = FStar_UInt128_logand(b4, FStar_UInt128_uint64_to_uint128((uint64_t)0x7ffffffffffffU)); + FStar_UInt128_t + b0_ = + FStar_UInt128_add(b0, + FStar_UInt128_mul_wide((uint64_t)19U, + FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(b4, (uint32_t)51U)))); + tmp[4U] = b4_; + tmp[0U] = b0_; + Hacl_Bignum_Fproduct_copy_from_wide_(output, tmp); + uint64_t i0 = output[0U]; + uint64_t i1 = output[1U]; + uint64_t i0_ = i0 & (uint64_t)0x7ffffffffffffU; + uint64_t i1_ = i1 + (i0 >> (uint32_t)51U); + output[0U] = i0_; + output[1U] = i1_; +} + +static void +Hacl_Bignum_Fsquare_fsquare_times_(uint64_t *input, FStar_UInt128_t *tmp, uint32_t count1) +{ + Hacl_Bignum_Fsquare_fsquare_(tmp, input); + for (uint32_t i = (uint32_t)1U; i < count1; i = i + (uint32_t)1U) + Hacl_Bignum_Fsquare_fsquare_(tmp, input); +} + +inline static void +Hacl_Bignum_Fsquare_fsquare_times(uint64_t *output, uint64_t *input, uint32_t count1) +{ + KRML_CHECK_SIZE(FStar_UInt128_uint64_to_uint128((uint64_t)0U), (uint32_t)5U); + FStar_UInt128_t t[5U]; + for (uint32_t _i = 0U; _i < (uint32_t)5U; ++_i) + t[_i] = FStar_UInt128_uint64_to_uint128((uint64_t)0U); + memcpy(output, input, (uint32_t)5U * sizeof input[0U]); + Hacl_Bignum_Fsquare_fsquare_times_(output, t, count1); +} + +inline static void +Hacl_Bignum_Fsquare_fsquare_times_inplace(uint64_t *output, uint32_t count1) +{ + KRML_CHECK_SIZE(FStar_UInt128_uint64_to_uint128((uint64_t)0U), (uint32_t)5U); + FStar_UInt128_t t[5U]; + for (uint32_t _i = 0U; _i < (uint32_t)5U; ++_i) + t[_i] = FStar_UInt128_uint64_to_uint128((uint64_t)0U); + Hacl_Bignum_Fsquare_fsquare_times_(output, t, count1); +} + +inline static void +Hacl_Bignum_Crecip_crecip(uint64_t *out, uint64_t *z) +{ + uint64_t buf[20U] = { 0U }; + uint64_t *a = buf; + uint64_t *t00 = buf + (uint32_t)5U; + uint64_t *b0 = buf + (uint32_t)10U; + Hacl_Bignum_Fsquare_fsquare_times(a, z, (uint32_t)1U); + Hacl_Bignum_Fsquare_fsquare_times(t00, a, (uint32_t)2U); + Hacl_Bignum_Fmul_fmul(b0, t00, z); + Hacl_Bignum_Fmul_fmul(a, b0, a); + Hacl_Bignum_Fsquare_fsquare_times(t00, a, (uint32_t)1U); + Hacl_Bignum_Fmul_fmul(b0, t00, b0); + Hacl_Bignum_Fsquare_fsquare_times(t00, b0, (uint32_t)5U); + uint64_t *t01 = buf + (uint32_t)5U; + uint64_t *b1 = buf + (uint32_t)10U; + uint64_t *c0 = buf + (uint32_t)15U; + Hacl_Bignum_Fmul_fmul(b1, t01, b1); + Hacl_Bignum_Fsquare_fsquare_times(t01, b1, (uint32_t)10U); + Hacl_Bignum_Fmul_fmul(c0, t01, b1); + Hacl_Bignum_Fsquare_fsquare_times(t01, c0, (uint32_t)20U); + Hacl_Bignum_Fmul_fmul(t01, t01, c0); + Hacl_Bignum_Fsquare_fsquare_times_inplace(t01, (uint32_t)10U); + Hacl_Bignum_Fmul_fmul(b1, t01, b1); + Hacl_Bignum_Fsquare_fsquare_times(t01, b1, (uint32_t)50U); + uint64_t *a0 = buf; + uint64_t *t0 = buf + (uint32_t)5U; + uint64_t *b = buf + (uint32_t)10U; + uint64_t *c = buf + (uint32_t)15U; + Hacl_Bignum_Fmul_fmul(c, t0, b); + Hacl_Bignum_Fsquare_fsquare_times(t0, c, (uint32_t)100U); + Hacl_Bignum_Fmul_fmul(t0, t0, c); + Hacl_Bignum_Fsquare_fsquare_times_inplace(t0, (uint32_t)50U); + Hacl_Bignum_Fmul_fmul(t0, t0, b); + Hacl_Bignum_Fsquare_fsquare_times_inplace(t0, (uint32_t)5U); + Hacl_Bignum_Fmul_fmul(out, t0, a0); +} + +inline static void +Hacl_Bignum_fsum(uint64_t *a, uint64_t *b) +{ + { + uint64_t xi = a[0U]; + uint64_t yi = b[0U]; + a[0U] = xi + yi; + } + { + uint64_t xi = a[1U]; + uint64_t yi = b[1U]; + a[1U] = xi + yi; + } + { + uint64_t xi = a[2U]; + uint64_t yi = b[2U]; + a[2U] = xi + yi; + } + { + uint64_t xi = a[3U]; + uint64_t yi = b[3U]; + a[3U] = xi + yi; + } + { + uint64_t xi = a[4U]; + uint64_t yi = b[4U]; + a[4U] = xi + yi; + } +} + +inline static void +Hacl_Bignum_fdifference(uint64_t *a, uint64_t *b) +{ + uint64_t tmp[5U] = { 0U }; + memcpy(tmp, b, (uint32_t)5U * sizeof b[0U]); + uint64_t b0 = tmp[0U]; + uint64_t b1 = tmp[1U]; + uint64_t b2 = tmp[2U]; + uint64_t b3 = tmp[3U]; + uint64_t b4 = tmp[4U]; + tmp[0U] = b0 + (uint64_t)0x3fffffffffff68U; + tmp[1U] = b1 + (uint64_t)0x3ffffffffffff8U; + tmp[2U] = b2 + (uint64_t)0x3ffffffffffff8U; + tmp[3U] = b3 + (uint64_t)0x3ffffffffffff8U; + tmp[4U] = b4 + (uint64_t)0x3ffffffffffff8U; + { + uint64_t xi = a[0U]; + uint64_t yi = tmp[0U]; + a[0U] = yi - xi; + } + { + uint64_t xi = a[1U]; + uint64_t yi = tmp[1U]; + a[1U] = yi - xi; + } + { + uint64_t xi = a[2U]; + uint64_t yi = tmp[2U]; + a[2U] = yi - xi; + } + { + uint64_t xi = a[3U]; + uint64_t yi = tmp[3U]; + a[3U] = yi - xi; + } + { + uint64_t xi = a[4U]; + uint64_t yi = tmp[4U]; + a[4U] = yi - xi; + } +} + +inline static void +Hacl_Bignum_fscalar(uint64_t *output, uint64_t *b, uint64_t s) +{ + KRML_CHECK_SIZE(FStar_UInt128_uint64_to_uint128((uint64_t)0U), (uint32_t)5U); + FStar_UInt128_t tmp[5U]; + for (uint32_t _i = 0U; _i < (uint32_t)5U; ++_i) + tmp[_i] = FStar_UInt128_uint64_to_uint128((uint64_t)0U); + { + uint64_t xi = b[0U]; + tmp[0U] = FStar_UInt128_mul_wide(xi, s); + } + { + uint64_t xi = b[1U]; + tmp[1U] = FStar_UInt128_mul_wide(xi, s); + } + { + uint64_t xi = b[2U]; + tmp[2U] = FStar_UInt128_mul_wide(xi, s); + } + { + uint64_t xi = b[3U]; + tmp[3U] = FStar_UInt128_mul_wide(xi, s); + } + { + uint64_t xi = b[4U]; + tmp[4U] = FStar_UInt128_mul_wide(xi, s); + } + Hacl_Bignum_Fproduct_carry_wide_(tmp); + FStar_UInt128_t b4 = tmp[4U]; + FStar_UInt128_t b0 = tmp[0U]; + FStar_UInt128_t + b4_ = FStar_UInt128_logand(b4, FStar_UInt128_uint64_to_uint128((uint64_t)0x7ffffffffffffU)); + FStar_UInt128_t + b0_ = + FStar_UInt128_add(b0, + FStar_UInt128_mul_wide((uint64_t)19U, + FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(b4, (uint32_t)51U)))); + tmp[4U] = b4_; + tmp[0U] = b0_; + Hacl_Bignum_Fproduct_copy_from_wide_(output, tmp); +} + +inline static void +Hacl_Bignum_fmul(uint64_t *output, uint64_t *a, uint64_t *b) +{ + Hacl_Bignum_Fmul_fmul(output, a, b); +} + +inline static void +Hacl_Bignum_crecip(uint64_t *output, uint64_t *input) +{ + Hacl_Bignum_Crecip_crecip(output, input); +} + +static void +Hacl_EC_Point_swap_conditional_step(uint64_t *a, uint64_t *b, uint64_t swap1, uint32_t ctr) +{ + uint32_t i = ctr - (uint32_t)1U; + uint64_t ai = a[i]; + uint64_t bi = b[i]; + uint64_t x = swap1 & (ai ^ bi); + uint64_t ai1 = ai ^ x; + uint64_t bi1 = bi ^ x; + a[i] = ai1; + b[i] = bi1; +} + +static void +Hacl_EC_Point_swap_conditional_(uint64_t *a, uint64_t *b, uint64_t swap1, uint32_t ctr) +{ + if (!(ctr == (uint32_t)0U)) { + Hacl_EC_Point_swap_conditional_step(a, b, swap1, ctr); + uint32_t i = ctr - (uint32_t)1U; + Hacl_EC_Point_swap_conditional_(a, b, swap1, i); + } +} + +static void +Hacl_EC_Point_swap_conditional(uint64_t *a, uint64_t *b, uint64_t iswap) +{ + uint64_t swap1 = (uint64_t)0U - iswap; + Hacl_EC_Point_swap_conditional_(a, b, swap1, (uint32_t)5U); + Hacl_EC_Point_swap_conditional_(a + (uint32_t)5U, b + (uint32_t)5U, swap1, (uint32_t)5U); +} + +static void +Hacl_EC_Point_copy(uint64_t *output, uint64_t *input) +{ + memcpy(output, input, (uint32_t)5U * sizeof input[0U]); + memcpy(output + (uint32_t)5U, + input + (uint32_t)5U, + (uint32_t)5U * sizeof(input + (uint32_t)5U)[0U]); +} + +static void +Hacl_EC_AddAndDouble_fmonty( + uint64_t *pp, + uint64_t *ppq, + uint64_t *p, + uint64_t *pq, + uint64_t *qmqp) +{ + uint64_t *qx = qmqp; + uint64_t *x2 = pp; + uint64_t *z2 = pp + (uint32_t)5U; + uint64_t *x3 = ppq; + uint64_t *z3 = ppq + (uint32_t)5U; + uint64_t *x = p; + uint64_t *z = p + (uint32_t)5U; + uint64_t *xprime = pq; + uint64_t *zprime = pq + (uint32_t)5U; + uint64_t buf[40U] = { 0U }; + uint64_t *origx = buf; + uint64_t *origxprime = buf + (uint32_t)5U; + uint64_t *xxprime0 = buf + (uint32_t)25U; + uint64_t *zzprime0 = buf + (uint32_t)30U; + memcpy(origx, x, (uint32_t)5U * sizeof x[0U]); + Hacl_Bignum_fsum(x, z); + Hacl_Bignum_fdifference(z, origx); + memcpy(origxprime, xprime, (uint32_t)5U * sizeof xprime[0U]); + Hacl_Bignum_fsum(xprime, zprime); + Hacl_Bignum_fdifference(zprime, origxprime); + Hacl_Bignum_fmul(xxprime0, xprime, z); + Hacl_Bignum_fmul(zzprime0, x, zprime); + uint64_t *origxprime0 = buf + (uint32_t)5U; + uint64_t *xx0 = buf + (uint32_t)15U; + uint64_t *zz0 = buf + (uint32_t)20U; + uint64_t *xxprime = buf + (uint32_t)25U; + uint64_t *zzprime = buf + (uint32_t)30U; + uint64_t *zzzprime = buf + (uint32_t)35U; + memcpy(origxprime0, xxprime, (uint32_t)5U * sizeof xxprime[0U]); + Hacl_Bignum_fsum(xxprime, zzprime); + Hacl_Bignum_fdifference(zzprime, origxprime0); + Hacl_Bignum_Fsquare_fsquare_times(x3, xxprime, (uint32_t)1U); + Hacl_Bignum_Fsquare_fsquare_times(zzzprime, zzprime, (uint32_t)1U); + Hacl_Bignum_fmul(z3, zzzprime, qx); + Hacl_Bignum_Fsquare_fsquare_times(xx0, x, (uint32_t)1U); + Hacl_Bignum_Fsquare_fsquare_times(zz0, z, (uint32_t)1U); + uint64_t *zzz = buf + (uint32_t)10U; + uint64_t *xx = buf + (uint32_t)15U; + uint64_t *zz = buf + (uint32_t)20U; + Hacl_Bignum_fmul(x2, xx, zz); + Hacl_Bignum_fdifference(zz, xx); + uint64_t scalar = (uint64_t)121665U; + Hacl_Bignum_fscalar(zzz, zz, scalar); + Hacl_Bignum_fsum(zzz, xx); + Hacl_Bignum_fmul(z2, zzz, zz); +} + +static void +Hacl_EC_Ladder_SmallLoop_cmult_small_loop_step( + uint64_t *nq, + uint64_t *nqpq, + uint64_t *nq2, + uint64_t *nqpq2, + uint64_t *q, + uint8_t byt) +{ + uint64_t bit = (uint64_t)(byt >> (uint32_t)7U); + Hacl_EC_Point_swap_conditional(nq, nqpq, bit); + Hacl_EC_AddAndDouble_fmonty(nq2, nqpq2, nq, nqpq, q); + uint64_t bit0 = (uint64_t)(byt >> (uint32_t)7U); + Hacl_EC_Point_swap_conditional(nq2, nqpq2, bit0); +} + +static void +Hacl_EC_Ladder_SmallLoop_cmult_small_loop_double_step( + uint64_t *nq, + uint64_t *nqpq, + uint64_t *nq2, + uint64_t *nqpq2, + uint64_t *q, + uint8_t byt) +{ + Hacl_EC_Ladder_SmallLoop_cmult_small_loop_step(nq, nqpq, nq2, nqpq2, q, byt); + uint8_t byt1 = byt << (uint32_t)1U; + Hacl_EC_Ladder_SmallLoop_cmult_small_loop_step(nq2, nqpq2, nq, nqpq, q, byt1); +} + +static void +Hacl_EC_Ladder_SmallLoop_cmult_small_loop( + uint64_t *nq, + uint64_t *nqpq, + uint64_t *nq2, + uint64_t *nqpq2, + uint64_t *q, + uint8_t byt, + uint32_t i) +{ + if (!(i == (uint32_t)0U)) { + uint32_t i_ = i - (uint32_t)1U; + Hacl_EC_Ladder_SmallLoop_cmult_small_loop_double_step(nq, nqpq, nq2, nqpq2, q, byt); + uint8_t byt_ = byt << (uint32_t)2U; + Hacl_EC_Ladder_SmallLoop_cmult_small_loop(nq, nqpq, nq2, nqpq2, q, byt_, i_); + } +} + +static void +Hacl_EC_Ladder_BigLoop_cmult_big_loop( + uint8_t *n1, + uint64_t *nq, + uint64_t *nqpq, + uint64_t *nq2, + uint64_t *nqpq2, + uint64_t *q, + uint32_t i) +{ + if (!(i == (uint32_t)0U)) { + uint32_t i1 = i - (uint32_t)1U; + uint8_t byte = n1[i1]; + Hacl_EC_Ladder_SmallLoop_cmult_small_loop(nq, nqpq, nq2, nqpq2, q, byte, (uint32_t)4U); + Hacl_EC_Ladder_BigLoop_cmult_big_loop(n1, nq, nqpq, nq2, nqpq2, q, i1); + } +} + +static void +Hacl_EC_Ladder_cmult(uint64_t *result, uint8_t *n1, uint64_t *q) +{ + uint64_t point_buf[40U] = { 0U }; + uint64_t *nq = point_buf; + uint64_t *nqpq = point_buf + (uint32_t)10U; + uint64_t *nq2 = point_buf + (uint32_t)20U; + uint64_t *nqpq2 = point_buf + (uint32_t)30U; + Hacl_EC_Point_copy(nqpq, q); + nq[0U] = (uint64_t)1U; + Hacl_EC_Ladder_BigLoop_cmult_big_loop(n1, nq, nqpq, nq2, nqpq2, q, (uint32_t)32U); + Hacl_EC_Point_copy(result, nq); +} + +static void +Hacl_EC_Format_fexpand(uint64_t *output, uint8_t *input) +{ + uint64_t i0 = load64_le(input); + uint8_t *x00 = input + (uint32_t)6U; + uint64_t i1 = load64_le(x00); + uint8_t *x01 = input + (uint32_t)12U; + uint64_t i2 = load64_le(x01); + uint8_t *x02 = input + (uint32_t)19U; + uint64_t i3 = load64_le(x02); + uint8_t *x0 = input + (uint32_t)24U; + uint64_t i4 = load64_le(x0); + uint64_t output0 = i0 & (uint64_t)0x7ffffffffffffU; + uint64_t output1 = i1 >> (uint32_t)3U & (uint64_t)0x7ffffffffffffU; + uint64_t output2 = i2 >> (uint32_t)6U & (uint64_t)0x7ffffffffffffU; + uint64_t output3 = i3 >> (uint32_t)1U & (uint64_t)0x7ffffffffffffU; + uint64_t output4 = i4 >> (uint32_t)12U & (uint64_t)0x7ffffffffffffU; + output[0U] = output0; + output[1U] = output1; + output[2U] = output2; + output[3U] = output3; + output[4U] = output4; +} + +static void +Hacl_EC_Format_fcontract_first_carry_pass(uint64_t *input) +{ + uint64_t t0 = input[0U]; + uint64_t t1 = input[1U]; + uint64_t t2 = input[2U]; + uint64_t t3 = input[3U]; + uint64_t t4 = input[4U]; + uint64_t t1_ = t1 + (t0 >> (uint32_t)51U); + uint64_t t0_ = t0 & (uint64_t)0x7ffffffffffffU; + uint64_t t2_ = t2 + (t1_ >> (uint32_t)51U); + uint64_t t1__ = t1_ & (uint64_t)0x7ffffffffffffU; + uint64_t t3_ = t3 + (t2_ >> (uint32_t)51U); + uint64_t t2__ = t2_ & (uint64_t)0x7ffffffffffffU; + uint64_t t4_ = t4 + (t3_ >> (uint32_t)51U); + uint64_t t3__ = t3_ & (uint64_t)0x7ffffffffffffU; + input[0U] = t0_; + input[1U] = t1__; + input[2U] = t2__; + input[3U] = t3__; + input[4U] = t4_; +} + +static void +Hacl_EC_Format_fcontract_first_carry_full(uint64_t *input) +{ + Hacl_EC_Format_fcontract_first_carry_pass(input); + Hacl_Bignum_Modulo_carry_top(input); +} + +static void +Hacl_EC_Format_fcontract_second_carry_pass(uint64_t *input) +{ + uint64_t t0 = input[0U]; + uint64_t t1 = input[1U]; + uint64_t t2 = input[2U]; + uint64_t t3 = input[3U]; + uint64_t t4 = input[4U]; + uint64_t t1_ = t1 + (t0 >> (uint32_t)51U); + uint64_t t0_ = t0 & (uint64_t)0x7ffffffffffffU; + uint64_t t2_ = t2 + (t1_ >> (uint32_t)51U); + uint64_t t1__ = t1_ & (uint64_t)0x7ffffffffffffU; + uint64_t t3_ = t3 + (t2_ >> (uint32_t)51U); + uint64_t t2__ = t2_ & (uint64_t)0x7ffffffffffffU; + uint64_t t4_ = t4 + (t3_ >> (uint32_t)51U); + uint64_t t3__ = t3_ & (uint64_t)0x7ffffffffffffU; + input[0U] = t0_; + input[1U] = t1__; + input[2U] = t2__; + input[3U] = t3__; + input[4U] = t4_; +} + +static void +Hacl_EC_Format_fcontract_second_carry_full(uint64_t *input) +{ + Hacl_EC_Format_fcontract_second_carry_pass(input); + Hacl_Bignum_Modulo_carry_top(input); + uint64_t i0 = input[0U]; + uint64_t i1 = input[1U]; + uint64_t i0_ = i0 & (uint64_t)0x7ffffffffffffU; + uint64_t i1_ = i1 + (i0 >> (uint32_t)51U); + input[0U] = i0_; + input[1U] = i1_; +} + +static void +Hacl_EC_Format_fcontract_trim(uint64_t *input) +{ + uint64_t a0 = input[0U]; + uint64_t a1 = input[1U]; + uint64_t a2 = input[2U]; + uint64_t a3 = input[3U]; + uint64_t a4 = input[4U]; + uint64_t mask0 = FStar_UInt64_gte_mask(a0, (uint64_t)0x7ffffffffffedU); + uint64_t mask1 = FStar_UInt64_eq_mask(a1, (uint64_t)0x7ffffffffffffU); + uint64_t mask2 = FStar_UInt64_eq_mask(a2, (uint64_t)0x7ffffffffffffU); + uint64_t mask3 = FStar_UInt64_eq_mask(a3, (uint64_t)0x7ffffffffffffU); + uint64_t mask4 = FStar_UInt64_eq_mask(a4, (uint64_t)0x7ffffffffffffU); + uint64_t mask = (((mask0 & mask1) & mask2) & mask3) & mask4; + uint64_t a0_ = a0 - ((uint64_t)0x7ffffffffffedU & mask); + uint64_t a1_ = a1 - ((uint64_t)0x7ffffffffffffU & mask); + uint64_t a2_ = a2 - ((uint64_t)0x7ffffffffffffU & mask); + uint64_t a3_ = a3 - ((uint64_t)0x7ffffffffffffU & mask); + uint64_t a4_ = a4 - ((uint64_t)0x7ffffffffffffU & mask); + input[0U] = a0_; + input[1U] = a1_; + input[2U] = a2_; + input[3U] = a3_; + input[4U] = a4_; +} + +static void +Hacl_EC_Format_fcontract_store(uint8_t *output, uint64_t *input) +{ + uint64_t t0 = input[0U]; + uint64_t t1 = input[1U]; + uint64_t t2 = input[2U]; + uint64_t t3 = input[3U]; + uint64_t t4 = input[4U]; + uint64_t o0 = t1 << (uint32_t)51U | t0; + uint64_t o1 = t2 << (uint32_t)38U | t1 >> (uint32_t)13U; + uint64_t o2 = t3 << (uint32_t)25U | t2 >> (uint32_t)26U; + uint64_t o3 = t4 << (uint32_t)12U | t3 >> (uint32_t)39U; + uint8_t *b0 = output; + uint8_t *b1 = output + (uint32_t)8U; + uint8_t *b2 = output + (uint32_t)16U; + uint8_t *b3 = output + (uint32_t)24U; + store64_le(b0, o0); + store64_le(b1, o1); + store64_le(b2, o2); + store64_le(b3, o3); +} + +static void +Hacl_EC_Format_fcontract(uint8_t *output, uint64_t *input) +{ + Hacl_EC_Format_fcontract_first_carry_full(input); + Hacl_EC_Format_fcontract_second_carry_full(input); + Hacl_EC_Format_fcontract_trim(input); + Hacl_EC_Format_fcontract_store(output, input); +} + +static void +Hacl_EC_Format_scalar_of_point(uint8_t *scalar, uint64_t *point) +{ + uint64_t *x = point; + uint64_t *z = point + (uint32_t)5U; + uint64_t buf[10U] = { 0U }; + uint64_t *zmone = buf; + uint64_t *sc = buf + (uint32_t)5U; + Hacl_Bignum_crecip(zmone, z); + Hacl_Bignum_fmul(sc, x, zmone); + Hacl_EC_Format_fcontract(scalar, sc); +} + +void +Hacl_EC_crypto_scalarmult(uint8_t *mypublic, uint8_t *secret, uint8_t *basepoint) +{ + uint64_t buf0[10U] = { 0U }; + uint64_t *x0 = buf0; + uint64_t *z = buf0 + (uint32_t)5U; + Hacl_EC_Format_fexpand(x0, basepoint); + z[0U] = (uint64_t)1U; + uint64_t *q = buf0; + uint8_t e[32U] = { 0U }; + memcpy(e, secret, (uint32_t)32U * sizeof secret[0U]); + uint8_t e0 = e[0U]; + uint8_t e31 = e[31U]; + uint8_t e01 = e0 & (uint8_t)248U; + uint8_t e311 = e31 & (uint8_t)127U; + uint8_t e312 = e311 | (uint8_t)64U; + e[0U] = e01; + e[31U] = e312; + uint8_t *scalar = e; + uint64_t buf[15U] = { 0U }; + uint64_t *nq = buf; + uint64_t *x = nq; + x[0U] = (uint64_t)1U; + Hacl_EC_Ladder_cmult(nq, scalar, q); + Hacl_EC_Format_scalar_of_point(mypublic, nq); +} + +void +Hacl_Curve25519_crypto_scalarmult(uint8_t *mypublic, uint8_t *secret, uint8_t *basepoint) +{ + Hacl_EC_crypto_scalarmult(mypublic, secret, basepoint); +} diff --git a/security/nss/lib/freebl/verified/Hacl_Curve25519.h b/security/nss/lib/freebl/verified/Hacl_Curve25519.h new file mode 100644 index 000000000..0e443f177 --- /dev/null +++ b/security/nss/lib/freebl/verified/Hacl_Curve25519.h @@ -0,0 +1,57 @@ +/* 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_Curve25519_H +#define __Hacl_Curve25519_H + +typedef uint64_t Hacl_Bignum_Constants_limb; + +typedef FStar_UInt128_t Hacl_Bignum_Constants_wide; + +typedef uint64_t Hacl_Bignum_Parameters_limb; + +typedef FStar_UInt128_t Hacl_Bignum_Parameters_wide; + +typedef uint32_t Hacl_Bignum_Parameters_ctr; + +typedef uint64_t *Hacl_Bignum_Parameters_felem; + +typedef FStar_UInt128_t *Hacl_Bignum_Parameters_felem_wide; + +typedef void *Hacl_Bignum_Parameters_seqelem; + +typedef void *Hacl_Bignum_Parameters_seqelem_wide; + +typedef FStar_UInt128_t Hacl_Bignum_Wide_t; + +typedef uint64_t Hacl_Bignum_Limb_t; + +extern void Hacl_Bignum_lemma_diff(Prims_int x0, Prims_int x1, Prims_pos x2); + +typedef uint64_t *Hacl_EC_Point_point; + +typedef uint8_t *Hacl_EC_Ladder_SmallLoop_uint8_p; + +typedef uint8_t *Hacl_EC_Ladder_uint8_p; + +typedef uint8_t *Hacl_EC_Format_uint8_p; + +void Hacl_EC_crypto_scalarmult(uint8_t *mypublic, uint8_t *secret, uint8_t *basepoint); + +typedef uint8_t *Hacl_Curve25519_uint8_p; + +void Hacl_Curve25519_crypto_scalarmult(uint8_t *mypublic, uint8_t *secret, uint8_t *basepoint); +#endif diff --git a/security/nss/lib/freebl/verified/Hacl_Poly1305_64.c b/security/nss/lib/freebl/verified/Hacl_Poly1305_64.c new file mode 100644 index 000000000..984031ae2 --- /dev/null +++ b/security/nss/lib/freebl/verified/Hacl_Poly1305_64.c @@ -0,0 +1,485 @@ +/* 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_64.h" + +inline static void +Hacl_Bignum_Modulo_reduce(uint64_t *b) +{ + uint64_t b0 = b[0U]; + b[0U] = (b0 << (uint32_t)4U) + (b0 << (uint32_t)2U); +} + +inline static void +Hacl_Bignum_Modulo_carry_top(uint64_t *b) +{ + uint64_t b2 = b[2U]; + uint64_t b0 = b[0U]; + uint64_t b2_42 = b2 >> (uint32_t)42U; + b[2U] = b2 & (uint64_t)0x3ffffffffffU; + b[0U] = (b2_42 << (uint32_t)2U) + b2_42 + b0; +} + +inline static void +Hacl_Bignum_Modulo_carry_top_wide(FStar_UInt128_t *b) +{ + FStar_UInt128_t b2 = b[2U]; + FStar_UInt128_t b0 = b[0U]; + FStar_UInt128_t + b2_ = FStar_UInt128_logand(b2, FStar_UInt128_uint64_to_uint128((uint64_t)0x3ffffffffffU)); + uint64_t b2_42 = FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(b2, (uint32_t)42U)); + FStar_UInt128_t + b0_ = FStar_UInt128_add(b0, FStar_UInt128_uint64_to_uint128((b2_42 << (uint32_t)2U) + b2_42)); + b[2U] = b2_; + b[0U] = b0_; +} + +inline static void +Hacl_Bignum_Fproduct_copy_from_wide_(uint64_t *output, FStar_UInt128_t *input) +{ + for (uint32_t i = (uint32_t)0U; i < (uint32_t)3U; i = i + (uint32_t)1U) { + FStar_UInt128_t xi = input[i]; + output[i] = FStar_UInt128_uint128_to_uint64(xi); + } +} + +inline static void +Hacl_Bignum_Fproduct_sum_scalar_multiplication_( + FStar_UInt128_t *output, + uint64_t *input, + uint64_t s) +{ + for (uint32_t i = (uint32_t)0U; i < (uint32_t)3U; i = i + (uint32_t)1U) { + FStar_UInt128_t xi = output[i]; + uint64_t yi = input[i]; + output[i] = FStar_UInt128_add_mod(xi, FStar_UInt128_mul_wide(yi, s)); + } +} + +inline static void +Hacl_Bignum_Fproduct_carry_wide_(FStar_UInt128_t *tmp) +{ + for (uint32_t i = (uint32_t)0U; i < (uint32_t)2U; i = i + (uint32_t)1U) { + uint32_t ctr = i; + FStar_UInt128_t tctr = tmp[ctr]; + FStar_UInt128_t tctrp1 = tmp[ctr + (uint32_t)1U]; + uint64_t r0 = FStar_UInt128_uint128_to_uint64(tctr) & (uint64_t)0xfffffffffffU; + FStar_UInt128_t c = FStar_UInt128_shift_right(tctr, (uint32_t)44U); + tmp[ctr] = FStar_UInt128_uint64_to_uint128(r0); + tmp[ctr + (uint32_t)1U] = FStar_UInt128_add(tctrp1, c); + } +} + +inline static void +Hacl_Bignum_Fproduct_carry_limb_(uint64_t *tmp) +{ + for (uint32_t i = (uint32_t)0U; i < (uint32_t)2U; i = i + (uint32_t)1U) { + uint32_t ctr = i; + uint64_t tctr = tmp[ctr]; + uint64_t tctrp1 = tmp[ctr + (uint32_t)1U]; + uint64_t r0 = tctr & (uint64_t)0xfffffffffffU; + uint64_t c = tctr >> (uint32_t)44U; + tmp[ctr] = r0; + tmp[ctr + (uint32_t)1U] = tctrp1 + c; + } +} + +inline static void +Hacl_Bignum_Fmul_shift_reduce(uint64_t *output) +{ + uint64_t tmp = output[2U]; + for (uint32_t i = (uint32_t)0U; i < (uint32_t)2U; i = i + (uint32_t)1U) { + uint32_t ctr = (uint32_t)3U - i - (uint32_t)1U; + uint64_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_(FStar_UInt128_t *output, uint64_t *input, uint64_t *input2) +{ + for (uint32_t i = (uint32_t)0U; i < (uint32_t)2U; i = i + (uint32_t)1U) { + uint64_t input2i = input2[i]; + Hacl_Bignum_Fproduct_sum_scalar_multiplication_(output, input, input2i); + Hacl_Bignum_Fmul_shift_reduce(input); + } + uint32_t i = (uint32_t)2U; + uint64_t input2i = input2[i]; + Hacl_Bignum_Fproduct_sum_scalar_multiplication_(output, input, input2i); +} + +inline static void +Hacl_Bignum_Fmul_fmul(uint64_t *output, uint64_t *input, uint64_t *input2) +{ + uint64_t tmp[3U] = { 0U }; + memcpy(tmp, input, (uint32_t)3U * sizeof input[0U]); + KRML_CHECK_SIZE(FStar_UInt128_uint64_to_uint128((uint64_t)0U), (uint32_t)3U); + FStar_UInt128_t t[3U]; + for (uint32_t _i = 0U; _i < (uint32_t)3U; ++_i) + t[_i] = FStar_UInt128_uint64_to_uint128((uint64_t)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); + uint64_t i0 = output[0U]; + uint64_t i1 = output[1U]; + uint64_t i0_ = i0 & (uint64_t)0xfffffffffffU; + uint64_t i1_ = i1 + (i0 >> (uint32_t)44U); + output[0U] = i0_; + output[1U] = i1_; +} + +inline static void +Hacl_Bignum_AddAndMultiply_add_and_multiply(uint64_t *acc, uint64_t *block, uint64_t *r) +{ + for (uint32_t i = (uint32_t)0U; i < (uint32_t)3U; i = i + (uint32_t)1U) { + uint64_t xi = acc[i]; + uint64_t yi = block[i]; + acc[i] = xi + yi; + } + Hacl_Bignum_Fmul_fmul(acc, acc, r); +} + +inline static void +Hacl_Impl_Poly1305_64_poly1305_update( + Hacl_Impl_Poly1305_64_State_poly1305_state st, + uint8_t *m) +{ + Hacl_Impl_Poly1305_64_State_poly1305_state scrut0 = st; + uint64_t *h = scrut0.h; + uint64_t *acc = h; + Hacl_Impl_Poly1305_64_State_poly1305_state scrut = st; + uint64_t *r = scrut.r; + uint64_t *r3 = r; + uint64_t tmp[3U] = { 0U }; + FStar_UInt128_t m0 = load128_le(m); + uint64_t r0 = FStar_UInt128_uint128_to_uint64(m0) & (uint64_t)0xfffffffffffU; + uint64_t + r1 = + FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(m0, (uint32_t)44U)) & (uint64_t)0xfffffffffffU; + uint64_t r2 = FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(m0, (uint32_t)88U)); + tmp[0U] = r0; + tmp[1U] = r1; + tmp[2U] = r2; + uint64_t b2 = tmp[2U]; + uint64_t b2_ = (uint64_t)0x10000000000U | b2; + tmp[2U] = b2_; + Hacl_Bignum_AddAndMultiply_add_and_multiply(acc, tmp, r3); +} + +inline static void +Hacl_Impl_Poly1305_64_poly1305_process_last_block_( + uint8_t *block, + Hacl_Impl_Poly1305_64_State_poly1305_state st, + uint8_t *m, + uint64_t rem_) +{ + uint64_t tmp[3U] = { 0U }; + FStar_UInt128_t m0 = load128_le(block); + uint64_t r0 = FStar_UInt128_uint128_to_uint64(m0) & (uint64_t)0xfffffffffffU; + uint64_t + r1 = + FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(m0, (uint32_t)44U)) & (uint64_t)0xfffffffffffU; + uint64_t r2 = FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(m0, (uint32_t)88U)); + tmp[0U] = r0; + tmp[1U] = r1; + tmp[2U] = r2; + Hacl_Impl_Poly1305_64_State_poly1305_state scrut0 = st; + uint64_t *h = scrut0.h; + Hacl_Impl_Poly1305_64_State_poly1305_state scrut = st; + uint64_t *r = scrut.r; + Hacl_Bignum_AddAndMultiply_add_and_multiply(h, tmp, r); +} + +inline static void +Hacl_Impl_Poly1305_64_poly1305_process_last_block( + Hacl_Impl_Poly1305_64_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_64_poly1305_process_last_block_(block, st, m, rem_); +} + +static void +Hacl_Impl_Poly1305_64_poly1305_last_pass(uint64_t *acc) +{ + Hacl_Bignum_Fproduct_carry_limb_(acc); + Hacl_Bignum_Modulo_carry_top(acc); + uint64_t a0 = acc[0U]; + uint64_t a10 = acc[1U]; + uint64_t a20 = acc[2U]; + uint64_t a0_ = a0 & (uint64_t)0xfffffffffffU; + uint64_t r0 = a0 >> (uint32_t)44U; + uint64_t a1_ = (a10 + r0) & (uint64_t)0xfffffffffffU; + uint64_t r1 = (a10 + r0) >> (uint32_t)44U; + uint64_t a2_ = a20 + r1; + acc[0U] = a0_; + acc[1U] = a1_; + acc[2U] = a2_; + Hacl_Bignum_Modulo_carry_top(acc); + uint64_t i0 = acc[0U]; + uint64_t i1 = acc[1U]; + uint64_t i0_ = i0 & (uint64_t)0xfffffffffffU; + uint64_t i1_ = i1 + (i0 >> (uint32_t)44U); + acc[0U] = i0_; + acc[1U] = i1_; + uint64_t a00 = acc[0U]; + uint64_t a1 = acc[1U]; + uint64_t a2 = acc[2U]; + uint64_t mask0 = FStar_UInt64_gte_mask(a00, (uint64_t)0xffffffffffbU); + uint64_t mask1 = FStar_UInt64_eq_mask(a1, (uint64_t)0xfffffffffffU); + uint64_t mask2 = FStar_UInt64_eq_mask(a2, (uint64_t)0x3ffffffffffU); + uint64_t mask = (mask0 & mask1) & mask2; + uint64_t a0_0 = a00 - ((uint64_t)0xffffffffffbU & mask); + uint64_t a1_0 = a1 - ((uint64_t)0xfffffffffffU & mask); + uint64_t a2_0 = a2 - ((uint64_t)0x3ffffffffffU & mask); + acc[0U] = a0_0; + acc[1U] = a1_0; + acc[2U] = a2_0; +} + +static Hacl_Impl_Poly1305_64_State_poly1305_state +Hacl_Impl_Poly1305_64_mk_state(uint64_t *r, uint64_t *h) +{ + return ((Hacl_Impl_Poly1305_64_State_poly1305_state){.r = r, .h = h }); +} + +static void +Hacl_Standalone_Poly1305_64_poly1305_blocks( + Hacl_Impl_Poly1305_64_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_64_poly1305_update(st, block); + uint64_t len2 = len1 - (uint64_t)1U; + Hacl_Standalone_Poly1305_64_poly1305_blocks(st, tail1, len2); + } +} + +static void +Hacl_Standalone_Poly1305_64_poly1305_partial( + Hacl_Impl_Poly1305_64_State_poly1305_state st, + uint8_t *input, + uint64_t len1, + uint8_t *kr) +{ + Hacl_Impl_Poly1305_64_State_poly1305_state scrut = st; + uint64_t *r = scrut.r; + uint64_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))); + uint64_t r0 = FStar_UInt128_uint128_to_uint64(k_clamped) & (uint64_t)0xfffffffffffU; + uint64_t + r1 = + FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(k_clamped, (uint32_t)44U)) & (uint64_t)0xfffffffffffU; + uint64_t + r2 = FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(k_clamped, (uint32_t)88U)); + x0[0U] = r0; + x0[1U] = r1; + x0[2U] = r2; + Hacl_Impl_Poly1305_64_State_poly1305_state scrut0 = st; + uint64_t *h = scrut0.h; + uint64_t *x00 = h; + x00[0U] = (uint64_t)0U; + x00[1U] = (uint64_t)0U; + x00[2U] = (uint64_t)0U; + Hacl_Standalone_Poly1305_64_poly1305_blocks(st, input, len1); +} + +static void +Hacl_Standalone_Poly1305_64_poly1305_complete( + Hacl_Impl_Poly1305_64_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_64_poly1305_partial(st, part_input, len16, kr); + if (!(rem16 == (uint64_t)0U)) + Hacl_Impl_Poly1305_64_poly1305_process_last_block(st, last_block, rem16); + Hacl_Impl_Poly1305_64_State_poly1305_state scrut = st; + uint64_t *h = scrut.h; + uint64_t *acc = h; + Hacl_Impl_Poly1305_64_poly1305_last_pass(acc); +} + +static void +Hacl_Standalone_Poly1305_64_crypto_onetimeauth_( + uint8_t *output, + uint8_t *input, + uint64_t len1, + uint8_t *k1) +{ + uint64_t buf[6U] = { 0U }; + uint64_t *r = buf; + uint64_t *h = buf + (uint32_t)3U; + Hacl_Impl_Poly1305_64_State_poly1305_state st = Hacl_Impl_Poly1305_64_mk_state(r, h); + uint8_t *key_s = k1 + (uint32_t)16U; + Hacl_Standalone_Poly1305_64_poly1305_complete(st, input, len1, k1); + Hacl_Impl_Poly1305_64_State_poly1305_state scrut = st; + uint64_t *h3 = scrut.h; + uint64_t *acc = h3; + FStar_UInt128_t k_ = load128_le(key_s); + uint64_t h0 = acc[0U]; + uint64_t h1 = acc[1U]; + uint64_t h2 = acc[2U]; + FStar_UInt128_t + acc_ = + FStar_UInt128_logor(FStar_UInt128_shift_left(FStar_UInt128_uint64_to_uint128(h2 + << (uint32_t)24U | + h1 >> (uint32_t)20U), + (uint32_t)64U), + FStar_UInt128_uint64_to_uint128(h1 << (uint32_t)44U | h0)); + FStar_UInt128_t mac_ = FStar_UInt128_add_mod(acc_, k_); + store128_le(output, mac_); +} + +static void +Hacl_Standalone_Poly1305_64_crypto_onetimeauth( + uint8_t *output, + uint8_t *input, + uint64_t len1, + uint8_t *k1) +{ + Hacl_Standalone_Poly1305_64_crypto_onetimeauth_(output, input, len1, k1); +} + +Hacl_Impl_Poly1305_64_State_poly1305_state +Hacl_Poly1305_64_mk_state(uint64_t *r, uint64_t *acc) +{ + return Hacl_Impl_Poly1305_64_mk_state(r, acc); +} + +void +Hacl_Poly1305_64_init(Hacl_Impl_Poly1305_64_State_poly1305_state st, uint8_t *k1) +{ + Hacl_Impl_Poly1305_64_State_poly1305_state scrut = st; + uint64_t *r = scrut.r; + uint64_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))); + uint64_t r0 = FStar_UInt128_uint128_to_uint64(k_clamped) & (uint64_t)0xfffffffffffU; + uint64_t + r1 = + FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(k_clamped, (uint32_t)44U)) & (uint64_t)0xfffffffffffU; + uint64_t + r2 = FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(k_clamped, (uint32_t)88U)); + x0[0U] = r0; + x0[1U] = r1; + x0[2U] = r2; + Hacl_Impl_Poly1305_64_State_poly1305_state scrut0 = st; + uint64_t *h = scrut0.h; + uint64_t *x00 = h; + x00[0U] = (uint64_t)0U; + x00[1U] = (uint64_t)0U; + x00[2U] = (uint64_t)0U; +} + +void +Hacl_Poly1305_64_update_block(Hacl_Impl_Poly1305_64_State_poly1305_state st, uint8_t *m) +{ + Hacl_Impl_Poly1305_64_poly1305_update(st, m); +} + +void +Hacl_Poly1305_64_update( + Hacl_Impl_Poly1305_64_State_poly1305_state st, + uint8_t *m, + uint32_t num_blocks) +{ + if (!(num_blocks == (uint32_t)0U)) { + uint8_t *block = m; + uint8_t *m_ = m + (uint32_t)16U; + uint32_t n1 = num_blocks - (uint32_t)1U; + Hacl_Poly1305_64_update_block(st, block); + Hacl_Poly1305_64_update(st, m_, n1); + } +} + +void +Hacl_Poly1305_64_update_last( + Hacl_Impl_Poly1305_64_State_poly1305_state st, + uint8_t *m, + uint32_t len1) +{ + if (!((uint64_t)len1 == (uint64_t)0U)) + Hacl_Impl_Poly1305_64_poly1305_process_last_block(st, m, (uint64_t)len1); + Hacl_Impl_Poly1305_64_State_poly1305_state scrut = st; + uint64_t *h = scrut.h; + uint64_t *acc = h; + Hacl_Impl_Poly1305_64_poly1305_last_pass(acc); +} + +void +Hacl_Poly1305_64_finish( + Hacl_Impl_Poly1305_64_State_poly1305_state st, + uint8_t *mac, + uint8_t *k1) +{ + Hacl_Impl_Poly1305_64_State_poly1305_state scrut = st; + uint64_t *h = scrut.h; + uint64_t *acc = h; + FStar_UInt128_t k_ = load128_le(k1); + uint64_t h0 = acc[0U]; + uint64_t h1 = acc[1U]; + uint64_t h2 = acc[2U]; + FStar_UInt128_t + acc_ = + FStar_UInt128_logor(FStar_UInt128_shift_left(FStar_UInt128_uint64_to_uint128(h2 + << (uint32_t)24U | + h1 >> (uint32_t)20U), + (uint32_t)64U), + FStar_UInt128_uint64_to_uint128(h1 << (uint32_t)44U | h0)); + FStar_UInt128_t mac_ = FStar_UInt128_add_mod(acc_, k_); + store128_le(mac, mac_); +} + +void +Hacl_Poly1305_64_crypto_onetimeauth( + uint8_t *output, + uint8_t *input, + uint64_t len1, + uint8_t *k1) +{ + Hacl_Standalone_Poly1305_64_crypto_onetimeauth(output, input, len1, k1); +} diff --git a/security/nss/lib/freebl/verified/Hacl_Poly1305_64.h b/security/nss/lib/freebl/verified/Hacl_Poly1305_64.h new file mode 100644 index 000000000..0aa9a0de3 --- /dev/null +++ b/security/nss/lib/freebl/verified/Hacl_Poly1305_64.h @@ -0,0 +1,99 @@ +/* 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_64_H +#define __Hacl_Poly1305_64_H + +typedef uint64_t Hacl_Bignum_Constants_limb; + +typedef FStar_UInt128_t Hacl_Bignum_Constants_wide; + +typedef FStar_UInt128_t Hacl_Bignum_Wide_t; + +typedef uint64_t Hacl_Bignum_Limb_t; + +typedef void *Hacl_Impl_Poly1305_64_State_log_t; + +typedef uint8_t *Hacl_Impl_Poly1305_64_State_uint8_p; + +typedef uint64_t *Hacl_Impl_Poly1305_64_State_bigint; + +typedef void *Hacl_Impl_Poly1305_64_State_seqelem; + +typedef uint64_t *Hacl_Impl_Poly1305_64_State_elemB; + +typedef uint8_t *Hacl_Impl_Poly1305_64_State_wordB; + +typedef uint8_t *Hacl_Impl_Poly1305_64_State_wordB_16; + +typedef struct +{ + uint64_t *r; + uint64_t *h; +} Hacl_Impl_Poly1305_64_State_poly1305_state; + +typedef void *Hacl_Impl_Poly1305_64_log_t; + +typedef uint64_t *Hacl_Impl_Poly1305_64_bigint; + +typedef uint8_t *Hacl_Impl_Poly1305_64_uint8_p; + +typedef uint64_t *Hacl_Impl_Poly1305_64_elemB; + +typedef uint8_t *Hacl_Impl_Poly1305_64_wordB; + +typedef uint8_t *Hacl_Impl_Poly1305_64_wordB_16; + +typedef uint8_t *Hacl_Poly1305_64_uint8_p; + +typedef uint64_t Hacl_Poly1305_64_uint64_t; + +typedef uint8_t *Hacl_Poly1305_64_key; + +typedef Hacl_Impl_Poly1305_64_State_poly1305_state Hacl_Poly1305_64_state; + +Hacl_Impl_Poly1305_64_State_poly1305_state +Hacl_Poly1305_64_mk_state(uint64_t *r, uint64_t *acc); + +void Hacl_Poly1305_64_init(Hacl_Impl_Poly1305_64_State_poly1305_state st, uint8_t *k1); + +void Hacl_Poly1305_64_update_block(Hacl_Impl_Poly1305_64_State_poly1305_state st, uint8_t *m); + +void +Hacl_Poly1305_64_update( + Hacl_Impl_Poly1305_64_State_poly1305_state st, + uint8_t *m, + uint32_t num_blocks); + +void +Hacl_Poly1305_64_update_last( + Hacl_Impl_Poly1305_64_State_poly1305_state st, + uint8_t *m, + uint32_t len1); + +void +Hacl_Poly1305_64_finish( + Hacl_Impl_Poly1305_64_State_poly1305_state st, + uint8_t *mac, + uint8_t *k1); + +void +Hacl_Poly1305_64_crypto_onetimeauth( + uint8_t *output, + uint8_t *input, + uint64_t len1, + uint8_t *k1); +#endif diff --git a/security/nss/lib/freebl/verified/kremlib.h b/security/nss/lib/freebl/verified/kremlib.h new file mode 100644 index 000000000..c12164e74 --- /dev/null +++ b/security/nss/lib/freebl/verified/kremlib.h @@ -0,0 +1,672 @@ +/* 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. + */ + +#ifndef __KREMLIB_H +#define __KREMLIB_H + +#include "kremlib_base.h" + +/* For tests only: we might need this function to be forward-declared, because + * the dependency on WasmSupport appears very late, after SimplifyWasm, and + * sadly, after the topological order has been done. */ +void WasmSupport_check_buffer_size(uint32_t s); + +/******************************************************************************/ +/* Stubs to ease compilation of non-Low* code */ +/******************************************************************************/ + +/* Some types that KreMLin has no special knowledge of; many of them appear in + * signatures of ghost functions, meaning that it suffices to give them (any) + * definition. */ +typedef void *FStar_Seq_Base_seq, *Prims_prop, *FStar_HyperStack_mem, + *FStar_Set_set, *Prims_st_pre_h, *FStar_Heap_heap, *Prims_all_pre_h, + *FStar_TSet_set, *Prims_list, *FStar_Map_t, *FStar_UInt63_t_, + *FStar_Int63_t_, *FStar_UInt63_t, *FStar_Int63_t, *FStar_UInt_uint_t, + *FStar_Int_int_t, *FStar_HyperStack_stackref, *FStar_Bytes_bytes, + *FStar_HyperHeap_rid, *FStar_Heap_aref, *FStar_Monotonic_Heap_heap, + *FStar_Monotonic_Heap_aref, *FStar_Monotonic_HyperHeap_rid, + *FStar_Monotonic_HyperStack_mem, *FStar_Char_char_; + +typedef const char *Prims_string; + +/* For "bare" targets that do not have a C stdlib, the user might want to use + * [-add-include '"mydefinitions.h"'] and override these. */ +#ifndef KRML_HOST_PRINTF +#define KRML_HOST_PRINTF printf +#endif + +#ifndef KRML_HOST_EXIT +#define KRML_HOST_EXIT exit +#endif + +#ifndef KRML_HOST_MALLOC +#define KRML_HOST_MALLOC malloc +#endif + +/* In statement position, exiting is easy. */ +#define KRML_EXIT \ + do { \ + KRML_HOST_PRINTF("Unimplemented function at %s:%d\n", __FILE__, __LINE__); \ + KRML_HOST_EXIT(254); \ + } while (0) + +/* In expression position, use the comma-operator and a malloc to return an + * expression of the right size. KreMLin passes t as the parameter to the macro. + */ +#define KRML_EABORT(t, msg) \ + (KRML_HOST_PRINTF("KreMLin abort at %s:%d\n%s\n", __FILE__, __LINE__, msg), \ + KRML_HOST_EXIT(255), *((t *)KRML_HOST_MALLOC(sizeof(t)))) + +/* In FStar.Buffer.fst, the size of arrays is uint32_t, but it's a number of + * *elements*. Do an ugly, run-time check (some of which KreMLin can eliminate). + */ +#define KRML_CHECK_SIZE(elt, size) \ + if (((size_t)size) > SIZE_MAX / sizeof(elt)) { \ + KRML_HOST_PRINTF( \ + "Maximum allocatable size exceeded, aborting before overflow at " \ + "%s:%d\n", \ + __FILE__, __LINE__); \ + KRML_HOST_EXIT(253); \ + } + +/* A series of GCC atrocities to trace function calls (kremlin's [-d c-calls] + * option). Useful when trying to debug, say, Wasm, to compare traces. */ +/* clang-format off */ +#ifdef __GNUC__ +#define KRML_FORMAT(X) _Generic((X), \ + uint8_t : "0x%08" PRIx8, \ + uint16_t: "0x%08" PRIx16, \ + uint32_t: "0x%08" PRIx32, \ + uint64_t: "0x%08" PRIx64, \ + int8_t : "0x%08" PRIx8, \ + int16_t : "0x%08" PRIx16, \ + int32_t : "0x%08" PRIx32, \ + int64_t : "0x%08" PRIx64, \ + default : "%s") + +#define KRML_FORMAT_ARG(X) _Generic((X), \ + uint8_t : X, \ + uint16_t: X, \ + uint32_t: X, \ + uint64_t: X, \ + int8_t : X, \ + int16_t : X, \ + int32_t : X, \ + int64_t : X, \ + default : "unknown") +/* clang-format on */ + +#define KRML_DEBUG_RETURN(X) \ + ({ \ + __auto_type _ret = (X); \ + KRML_HOST_PRINTF("returning: "); \ + KRML_HOST_PRINTF(KRML_FORMAT(_ret), KRML_FORMAT_ARG(_ret)); \ + KRML_HOST_PRINTF(" \n"); \ + _ret; \ + }) +#endif + +#define FStar_Buffer_eqb(b1, b2, n) \ + (memcmp((b1), (b2), (n) * sizeof((b1)[0])) == 0) + +/* Stubs to make ST happy. Important note: you must generate a use of the macro + * argument, otherwise, you may have FStar_ST_recall(f) as the only use of f; + * KreMLin will think that this is a valid use, but then the C compiler, after + * macro expansion, will error out. */ +#define FStar_HyperHeap_root 0 +#define FStar_Pervasives_Native_fst(x) (x).fst +#define FStar_Pervasives_Native_snd(x) (x).snd +#define FStar_Seq_Base_createEmpty(x) 0 +#define FStar_Seq_Base_create(len, init) 0 +#define FStar_Seq_Base_upd(s, i, e) 0 +#define FStar_Seq_Base_eq(l1, l2) 0 +#define FStar_Seq_Base_length(l1) 0 +#define FStar_Seq_Base_append(x, y) 0 +#define FStar_Seq_Base_slice(x, y, z) 0 +#define FStar_Seq_Properties_snoc(x, y) 0 +#define FStar_Seq_Properties_cons(x, y) 0 +#define FStar_Seq_Base_index(x, y) 0 +#define FStar_HyperStack_is_eternal_color(x) 0 +#define FStar_Monotonic_HyperHeap_root 0 +#define FStar_Buffer_to_seq_full(x) 0 +#define FStar_Buffer_recall(x) +#define FStar_HyperStack_ST_op_Colon_Equals(x, v) KRML_EXIT +#define FStar_HyperStack_ST_op_Bang(x) 0 +#define FStar_HyperStack_ST_salloc(x) 0 +#define FStar_HyperStack_ST_ralloc(x, y) 0 +#define FStar_HyperStack_ST_new_region(x) (0) +#define FStar_Monotonic_RRef_m_alloc(x) \ + { \ + 0 \ + } + +#define FStar_HyperStack_ST_recall(x) \ + do { \ + (void)(x); \ + } while (0) + +#define FStar_HyperStack_ST_recall_region(x) \ + do { \ + (void)(x); \ + } while (0) + +#define FStar_Monotonic_RRef_m_recall(x1, x2) \ + do { \ + (void)(x1); \ + (void)(x2); \ + } while (0) + +#define FStar_Monotonic_RRef_m_write(x1, x2, x3, x4, x5) \ + do { \ + (void)(x1); \ + (void)(x2); \ + (void)(x3); \ + (void)(x4); \ + (void)(x5); \ + } while (0) + +/******************************************************************************/ +/* Endian-ness macros that can only be implemented in C */ +/******************************************************************************/ + +/* ... for Linux */ +#if defined(__linux__) || defined(__CYGWIN__) +#include <endian.h> + +/* ... for OSX */ +#elif defined(__APPLE__) +#include <libkern/OSByteOrder.h> +#define htole64(x) OSSwapHostToLittleInt64(x) +#define le64toh(x) OSSwapLittleToHostInt64(x) +#define htobe64(x) OSSwapHostToBigInt64(x) +#define be64toh(x) OSSwapBigToHostInt64(x) + +#define htole16(x) OSSwapHostToLittleInt16(x) +#define le16toh(x) OSSwapLittleToHostInt16(x) +#define htobe16(x) OSSwapHostToBigInt16(x) +#define be16toh(x) OSSwapBigToHostInt16(x) + +#define htole32(x) OSSwapHostToLittleInt32(x) +#define le32toh(x) OSSwapLittleToHostInt32(x) +#define htobe32(x) OSSwapHostToBigInt32(x) +#define be32toh(x) OSSwapBigToHostInt32(x) + +/* ... for Solaris */ +#elif defined(__sun__) +#include <sys/byteorder.h> +#define htole64(x) LE_64(x) +#define le64toh(x) LE_64(x) +#define htobe64(x) BE_64(x) +#define be64toh(x) BE_64(x) + +#define htole16(x) LE_16(x) +#define le16toh(x) LE_16(x) +#define htobe16(x) BE_16(x) +#define be16toh(x) BE_16(x) + +#define htole32(x) LE_32(x) +#define le32toh(x) LE_32(x) +#define htobe32(x) BE_32(x) +#define be32toh(x) BE_32(x) + +/* ... for the BSDs */ +#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) +#include <sys/endian.h> +#elif defined(__OpenBSD__) +#include <endian.h> + +/* ... for Windows (MSVC)... not targeting XBOX 360! */ +#elif defined(_MSC_VER) + +#include <stdlib.h> +#define htobe16(x) _byteswap_ushort(x) +#define htole16(x) (x) +#define be16toh(x) _byteswap_ushort(x) +#define le16toh(x) (x) + +#define htobe32(x) _byteswap_ulong(x) +#define htole32(x) (x) +#define be32toh(x) _byteswap_ulong(x) +#define le32toh(x) (x) + +#define htobe64(x) _byteswap_uint64(x) +#define htole64(x) (x) +#define be64toh(x) _byteswap_uint64(x) +#define le64toh(x) (x) + +/* ... for Windows (GCC-like, e.g. mingw or clang) */ +#elif (defined(_WIN32) || defined(_WIN64)) && \ + (defined(__GNUC__) || defined(__clang__)) + +#define htobe16(x) __builtin_bswap16(x) +#define htole16(x) (x) +#define be16toh(x) __builtin_bswap16(x) +#define le16toh(x) (x) + +#define htobe32(x) __builtin_bswap32(x) +#define htole32(x) (x) +#define be32toh(x) __builtin_bswap32(x) +#define le32toh(x) (x) + +#define htobe64(x) __builtin_bswap64(x) +#define htole64(x) (x) +#define be64toh(x) __builtin_bswap64(x) +#define le64toh(x) (x) + +/* ... generic big-endian fallback code */ +#elif defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + +/* byte swapping code inspired by: + * https://github.com/rweather/arduinolibs/blob/master/libraries/Crypto/utility/EndianUtil.h + * */ + +#define htobe32(x) (x) +#define be32toh(x) (x) +#define htole32(x) \ + (__extension__({ \ + uint32_t _temp = (x); \ + ((_temp >> 24) & 0x000000FF) | ((_temp >> 8) & 0x0000FF00) | \ + ((_temp << 8) & 0x00FF0000) | ((_temp << 24) & 0xFF000000); \ + })) +#define le32toh(x) (htole32((x))) + +#define htobe64(x) (x) +#define be64toh(x) (x) +#define htole64(x) \ + (__extension__({ \ + uint64_t __temp = (x); \ + uint32_t __low = htobe32((uint32_t)__temp); \ + uint32_t __high = htobe32((uint32_t)(__temp >> 32)); \ + (((uint64_t)__low) << 32) | __high; \ + })) +#define le64toh(x) (htole64((x))) + +/* ... generic little-endian fallback code */ +#elif defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + +#define htole32(x) (x) +#define le32toh(x) (x) +#define htobe32(x) \ + (__extension__({ \ + uint32_t _temp = (x); \ + ((_temp >> 24) & 0x000000FF) | ((_temp >> 8) & 0x0000FF00) | \ + ((_temp << 8) & 0x00FF0000) | ((_temp << 24) & 0xFF000000); \ + })) +#define be32toh(x) (htobe32((x))) + +#define htole64(x) (x) +#define le64toh(x) (x) +#define htobe64(x) \ + (__extension__({ \ + uint64_t __temp = (x); \ + uint32_t __low = htobe32((uint32_t)__temp); \ + uint32_t __high = htobe32((uint32_t)(__temp >> 32)); \ + (((uint64_t)__low) << 32) | __high; \ + })) +#define be64toh(x) (htobe64((x))) + +/* ... couldn't determine endian-ness of the target platform */ +#else +#error "Please define __BYTE_ORDER__!" + +#endif /* defined(__linux__) || ... */ + +/* Loads and stores. These avoid undefined behavior due to unaligned memory + * accesses, via memcpy. */ + +inline static uint16_t +load16(uint8_t *b) +{ + uint16_t x; + memcpy(&x, b, 2); + return x; +} + +inline static uint32_t +load32(uint8_t *b) +{ + uint32_t x; + memcpy(&x, b, 4); + return x; +} + +inline static uint64_t +load64(uint8_t *b) +{ + uint64_t x; + memcpy(&x, b, 8); + return x; +} + +inline static void +store16(uint8_t *b, uint16_t i) +{ + memcpy(b, &i, 2); +} + +inline static void +store32(uint8_t *b, uint32_t i) +{ + memcpy(b, &i, 4); +} + +inline static void +store64(uint8_t *b, uint64_t i) +{ + memcpy(b, &i, 8); +} + +#define load16_le(b) (le16toh(load16(b))) +#define store16_le(b, i) (store16(b, htole16(i))) +#define load16_be(b) (be16toh(load16(b))) +#define store16_be(b, i) (store16(b, htobe16(i))) + +#define load32_le(b) (le32toh(load32(b))) +#define store32_le(b, i) (store32(b, htole32(i))) +#define load32_be(b) (be32toh(load32(b))) +#define store32_be(b, i) (store32(b, htobe32(i))) + +#define load64_le(b) (le64toh(load64(b))) +#define store64_le(b, i) (store64(b, htole64(i))) +#define load64_be(b) (be64toh(load64(b))) +#define store64_be(b, i) (store64(b, htobe64(i))) + +/******************************************************************************/ +/* Checked integers to ease the compilation of non-Low* code */ +/******************************************************************************/ + +typedef int32_t Prims_pos, Prims_nat, Prims_nonzero, Prims_int, + krml_checked_int_t; + +inline static bool +Prims_op_GreaterThanOrEqual(int32_t x, int32_t y) +{ + return x >= y; +} + +inline static bool +Prims_op_LessThanOrEqual(int32_t x, int32_t y) +{ + return x <= y; +} + +inline static bool +Prims_op_GreaterThan(int32_t x, int32_t y) +{ + return x > y; +} + +inline static bool +Prims_op_LessThan(int32_t x, int32_t y) +{ + return x < y; +} + +#define RETURN_OR(x) \ + do { \ + int64_t __ret = x; \ + if (__ret < INT32_MIN || INT32_MAX < __ret) { \ + KRML_HOST_PRINTF("Prims.{int,nat,pos} integer overflow at %s:%d\n", \ + __FILE__, __LINE__); \ + KRML_HOST_EXIT(252); \ + } \ + return (int32_t)__ret; \ + } while (0) + +inline static int32_t +Prims_pow2(int32_t x) +{ + RETURN_OR((int64_t)1 << (int64_t)x); +} + +inline static int32_t +Prims_op_Multiply(int32_t x, int32_t y) +{ + RETURN_OR((int64_t)x * (int64_t)y); +} + +inline static int32_t +Prims_op_Addition(int32_t x, int32_t y) +{ + RETURN_OR((int64_t)x + (int64_t)y); +} + +inline static int32_t +Prims_op_Subtraction(int32_t x, int32_t y) +{ + RETURN_OR((int64_t)x - (int64_t)y); +} + +inline static int32_t +Prims_op_Division(int32_t x, int32_t y) +{ + RETURN_OR((int64_t)x / (int64_t)y); +} + +inline static int32_t +Prims_op_Modulus(int32_t x, int32_t y) +{ + RETURN_OR((int64_t)x % (int64_t)y); +} + +inline static int8_t +FStar_UInt8_uint_to_t(int8_t x) +{ + return x; +} +inline static int16_t +FStar_UInt16_uint_to_t(int16_t x) +{ + return x; +} +inline static int32_t +FStar_UInt32_uint_to_t(int32_t x) +{ + return x; +} +inline static int64_t +FStar_UInt64_uint_to_t(int64_t x) +{ + return x; +} + +inline static int8_t +FStar_UInt8_v(int8_t x) +{ + return x; +} +inline static int16_t +FStar_UInt16_v(int16_t x) +{ + return x; +} +inline static int32_t +FStar_UInt32_v(int32_t x) +{ + return x; +} +inline static int64_t +FStar_UInt64_v(int64_t x) +{ + return x; +} + +/* Platform-specific 128-bit arithmetic. These are static functions in a header, + * so that each translation unit gets its own copy and the C compiler can + * optimize. */ +#ifndef KRML_NOUINT128 +typedef unsigned __int128 FStar_UInt128_t, FStar_UInt128_t_, uint128_t; + +static inline void +print128(const char *where, uint128_t n) +{ + KRML_HOST_PRINTF("%s: [%" PRIu64 ",%" PRIu64 "]\n", where, + (uint64_t)(n >> 64), (uint64_t)n); +} + +static inline uint128_t +load128_le(uint8_t *b) +{ + uint128_t l = (uint128_t)load64_le(b); + uint128_t h = (uint128_t)load64_le(b + 8); + return (h << 64 | l); +} + +static inline void +store128_le(uint8_t *b, uint128_t n) +{ + store64_le(b, (uint64_t)n); + store64_le(b + 8, (uint64_t)(n >> 64)); +} + +static inline uint128_t +load128_be(uint8_t *b) +{ + uint128_t h = (uint128_t)load64_be(b); + uint128_t l = (uint128_t)load64_be(b + 8); + return (h << 64 | l); +} + +static inline void +store128_be(uint8_t *b, uint128_t n) +{ + store64_be(b, (uint64_t)(n >> 64)); + store64_be(b + 8, (uint64_t)n); +} + +#define FStar_UInt128_add(x, y) ((x) + (y)) +#define FStar_UInt128_mul(x, y) ((x) * (y)) +#define FStar_UInt128_add_mod(x, y) ((x) + (y)) +#define FStar_UInt128_sub(x, y) ((x) - (y)) +#define FStar_UInt128_sub_mod(x, y) ((x) - (y)) +#define FStar_UInt128_logand(x, y) ((x) & (y)) +#define FStar_UInt128_logor(x, y) ((x) | (y)) +#define FStar_UInt128_logxor(x, y) ((x) ^ (y)) +#define FStar_UInt128_lognot(x) (~(x)) +#define FStar_UInt128_shift_left(x, y) ((x) << (y)) +#define FStar_UInt128_shift_right(x, y) ((x) >> (y)) +#define FStar_UInt128_uint64_to_uint128(x) ((uint128_t)(x)) +#define FStar_UInt128_uint128_to_uint64(x) ((uint64_t)(x)) +#define FStar_UInt128_mul_wide(x, y) ((uint128_t)(x) * (y)) +#define FStar_UInt128_op_Hat_Hat(x, y) ((x) ^ (y)) + +static inline uint128_t +FStar_UInt128_eq_mask(uint128_t x, uint128_t y) +{ + uint64_t mask = + FStar_UInt64_eq_mask((uint64_t)(x >> 64), (uint64_t)(y >> 64)) & + FStar_UInt64_eq_mask(x, y); + return ((uint128_t)mask) << 64 | mask; +} + +static inline uint128_t +FStar_UInt128_gte_mask(uint128_t x, uint128_t y) +{ + uint64_t mask = + (FStar_UInt64_gte_mask(x >> 64, y >> 64) & + ~(FStar_UInt64_eq_mask(x >> 64, y >> 64))) | + (FStar_UInt64_eq_mask(x >> 64, y >> 64) & FStar_UInt64_gte_mask(x, y)); + return ((uint128_t)mask) << 64 | mask; +} + +#else /* !defined(KRML_NOUINT128) */ + +/* This is a bad circular dependency... should fix it properly. */ +#include "FStar.h" + +typedef FStar_UInt128_uint128 FStar_UInt128_t_, uint128_t; + +/* A series of definitions written using pointers. */ +static inline void +print128_(const char *where, uint128_t *n) +{ + KRML_HOST_PRINTF("%s: [0x%08" PRIx64 ",0x%08" PRIx64 "]\n", where, n->high, n->low); +} + +static inline void +load128_le_(uint8_t *b, uint128_t *r) +{ + r->low = load64_le(b); + r->high = load64_le(b + 8); +} + +static inline void +store128_le_(uint8_t *b, uint128_t *n) +{ + store64_le(b, n->low); + store64_le(b + 8, n->high); +} + +static inline void +load128_be_(uint8_t *b, uint128_t *r) +{ + r->high = load64_be(b); + r->low = load64_be(b + 8); +} + +static inline void +store128_be_(uint8_t *b, uint128_t *n) +{ + store64_be(b, n->high); + store64_be(b + 8, n->low); +} + +#ifndef KRML_NOSTRUCT_PASSING + +static inline void +print128(const char *where, uint128_t n) +{ + print128_(where, &n); +} + +static inline uint128_t +load128_le(uint8_t *b) +{ + uint128_t r; + load128_le_(b, &r); + return r; +} + +static inline void +store128_le(uint8_t *b, uint128_t n) +{ + store128_le_(b, &n); +} + +static inline uint128_t +load128_be(uint8_t *b) +{ + uint128_t r; + load128_be_(b, &r); + return r; +} + +static inline void +store128_be(uint8_t *b, uint128_t n) +{ + store128_be_(b, &n); +} + +#else /* !defined(KRML_STRUCT_PASSING) */ + +#define print128 print128_ +#define load128_le load128_le_ +#define store128_le store128_le_ +#define load128_be load128_be_ +#define store128_be store128_be_ + +#endif /* KRML_STRUCT_PASSING */ +#endif /* KRML_UINT128 */ +#endif /* __KREMLIB_H */ diff --git a/security/nss/lib/freebl/verified/kremlib_base.h b/security/nss/lib/freebl/verified/kremlib_base.h new file mode 100644 index 000000000..14170625d --- /dev/null +++ b/security/nss/lib/freebl/verified/kremlib_base.h @@ -0,0 +1,192 @@ +/* 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. + */ + +#ifndef __KREMLIB_BASE_H +#define __KREMLIB_BASE_H + +#include <inttypes.h> +#include <limits.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> + +/******************************************************************************/ +/* Some macros to ease compatibility */ +/******************************************************************************/ + +/* Define __cdecl and friends when using GCC, so that we can safely compile code + * that contains __cdecl on all platforms. Note that this is in a separate + * header so that Dafny-generated code can include just this file. */ +#ifndef _MSC_VER +/* Use the gcc predefined macros if on a platform/architectures that set them. + * Otherwise define them to be empty. */ +#ifndef __cdecl +#define __cdecl +#endif +#ifndef __stdcall +#define __stdcall +#endif +#ifndef __fastcall +#define __fastcall +#endif +#endif + +#ifdef __GNUC__ +#define inline __inline__ +#endif + +/* GCC-specific attribute syntax; everyone else gets the standard C inline + * attribute. */ +#ifdef __GNU_C__ +#ifndef __clang__ +#define force_inline inline __attribute__((always_inline)) +#else +#define force_inline inline +#endif +#else +#define force_inline inline +#endif + +/******************************************************************************/ +/* Implementing C.fst */ +/******************************************************************************/ + +/* Uppercase issue; we have to define lowercase versions of the C macros (as we + * have no way to refer to an uppercase *variable* in F*). */ +extern int exit_success; +extern int exit_failure; + +/* This one allows the user to write C.EXIT_SUCCESS. */ +typedef int exit_code; + +void print_string(const char *s); +void print_bytes(uint8_t *b, uint32_t len); + +/* The universal null pointer defined in C.Nullity.fst */ +#define C_Nullity_null(X) 0 + +/* If some globals need to be initialized before the main, then kremlin will + * generate and try to link last a function with this type: */ +void kremlinit_globals(void); + +/******************************************************************************/ +/* Implementation of machine integers (possibly of 128-bit integers) */ +/******************************************************************************/ + +/* Integer types */ +typedef uint64_t FStar_UInt64_t, FStar_UInt64_t_; +typedef int64_t FStar_Int64_t, FStar_Int64_t_; +typedef uint32_t FStar_UInt32_t, FStar_UInt32_t_; +typedef int32_t FStar_Int32_t, FStar_Int32_t_; +typedef uint16_t FStar_UInt16_t, FStar_UInt16_t_; +typedef int16_t FStar_Int16_t, FStar_Int16_t_; +typedef uint8_t FStar_UInt8_t, FStar_UInt8_t_; +typedef int8_t FStar_Int8_t, FStar_Int8_t_; + +static inline uint32_t +rotate32_left(uint32_t x, uint32_t n) +{ + /* assert (n<32); */ + return (x << n) | (x >> (32 - n)); +} +static inline uint32_t +rotate32_right(uint32_t x, uint32_t n) +{ + /* assert (n<32); */ + return (x >> n) | (x << (32 - n)); +} + +/* Constant time comparisons */ +static inline uint8_t +FStar_UInt8_eq_mask(uint8_t x, uint8_t y) +{ + x = ~(x ^ y); + x &= x << 4; + x &= x << 2; + x &= x << 1; + return (int8_t)x >> 7; +} + +static inline uint8_t +FStar_UInt8_gte_mask(uint8_t x, uint8_t y) +{ + return ~(uint8_t)(((int32_t)x - y) >> 31); +} + +static inline uint16_t +FStar_UInt16_eq_mask(uint16_t x, uint16_t y) +{ + x = ~(x ^ y); + x &= x << 8; + x &= x << 4; + x &= x << 2; + x &= x << 1; + return (int16_t)x >> 15; +} + +static inline uint16_t +FStar_UInt16_gte_mask(uint16_t x, uint16_t y) +{ + return ~(uint16_t)(((int32_t)x - y) >> 31); +} + +static inline uint32_t +FStar_UInt32_eq_mask(uint32_t x, uint32_t y) +{ + x = ~(x ^ y); + x &= x << 16; + x &= x << 8; + x &= x << 4; + x &= x << 2; + x &= x << 1; + return ((int32_t)x) >> 31; +} + +static inline uint32_t +FStar_UInt32_gte_mask(uint32_t x, uint32_t y) +{ + return ~((uint32_t)(((int64_t)x - y) >> 63)); +} + +static inline uint64_t +FStar_UInt64_eq_mask(uint64_t x, uint64_t y) +{ + x = ~(x ^ y); + x &= x << 32; + x &= x << 16; + x &= x << 8; + x &= x << 4; + x &= x << 2; + x &= x << 1; + return ((int64_t)x) >> 63; +} + +static inline uint64_t +FStar_UInt64_gte_mask(uint64_t x, uint64_t y) +{ + uint64_t low63 = + ~((uint64_t)((int64_t)((int64_t)(x & UINT64_C(0x7fffffffffffffff)) - + (int64_t)(y & UINT64_C(0x7fffffffffffffff))) >> + 63)); + uint64_t high_bit = + ~((uint64_t)((int64_t)((int64_t)(x & UINT64_C(0x8000000000000000)) - + (int64_t)(y & UINT64_C(0x8000000000000000))) >> + 63)); + return low63 & high_bit; +} + +#endif diff --git a/security/nss/lib/freebl/verified/specs/Spec.CTR.fst b/security/nss/lib/freebl/verified/specs/Spec.CTR.fst new file mode 100644 index 000000000..e411cd353 --- /dev/null +++ b/security/nss/lib/freebl/verified/specs/Spec.CTR.fst @@ -0,0 +1,98 @@ +/* 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. + */ + +module Spec.CTR + +module ST = FStar.HyperStack.ST + +open FStar.Mul +open FStar.Seq +open Spec.Lib + +#reset-options "--initial_fuel 0 --max_fuel 0 --initial_ifuel 0 --max_ifuel 0" + +type block_cipher_ctx = { + keylen: nat ; + blocklen: (x:nat{x>0}); + noncelen: nat; + counterbits: nat; + incr: pos} + +type key (c:block_cipher_ctx) = lbytes c.keylen +type nonce (c:block_cipher_ctx) = lbytes c.noncelen +type block (c:block_cipher_ctx) = lbytes (c.blocklen*c.incr) +type counter (c:block_cipher_ctx) = UInt.uint_t c.counterbits +type block_cipher (c:block_cipher_ctx) = key c -> nonce c -> counter c -> block c + +val xor: #len:nat -> x:lbytes len -> y:lbytes len -> Tot (lbytes len) +let xor #len x y = map2 FStar.UInt8.(fun x y -> x ^^ y) x y + + +val counter_mode_blocks: + ctx: block_cipher_ctx -> + bc: block_cipher ctx -> + k:key ctx -> n:nonce ctx -> c:counter ctx -> + plain:seq UInt8.t{c + ctx.incr * (length plain / ctx.blocklen) < pow2 ctx.counterbits /\ + length plain % (ctx.blocklen * ctx.incr) = 0} -> + Tot (lbytes (length plain)) + (decreases (length plain)) +#reset-options "--z3rlimit 200 --max_fuel 0" +let rec counter_mode_blocks ctx block_enc key nonce counter plain = + let len = length plain in + let len' = len / (ctx.blocklen * ctx.incr) in + Math.Lemmas.lemma_div_mod len (ctx.blocklen * ctx.incr) ; + if len = 0 then Seq.createEmpty #UInt8.t + else ( + let prefix, block = split plain (len - ctx.blocklen * ctx.incr) in + (* TODO: move to a single lemma for clarify *) + Math.Lemmas.lemma_mod_plus (length prefix) 1 (ctx.blocklen * ctx.incr); + Math.Lemmas.lemma_div_le (length prefix) len ctx.blocklen; + Spec.CTR.Lemmas.lemma_div len (ctx.blocklen * ctx.incr); + (* End TODO *) + let cipher = counter_mode_blocks ctx block_enc key nonce counter prefix in + let mask = block_enc key nonce (counter + (len / ctx.blocklen - 1) * ctx.incr) in + let eb = xor block mask in + cipher @| eb + ) + + +val counter_mode: + ctx: block_cipher_ctx -> + bc: block_cipher ctx -> + k:key ctx -> n:nonce ctx -> c:counter ctx -> + plain:seq UInt8.t{c + ctx.incr * (length plain / ctx.blocklen) < pow2 ctx.counterbits} -> + Tot (lbytes (length plain)) + (decreases (length plain)) +#reset-options "--z3rlimit 200 --max_fuel 0" +let counter_mode ctx block_enc key nonce counter plain = + let len = length plain in + let blocks_len = (ctx.incr * ctx.blocklen) * (len / (ctx.blocklen * ctx.incr)) in + let part_len = len % (ctx.blocklen * ctx.incr) in + (* TODO: move to a single lemma for clarify *) + Math.Lemmas.lemma_div_mod len (ctx.blocklen * ctx.incr); + Math.Lemmas.multiple_modulo_lemma (len / (ctx.blocklen * ctx.incr)) (ctx.blocklen * ctx.incr); + Math.Lemmas.lemma_div_le (blocks_len) len ctx.blocklen; + (* End TODO *) + let blocks, last_block = split plain blocks_len in + let cipher_blocks = counter_mode_blocks ctx block_enc key nonce counter blocks in + let cipher_last_block = + if part_len > 0 + then (* encrypt final partial block(s) *) + let mask = block_enc key nonce (counter+ctx.incr*(length plain / ctx.blocklen)) in + let mask = slice mask 0 part_len in + assert(length last_block = part_len); + xor #part_len last_block mask + else createEmpty in + cipher_blocks @| cipher_last_block diff --git a/security/nss/lib/freebl/verified/specs/Spec.Chacha20.fst b/security/nss/lib/freebl/verified/specs/Spec.Chacha20.fst new file mode 100644 index 000000000..0bdc69725 --- /dev/null +++ b/security/nss/lib/freebl/verified/specs/Spec.Chacha20.fst @@ -0,0 +1,169 @@ +/* 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. + */ + +module Spec.Chacha20 + +module ST = FStar.HyperStack.ST + +open FStar.Mul +open FStar.Seq +open FStar.UInt32 +open FStar.Endianness +open Spec.Lib +open Spec.Chacha20.Lemmas +open Seq.Create + +#set-options "--max_fuel 0 --z3rlimit 100" + +(* Constants *) +let keylen = 32 (* in bytes *) +let blocklen = 64 (* in bytes *) +let noncelen = 12 (* in bytes *) + +type key = lbytes keylen +type block = lbytes blocklen +type nonce = lbytes noncelen +type counter = UInt.uint_t 32 + +// using @ as a functional substitute for ; +// internally, blocks are represented as 16 x 4-byte integers +type state = m:seq UInt32.t {length m = 16} +type idx = n:nat{n < 16} +type shuffle = state -> Tot state + +let line (a:idx) (b:idx) (d:idx) (s:t{0 < v s /\ v s < 32}) (m:state) : Tot state = + let m = m.[a] <- (m.[a] +%^ m.[b]) in + let m = m.[d] <- ((m.[d] ^^ m.[a]) <<< s) in m + +let quarter_round a b c d : shuffle = + line a b d 16ul @ + line c d b 12ul @ + line a b d 8ul @ + line c d b 7ul + +let column_round : shuffle = + quarter_round 0 4 8 12 @ + quarter_round 1 5 9 13 @ + quarter_round 2 6 10 14 @ + quarter_round 3 7 11 15 + +let diagonal_round : shuffle = + quarter_round 0 5 10 15 @ + quarter_round 1 6 11 12 @ + quarter_round 2 7 8 13 @ + quarter_round 3 4 9 14 + +let double_round: shuffle = + column_round @ diagonal_round (* 2 rounds *) + +let rounds : shuffle = + iter 10 double_round (* 20 rounds *) + +let chacha20_core (s:state) : Tot state = + let s' = rounds s in + Spec.Loops.seq_map2 (fun x y -> x +%^ y) s' s + +(* state initialization *) +let c0 = 0x61707865ul +let c1 = 0x3320646eul +let c2 = 0x79622d32ul +let c3 = 0x6b206574ul + +let setup (k:key) (n:nonce) (c:counter): Tot state = + create_4 c0 c1 c2 c3 @| + uint32s_from_le 8 k @| + create_1 (UInt32.uint_to_t c) @| + uint32s_from_le 3 n + +let chacha20_block (k:key) (n:nonce) (c:counter): Tot block = + let st = setup k n c in + let st' = chacha20_core st in + uint32s_to_le 16 st' + +let chacha20_ctx: Spec.CTR.block_cipher_ctx = + let open Spec.CTR in + { + keylen = keylen; + blocklen = blocklen; + noncelen = noncelen; + counterbits = 32; + incr = 1 + } + +let chacha20_cipher: Spec.CTR.block_cipher chacha20_ctx = chacha20_block + +let chacha20_encrypt_bytes key nonce counter m = + Spec.CTR.counter_mode chacha20_ctx chacha20_cipher key nonce counter m + + +unfold let test_plaintext = [ + 0x4cuy; 0x61uy; 0x64uy; 0x69uy; 0x65uy; 0x73uy; 0x20uy; 0x61uy; + 0x6euy; 0x64uy; 0x20uy; 0x47uy; 0x65uy; 0x6euy; 0x74uy; 0x6cuy; + 0x65uy; 0x6duy; 0x65uy; 0x6euy; 0x20uy; 0x6fuy; 0x66uy; 0x20uy; + 0x74uy; 0x68uy; 0x65uy; 0x20uy; 0x63uy; 0x6cuy; 0x61uy; 0x73uy; + 0x73uy; 0x20uy; 0x6fuy; 0x66uy; 0x20uy; 0x27uy; 0x39uy; 0x39uy; + 0x3auy; 0x20uy; 0x49uy; 0x66uy; 0x20uy; 0x49uy; 0x20uy; 0x63uy; + 0x6fuy; 0x75uy; 0x6cuy; 0x64uy; 0x20uy; 0x6fuy; 0x66uy; 0x66uy; + 0x65uy; 0x72uy; 0x20uy; 0x79uy; 0x6fuy; 0x75uy; 0x20uy; 0x6fuy; + 0x6euy; 0x6cuy; 0x79uy; 0x20uy; 0x6fuy; 0x6euy; 0x65uy; 0x20uy; + 0x74uy; 0x69uy; 0x70uy; 0x20uy; 0x66uy; 0x6fuy; 0x72uy; 0x20uy; + 0x74uy; 0x68uy; 0x65uy; 0x20uy; 0x66uy; 0x75uy; 0x74uy; 0x75uy; + 0x72uy; 0x65uy; 0x2cuy; 0x20uy; 0x73uy; 0x75uy; 0x6euy; 0x73uy; + 0x63uy; 0x72uy; 0x65uy; 0x65uy; 0x6euy; 0x20uy; 0x77uy; 0x6fuy; + 0x75uy; 0x6cuy; 0x64uy; 0x20uy; 0x62uy; 0x65uy; 0x20uy; 0x69uy; + 0x74uy; 0x2euy +] + +unfold let test_ciphertext = [ + 0x6euy; 0x2euy; 0x35uy; 0x9auy; 0x25uy; 0x68uy; 0xf9uy; 0x80uy; + 0x41uy; 0xbauy; 0x07uy; 0x28uy; 0xdduy; 0x0duy; 0x69uy; 0x81uy; + 0xe9uy; 0x7euy; 0x7auy; 0xecuy; 0x1duy; 0x43uy; 0x60uy; 0xc2uy; + 0x0auy; 0x27uy; 0xafuy; 0xccuy; 0xfduy; 0x9fuy; 0xaeuy; 0x0buy; + 0xf9uy; 0x1buy; 0x65uy; 0xc5uy; 0x52uy; 0x47uy; 0x33uy; 0xabuy; + 0x8fuy; 0x59uy; 0x3duy; 0xabuy; 0xcduy; 0x62uy; 0xb3uy; 0x57uy; + 0x16uy; 0x39uy; 0xd6uy; 0x24uy; 0xe6uy; 0x51uy; 0x52uy; 0xabuy; + 0x8fuy; 0x53uy; 0x0cuy; 0x35uy; 0x9fuy; 0x08uy; 0x61uy; 0xd8uy; + 0x07uy; 0xcauy; 0x0duy; 0xbfuy; 0x50uy; 0x0duy; 0x6auy; 0x61uy; + 0x56uy; 0xa3uy; 0x8euy; 0x08uy; 0x8auy; 0x22uy; 0xb6uy; 0x5euy; + 0x52uy; 0xbcuy; 0x51uy; 0x4duy; 0x16uy; 0xccuy; 0xf8uy; 0x06uy; + 0x81uy; 0x8cuy; 0xe9uy; 0x1auy; 0xb7uy; 0x79uy; 0x37uy; 0x36uy; + 0x5auy; 0xf9uy; 0x0buy; 0xbfuy; 0x74uy; 0xa3uy; 0x5buy; 0xe6uy; + 0xb4uy; 0x0buy; 0x8euy; 0xeduy; 0xf2uy; 0x78uy; 0x5euy; 0x42uy; + 0x87uy; 0x4duy +] + +unfold let test_key = [ + 0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; + 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; + 16uy; 17uy; 18uy; 19uy; 20uy; 21uy; 22uy; 23uy; + 24uy; 25uy; 26uy; 27uy; 28uy; 29uy; 30uy; 31uy + ] +unfold let test_nonce = [ + 0uy; 0uy; 0uy; 0uy; 0uy; 0uy; 0uy; 0x4auy; 0uy; 0uy; 0uy; 0uy + ] + +unfold let test_counter = 1 + +let test() = + assert_norm(List.Tot.length test_plaintext = 114); + assert_norm(List.Tot.length test_ciphertext = 114); + assert_norm(List.Tot.length test_key = 32); + assert_norm(List.Tot.length test_nonce = 12); + let test_plaintext = createL test_plaintext in + let test_ciphertext = createL test_ciphertext in + let test_key = createL test_key in + let test_nonce = createL test_nonce in + chacha20_encrypt_bytes test_key test_nonce test_counter test_plaintext + = test_ciphertext diff --git a/security/nss/lib/freebl/verified/specs/Spec.Curve25519.fst b/security/nss/lib/freebl/verified/specs/Spec.Curve25519.fst new file mode 100644 index 000000000..af4035b09 --- /dev/null +++ b/security/nss/lib/freebl/verified/specs/Spec.Curve25519.fst @@ -0,0 +1,168 @@ +/* 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. + */ + +module Spec.Curve25519 + +module ST = FStar.HyperStack.ST + +open FStar.Mul +open FStar.Seq +open FStar.UInt8 +open FStar.Endianness +open Spec.Lib +open Spec.Curve25519.Lemmas + +#reset-options "--initial_fuel 0 --max_fuel 0 --z3rlimit 20" + +(* Field types and parameters *) +let prime = pow2 255 - 19 +type elem : Type0 = e:int{e >= 0 /\ e < prime} +let fadd e1 e2 = (e1 + e2) % prime +let fsub e1 e2 = (e1 - e2) % prime +let fmul e1 e2 = (e1 * e2) % prime +let zero : elem = 0 +let one : elem = 1 +let ( +@ ) = fadd +let ( *@ ) = fmul + +(** Exponentiation *) +let rec ( ** ) (e:elem) (n:pos) : Tot elem (decreases n) = + if n = 1 then e + else + if n % 2 = 0 then op_Star_Star (e `fmul` e) (n / 2) + else e `fmul` (op_Star_Star (e `fmul` e) ((n-1)/2)) + +(* Type aliases *) +type scalar = lbytes 32 +type serialized_point = lbytes 32 +type proj_point = | Proj: x:elem -> z:elem -> proj_point + +let decodeScalar25519 (k:scalar) = + let k = k.[0] <- (k.[0] &^ 248uy) in + let k = k.[31] <- ((k.[31] &^ 127uy) |^ 64uy) in k + +let decodePoint (u:serialized_point) = + (little_endian u % pow2 255) % prime + +let add_and_double qx nq nqp1 = + let x_1 = qx in + let x_2, z_2 = nq.x, nq.z in + let x_3, z_3 = nqp1.x, nqp1.z in + let a = x_2 `fadd` z_2 in + let aa = a**2 in + let b = x_2 `fsub` z_2 in + let bb = b**2 in + let e = aa `fsub` bb in + let c = x_3 `fadd` z_3 in + let d = x_3 `fsub` z_3 in + let da = d `fmul` a in + let cb = c `fmul` b in + let x_3 = (da `fadd` cb)**2 in + let z_3 = x_1 `fmul` ((da `fsub` cb)**2) in + let x_2 = aa `fmul` bb in + let z_2 = e `fmul` (aa `fadd` (121665 `fmul` e)) in + Proj x_2 z_2, Proj x_3 z_3 + +let ith_bit (k:scalar) (i:nat{i < 256}) = + let q = i / 8 in let r = i % 8 in + (v (k.[q]) / pow2 r) % 2 + +let rec montgomery_ladder_ (init:elem) x xp1 (k:scalar) (ctr:nat{ctr<=256}) + : Tot proj_point (decreases ctr) = + if ctr = 0 then x + else ( + let ctr' = ctr - 1 in + let (x', xp1') = + if ith_bit k ctr' = 1 then ( + let nqp2, nqp1 = add_and_double init xp1 x in + nqp1, nqp2 + ) else add_and_double init x xp1 in + montgomery_ladder_ init x' xp1' k ctr' + ) + +let montgomery_ladder (init:elem) (k:scalar) : Tot proj_point = + montgomery_ladder_ init (Proj one zero) (Proj init one) k 256 + +let encodePoint (p:proj_point) : Tot serialized_point = + let p = p.x `fmul` (p.z ** (prime - 2)) in + little_bytes 32ul p + +let scalarmult (k:scalar) (u:serialized_point) : Tot serialized_point = + let k = decodeScalar25519 k in + let u = decodePoint u in + let res = montgomery_ladder u k in + encodePoint res + + +(* ********************* *) +(* RFC 7748 Test Vectors *) +(* ********************* *) + +let scalar1 = [ + 0xa5uy; 0x46uy; 0xe3uy; 0x6buy; 0xf0uy; 0x52uy; 0x7cuy; 0x9duy; + 0x3buy; 0x16uy; 0x15uy; 0x4buy; 0x82uy; 0x46uy; 0x5euy; 0xdduy; + 0x62uy; 0x14uy; 0x4cuy; 0x0auy; 0xc1uy; 0xfcuy; 0x5auy; 0x18uy; + 0x50uy; 0x6auy; 0x22uy; 0x44uy; 0xbauy; 0x44uy; 0x9auy; 0xc4uy +] + +let scalar2 = [ + 0x4buy; 0x66uy; 0xe9uy; 0xd4uy; 0xd1uy; 0xb4uy; 0x67uy; 0x3cuy; + 0x5auy; 0xd2uy; 0x26uy; 0x91uy; 0x95uy; 0x7duy; 0x6auy; 0xf5uy; + 0xc1uy; 0x1buy; 0x64uy; 0x21uy; 0xe0uy; 0xeauy; 0x01uy; 0xd4uy; + 0x2cuy; 0xa4uy; 0x16uy; 0x9euy; 0x79uy; 0x18uy; 0xbauy; 0x0duy +] + +let input1 = [ + 0xe6uy; 0xdbuy; 0x68uy; 0x67uy; 0x58uy; 0x30uy; 0x30uy; 0xdbuy; + 0x35uy; 0x94uy; 0xc1uy; 0xa4uy; 0x24uy; 0xb1uy; 0x5fuy; 0x7cuy; + 0x72uy; 0x66uy; 0x24uy; 0xecuy; 0x26uy; 0xb3uy; 0x35uy; 0x3buy; + 0x10uy; 0xa9uy; 0x03uy; 0xa6uy; 0xd0uy; 0xabuy; 0x1cuy; 0x4cuy +] + +let input2 = [ + 0xe5uy; 0x21uy; 0x0fuy; 0x12uy; 0x78uy; 0x68uy; 0x11uy; 0xd3uy; + 0xf4uy; 0xb7uy; 0x95uy; 0x9duy; 0x05uy; 0x38uy; 0xaeuy; 0x2cuy; + 0x31uy; 0xdbuy; 0xe7uy; 0x10uy; 0x6fuy; 0xc0uy; 0x3cuy; 0x3euy; + 0xfcuy; 0x4cuy; 0xd5uy; 0x49uy; 0xc7uy; 0x15uy; 0xa4uy; 0x93uy +] + +let expected1 = [ + 0xc3uy; 0xdauy; 0x55uy; 0x37uy; 0x9duy; 0xe9uy; 0xc6uy; 0x90uy; + 0x8euy; 0x94uy; 0xeauy; 0x4duy; 0xf2uy; 0x8duy; 0x08uy; 0x4fuy; + 0x32uy; 0xecuy; 0xcfuy; 0x03uy; 0x49uy; 0x1cuy; 0x71uy; 0xf7uy; + 0x54uy; 0xb4uy; 0x07uy; 0x55uy; 0x77uy; 0xa2uy; 0x85uy; 0x52uy +] +let expected2 = [ + 0x95uy; 0xcbuy; 0xdeuy; 0x94uy; 0x76uy; 0xe8uy; 0x90uy; 0x7duy; + 0x7auy; 0xaduy; 0xe4uy; 0x5cuy; 0xb4uy; 0xb8uy; 0x73uy; 0xf8uy; + 0x8buy; 0x59uy; 0x5auy; 0x68uy; 0x79uy; 0x9fuy; 0xa1uy; 0x52uy; + 0xe6uy; 0xf8uy; 0xf7uy; 0x64uy; 0x7auy; 0xacuy; 0x79uy; 0x57uy +] + +let test () = + assert_norm(List.Tot.length scalar1 = 32); + assert_norm(List.Tot.length scalar2 = 32); + assert_norm(List.Tot.length input1 = 32); + assert_norm(List.Tot.length input2 = 32); + assert_norm(List.Tot.length expected1 = 32); + assert_norm(List.Tot.length expected2 = 32); + let scalar1 = createL scalar1 in + let scalar2 = createL scalar2 in + let input1 = createL input1 in + let input2 = createL input2 in + let expected1 = createL expected1 in + let expected2 = createL expected2 in + scalarmult scalar1 input1 = expected1 + && scalarmult scalar2 input2 = expected2 diff --git a/security/nss/lib/freebl/verified/specs/Spec.Poly1305.fst b/security/nss/lib/freebl/verified/specs/Spec.Poly1305.fst new file mode 100644 index 000000000..f9d8a4cb2 --- /dev/null +++ b/security/nss/lib/freebl/verified/specs/Spec.Poly1305.fst @@ -0,0 +1,107 @@ +/* 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. + */ + +module Spec.Poly1305 + +module ST = FStar.HyperStack.ST + +open FStar.Math.Lib +open FStar.Mul +open FStar.Seq +open FStar.UInt8 +open FStar.Endianness +open Spec.Poly1305.Lemmas + +#set-options "--initial_fuel 0 --max_fuel 0 --initial_ifuel 0 --max_ifuel 0" + +(* Field types and parameters *) +let prime = pow2 130 - 5 +type elem = e:int{e >= 0 /\ e < prime} +let fadd (e1:elem) (e2:elem) = (e1 + e2) % prime +let fmul (e1:elem) (e2:elem) = (e1 * e2) % prime +let zero : elem = 0 +let one : elem = 1 +let op_Plus_At = fadd +let op_Star_At = fmul +(* Type aliases *) +let op_Amp_Bar = UInt.logand #128 +type word = w:bytes{length w <= 16} +type word_16 = w:bytes{length w = 16} +type tag = word_16 +type key = lbytes 32 +type text = seq word + +(* Specification code *) +let encode (w:word) = + (pow2 (8 * length w)) `fadd` (little_endian w) + +let rec poly (txt:text) (r:e:elem) : Tot elem (decreases (length txt)) = + if length txt = 0 then zero + else + let a = poly (Seq.tail txt) r in + let n = encode (Seq.head txt) in + (n `fadd` a) `fmul` r + +let encode_r (rb:word_16) = + (little_endian rb) &| 0x0ffffffc0ffffffc0ffffffc0fffffff + +let finish (a:elem) (s:word_16) : Tot tag = + let n = (a + little_endian s) % pow2 128 in + little_bytes 16ul n + +let rec encode_bytes (txt:bytes) : Tot text (decreases (length txt)) = + if length txt = 0 then createEmpty + else + let w, txt = split txt (min (length txt) 16) in + append_last (encode_bytes txt) w + +let poly1305 (msg:bytes) (k:key) : Tot tag = + let text = encode_bytes msg in + let r = encode_r (slice k 0 16) in + let s = slice k 16 32 in + finish (poly text r) s + + +(* ********************* *) +(* RFC 7539 Test Vectors *) +(* ********************* *) + +#reset-options "--initial_fuel 0 --max_fuel 0 --z3rlimit 20" + +unfold let msg = [ + 0x43uy; 0x72uy; 0x79uy; 0x70uy; 0x74uy; 0x6fuy; 0x67uy; 0x72uy; + 0x61uy; 0x70uy; 0x68uy; 0x69uy; 0x63uy; 0x20uy; 0x46uy; 0x6fuy; + 0x72uy; 0x75uy; 0x6duy; 0x20uy; 0x52uy; 0x65uy; 0x73uy; 0x65uy; + 0x61uy; 0x72uy; 0x63uy; 0x68uy; 0x20uy; 0x47uy; 0x72uy; 0x6fuy; + 0x75uy; 0x70uy ] + +unfold let k = [ + 0x85uy; 0xd6uy; 0xbeuy; 0x78uy; 0x57uy; 0x55uy; 0x6duy; 0x33uy; + 0x7fuy; 0x44uy; 0x52uy; 0xfeuy; 0x42uy; 0xd5uy; 0x06uy; 0xa8uy; + 0x01uy; 0x03uy; 0x80uy; 0x8auy; 0xfbuy; 0x0duy; 0xb2uy; 0xfduy; + 0x4auy; 0xbfuy; 0xf6uy; 0xafuy; 0x41uy; 0x49uy; 0xf5uy; 0x1buy ] + +unfold let expected = [ + 0xa8uy; 0x06uy; 0x1duy; 0xc1uy; 0x30uy; 0x51uy; 0x36uy; 0xc6uy; + 0xc2uy; 0x2buy; 0x8buy; 0xafuy; 0x0cuy; 0x01uy; 0x27uy; 0xa9uy ] + +let test () : Tot bool = + assert_norm(List.Tot.length msg = 34); + assert_norm(List.Tot.length k = 32); + assert_norm(List.Tot.length expected = 16); + let msg = createL msg in + let k = createL k in + let expected = createL expected in + poly1305 msg k = expected diff --git a/security/nss/lib/freebl/verified/vec128.h b/security/nss/lib/freebl/verified/vec128.h new file mode 100644 index 000000000..986e9db82 --- /dev/null +++ b/security/nss/lib/freebl/verified/vec128.h @@ -0,0 +1,345 @@ +/* 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. + */ + +#ifndef __Vec_H +#define __Vec_H + +#ifdef __MSVC__ +#define forceinline __forceinline inline +#elif (defined(__GNUC__) || defined(__clang__)) +#define forceinline __attribute__((always_inline)) inline +#else +#define forceinline inline +#endif + +#if defined(__SSSE3__) || defined(__AVX2__) || defined(__AVX__) + +#include <emmintrin.h> +#include <tmmintrin.h> + +#define VEC128 +#define vec_size 4 + +typedef __m128i vec; + +static forceinline vec +vec_rotate_left_8(vec v) +{ + __m128i x = _mm_set_epi8(14, 13, 12, 15, 10, 9, 8, 11, 6, 5, 4, 7, 2, 1, 0, 3); + return _mm_shuffle_epi8(v, x); +} + +static forceinline vec +vec_rotate_left_16(vec v) +{ + __m128i x = _mm_set_epi8(13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2); + return _mm_shuffle_epi8(v, x); +} + +static forceinline vec +vec_rotate_left(vec v, unsigned int n) +{ + if (n == 8) + return vec_rotate_left_8(v); + if (n == 16) + return vec_rotate_left_16(v); + return _mm_xor_si128(_mm_slli_epi32(v, n), + _mm_srli_epi32(v, 32 - n)); +} + +static forceinline vec +vec_rotate_right(vec v, unsigned int n) +{ + return (vec_rotate_left(v, 32 - n)); +} + +#define vec_shuffle_right(x, n) \ + _mm_shuffle_epi32(x, _MM_SHUFFLE((3 + (n)) % 4, (2 + (n)) % 4, (1 + (n)) % 4, (n) % 4)) + +#define vec_shuffle_left(x, n) vec_shuffle_right((x), 4 - (n)) + +static forceinline vec +vec_load_32x4(uint32_t x1, uint32_t x2, uint32_t x3, uint32_t x4) +{ + return _mm_set_epi32(x4, x3, x2, x1); +} + +static forceinline vec +vec_load_32x8(uint32_t x1, uint32_t x2, uint32_t x3, uint32_t x4, uint32_t x5, uint32_t x6, uint32_t x7, uint32_t x8) +{ + return _mm_set_epi32(x4, x3, x2, x1); +} + +static forceinline vec +vec_load_le(const unsigned char* in) +{ + return _mm_loadu_si128((__m128i*)(in)); +} + +static forceinline vec +vec_load128_le(const unsigned char* in) +{ + return vec_load_le(in); +} + +static forceinline void +vec_store_le(unsigned char* out, vec v) +{ + _mm_storeu_si128((__m128i*)(out), v); +} + +static forceinline vec +vec_add(vec v1, vec v2) +{ + return _mm_add_epi32(v1, v2); +} + +static forceinline vec +vec_add_u32(vec v1, uint32_t x) +{ + vec v2 = vec_load_32x4(x, 0, 0, 0); + return _mm_add_epi32(v1, v2); +} + +static forceinline vec +vec_increment(vec v1) +{ + vec one = vec_load_32x4(1, 0, 0, 0); + return _mm_add_epi32(v1, one); +} + +static forceinline vec +vec_xor(vec v1, vec v2) +{ + return _mm_xor_si128(v1, v2); +} + +#define vec_zero() _mm_set_epi32(0, 0, 0, 0) + +#elif defined(__ARM_NEON__) || defined(__ARM_NEON) +#include <arm_neon.h> + +typedef uint32x4_t vec; + +static forceinline vec +vec_xor(vec v1, vec v2) +{ + return veorq_u32(v1, v2); +} + +#define vec_rotate_left(x, n) \ + vsriq_n_u32(vshlq_n_u32((x), (n)), (x), 32 - (n)) + +#define vec_rotate_right(a, b) \ + vec_rotate_left((b), 32 - (b)) + +#define vec_shuffle_right(x, n) \ + vextq_u32((x), (x), (n)) + +#define vec_shuffle_left(a, b) \ + vec_shuffle_right((a), 4 - (b)) + +static forceinline vec +vec_load_32x4(uint32_t x1, uint32_t x2, uint32_t x3, uint32_t x4) +{ + uint32_t a[4] = { x1, x2, x3, x4 }; + return vld1q_u32(a); +} + +static forceinline vec +vec_load_32(uint32_t x1) +{ + uint32_t a[4] = { x1, x1, x1, x1 }; + return vld1q_u32(a); +} + +static forceinline vec +vec_load_32x8(uint32_t x1, uint32_t x2, uint32_t x3, uint32_t x4, uint32_t x5, uint32_t x6, uint32_t x7, uint32_t x8) +{ + return vec_load_32x4(x1, x2, x3, x4); +} + +static forceinline vec +vec_load_le(const unsigned char* in) +{ + return vld1q_u32((uint32_t*)in); +} + +static forceinline vec +vec_load128_le(const unsigned char* in) +{ + return vec_load_le(in); +} + +static forceinline void +vec_store_le(unsigned char* out, vec v) +{ + vst1q_u32((uint32_t*)out, v); +} + +static forceinline vec +vec_add(vec v1, vec v2) +{ + return vaddq_u32(v1, v2); +} + +static forceinline vec +vec_add_u32(vec v1, uint32_t x) +{ + vec v2 = vec_load_32x4(x, 0, 0, 0); + return vec_add(v1, v2); +} + +static forceinline vec +vec_increment(vec v1) +{ + vec one = vec_load_32x4(1, 0, 0, 0); + return vec_add(v1, one); +} + +#define vec_zero() vec_load_32x4(0, 0, 0, 0) + +#else + +#define VEC128 +#define vec_size 4 + +typedef struct { + uint32_t v[4]; +} vec; + +static forceinline vec +vec_xor(vec v1, vec v2) +{ + vec r; + r.v[0] = v1.v[0] ^ v2.v[0]; + r.v[1] = v1.v[1] ^ v2.v[1]; + r.v[2] = v1.v[2] ^ v2.v[2]; + r.v[3] = v1.v[3] ^ v2.v[3]; + return r; +} + +static forceinline vec +vec_rotate_left(vec v, unsigned int n) +{ + vec r; + r.v[0] = (v.v[0] << n) ^ (v.v[0] >> (32 - n)); + r.v[1] = (v.v[1] << n) ^ (v.v[1] >> (32 - n)); + r.v[2] = (v.v[2] << n) ^ (v.v[2] >> (32 - n)); + r.v[3] = (v.v[3] << n) ^ (v.v[3] >> (32 - n)); + return r; +} + +static forceinline vec +vec_rotate_right(vec v, unsigned int n) +{ + return (vec_rotate_left(v, 32 - n)); +} + +static forceinline vec +vec_shuffle_right(vec v, unsigned int n) +{ + vec r; + r.v[0] = v.v[n % 4]; + r.v[1] = v.v[(n + 1) % 4]; + r.v[2] = v.v[(n + 2) % 4]; + r.v[3] = v.v[(n + 3) % 4]; + return r; +} + +static forceinline vec +vec_shuffle_left(vec x, unsigned int n) +{ + return vec_shuffle_right(x, 4 - n); +} + +static forceinline vec +vec_load_32x4(uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3) +{ + vec v; + v.v[0] = x0; + v.v[1] = x1; + v.v[2] = x2; + v.v[3] = x3; + return v; +} + +static forceinline vec +vec_load_32(uint32_t x0) +{ + vec v; + v.v[0] = x0; + v.v[1] = x0; + v.v[2] = x0; + v.v[3] = x0; + return v; +} + +static forceinline vec +vec_load_le(const uint8_t* in) +{ + vec r; + r.v[0] = load32_le((uint8_t*)in); + r.v[1] = load32_le((uint8_t*)in + 4); + r.v[2] = load32_le((uint8_t*)in + 8); + r.v[3] = load32_le((uint8_t*)in + 12); + return r; +} + +static forceinline void +vec_store_le(unsigned char* out, vec r) +{ + store32_le(out, r.v[0]); + store32_le(out + 4, r.v[1]); + store32_le(out + 8, r.v[2]); + store32_le(out + 12, r.v[3]); +} + +static forceinline vec +vec_load128_le(const unsigned char* in) +{ + return vec_load_le(in); +} + +static forceinline vec +vec_add(vec v1, vec v2) +{ + vec r; + r.v[0] = v1.v[0] + v2.v[0]; + r.v[1] = v1.v[1] + v2.v[1]; + r.v[2] = v1.v[2] + v2.v[2]; + r.v[3] = v1.v[3] + v2.v[3]; + return r; +} + +static forceinline vec +vec_add_u32(vec v1, uint32_t x) +{ + vec v2 = vec_load_32x4(x, 0, 0, 0); + return vec_add(v1, v2); +} + +static forceinline vec +vec_increment(vec v1) +{ + vec one = vec_load_32x4(1, 0, 0, 0); + return vec_add(v1, one); +} + +#define vec_zero() vec_load_32x4(0, 0, 0, 0) + +#endif + +#endif diff --git a/security/nss/lib/nss/nss.def b/security/nss/lib/nss/nss.def index e1453cc84..4f0ade4d0 100644 --- a/security/nss/lib/nss/nss.def +++ b/security/nss/lib/nss/nss.def @@ -1115,3 +1115,21 @@ PK11_GetTokenURI; ;+ local: ;+ *; ;+}; +;+NSS_3.33 { # NSS 3.33 release +;+ global: +CERT_FindCertByIssuerAndSNCX; +CERT_FindCertByNicknameOrEmailAddrCX; +CERT_FindCertByNicknameOrEmailAddrForUsageCX; +;+ local: +;+ *; +;+}; +;+NSS_3.34 { # NSS 3.34 release +;+ global: +PK11_CreateManagedGenericObject; +SGN_NewContextWithAlgorithmID; +SEC_SignDataWithAlgorithmID; +SEC_DerSignDataWithAlgorithmID; +SEC_CreateSignatureAlgorithmParameters; +;+ local: +;+ *; +;+}; diff --git a/security/nss/lib/nss/nss.h b/security/nss/lib/nss/nss.h index 8238faca7..d62f4957b 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.32.1" _NSS_CUSTOMIZED +#define NSS_VERSION "3.36.4" _NSS_CUSTOMIZED #define NSS_VMAJOR 3 -#define NSS_VMINOR 32 -#define NSS_VPATCH 1 +#define NSS_VMINOR 36 +#define NSS_VPATCH 4 #define NSS_VBUILD 0 #define NSS_BETA PR_FALSE @@ -291,6 +291,15 @@ SECStatus NSS_UnregisterShutdown(NSS_ShutdownFunc sFunc, void *appData); #define NSS_DTLS_VERSION_MIN_POLICY 0x00a #define NSS_DTLS_VERSION_MAX_POLICY 0x00b +/* Until NSS 3.30, the PKCS#12 implementation used BMPString encoding + * for all passwords. This changed to use UTF-8 for non-PKCS#12 PBEs + * in NSS 3.31. + * + * For backward compatibility, this option reverts the behavior to the + * old NSS versions. This option might be removed in the future NSS + * releases; don't rely on it. */ +#define __NSS_PKCS12_DECODE_FORCE_UNICODE 0x00c + /* * Set and get global options for the NSS library. */ diff --git a/security/nss/lib/nss/nssoptions.c b/security/nss/lib/nss/nssoptions.c index fc97d6278..1339cede8 100644 --- a/security/nss/lib/nss/nssoptions.c +++ b/security/nss/lib/nss/nssoptions.c @@ -23,6 +23,7 @@ struct nssOps { PRInt32 tlsVersionMaxPolicy; PRInt32 dtlsVersionMinPolicy; PRInt32 dtlsVersionMaxPolicy; + PRInt32 pkcs12DecodeForceUnicode; }; static struct nssOps nss_ops = { @@ -33,6 +34,7 @@ static struct nssOps nss_ops = { 0xffff, /* set TLS max to more than the largest legal SSL value */ 1, 0xffff, + PR_FALSE }; SECStatus @@ -62,6 +64,9 @@ NSS_OptionSet(PRInt32 which, PRInt32 value) case NSS_DTLS_VERSION_MAX_POLICY: nss_ops.dtlsVersionMaxPolicy = value; break; + case __NSS_PKCS12_DECODE_FORCE_UNICODE: + nss_ops.pkcs12DecodeForceUnicode = value; + break; default: rv = SECFailure; } @@ -96,6 +101,9 @@ NSS_OptionGet(PRInt32 which, PRInt32 *value) case NSS_DTLS_VERSION_MAX_POLICY: *value = nss_ops.dtlsVersionMaxPolicy; break; + case __NSS_PKCS12_DECODE_FORCE_UNICODE: + *value = nss_ops.pkcs12DecodeForceUnicode; + break; default: rv = SECFailure; } diff --git a/security/nss/lib/nss/utilwrap.c b/security/nss/lib/nss/utilwrap.c index 938d95c0f..48e147d88 100644 --- a/security/nss/lib/nss/utilwrap.c +++ b/security/nss/lib/nss/utilwrap.c @@ -75,6 +75,8 @@ #undef PORT_UCS2_ASCIIConversion #undef PORT_UCS2_UTF8Conversion #undef PORT_ZAlloc +#undef PORT_ZAllocAligned +#undef PORT_ZAllocAlignedOffset #undef PORT_ZFree #undef SEC_ASN1Decode #undef SEC_ASN1DecodeInteger @@ -144,6 +146,18 @@ PORT_ZAlloc(size_t bytes) return PORT_ZAlloc_Util(bytes); } +void * +PORT_ZAllocAligned(size_t bytes, size_t alignment, void **mem) +{ + return PORT_ZAllocAligned_Util(bytes, alignment, mem); +} + +void * +PORT_ZAllocAlignedOffset(size_t bytes, size_t alignment, size_t offset) +{ + return PORT_ZAllocAlignedOffset_Util(bytes, alignment, offset); +} + void PORT_Free(void *ptr) { diff --git a/security/nss/lib/pk11wrap/dev3hack.c b/security/nss/lib/pk11wrap/dev3hack.c index 39afd6743..3fb0cb0aa 100644 --- a/security/nss/lib/pk11wrap/dev3hack.c +++ b/security/nss/lib/pk11wrap/dev3hack.c @@ -120,6 +120,10 @@ nssSlot_CreateFromPK11SlotInfo(NSSTrustDomain *td, PK11SlotInfo *nss3slot) /* Grab the slot name from the PKCS#11 fixed-length buffer */ rvSlot->base.name = nssUTF8_Duplicate(nss3slot->slot_name, td->arena); rvSlot->lock = (nss3slot->isThreadSafe) ? NULL : nss3slot->sessionLock; + rvSlot->isPresentLock = PZ_NewLock(nssiLockOther); + rvSlot->isPresentCondition = PR_NewCondVar(rvSlot->isPresentLock); + rvSlot->isPresentThread = NULL; + rvSlot->lastTokenPingState = nssSlotLastPingState_Reset; return rvSlot; } diff --git a/security/nss/lib/pk11wrap/pk11auth.c b/security/nss/lib/pk11wrap/pk11auth.c index 625fa2dc6..6a3ba40d9 100644 --- a/security/nss/lib/pk11wrap/pk11auth.c +++ b/security/nss/lib/pk11wrap/pk11auth.c @@ -636,7 +636,7 @@ PK11_DoPassword(PK11SlotInfo *slot, CK_SESSION_HANDLE session, break; } if (rv == SECSuccess) { - if (!PK11_IsFriendly(slot)) { + if (!contextSpecific && !PK11_IsFriendly(slot)) { nssTrustDomain_UpdateCachedTokenCerts(slot->nssToken->trustDomain, slot->nssToken); } diff --git a/security/nss/lib/pk11wrap/pk11load.c b/security/nss/lib/pk11wrap/pk11load.c index 91339fad8..d1f6ec442 100644 --- a/security/nss/lib/pk11wrap/pk11load.c +++ b/security/nss/lib/pk11wrap/pk11load.c @@ -64,8 +64,7 @@ secmodUnlockMutext(CK_VOID_PTR mutext) static SECMODModuleID nextModuleID = 1; static const CK_C_INITIALIZE_ARGS secmodLockFunctions = { secmodCreateMutext, secmodDestroyMutext, secmodLockMutext, - secmodUnlockMutext, CKF_LIBRARY_CANT_CREATE_OS_THREADS | - CKF_OS_LOCKING_OK, + secmodUnlockMutext, CKF_LIBRARY_CANT_CREATE_OS_THREADS | CKF_OS_LOCKING_OK, NULL }; static const CK_C_INITIALIZE_ARGS secmodNoLockArgs = { diff --git a/security/nss/lib/pk11wrap/pk11merge.c b/security/nss/lib/pk11wrap/pk11merge.c index 8c4c5129a..c6125b6e6 100644 --- a/security/nss/lib/pk11wrap/pk11merge.c +++ b/security/nss/lib/pk11wrap/pk11merge.c @@ -68,10 +68,13 @@ pk11_copyAttributes(PLArenaPool *arena, copyTemplate, copyTemplateCount); /* if we have missing attributes, just skip them and create the object */ if (crv == CKR_ATTRIBUTE_TYPE_INVALID) { - int i, j; + CK_ULONG i, j; newTemplate = PORT_NewArray(CK_ATTRIBUTE, copyTemplateCount); + if (!newTemplate) { + return SECFailure; + } /* remove the unknown attributes. If we don't have enough attributes - * PK11_CreateNewObject() will fail */ + * PK11_CreateNewObject() will fail */ for (i = 0, j = 0; i < copyTemplateCount; i++) { if (copyTemplate[i].ulValueLen != -1) { newTemplate[j] = copyTemplate[i]; @@ -85,6 +88,7 @@ pk11_copyAttributes(PLArenaPool *arena, } if (crv != CKR_OK) { PORT_SetError(PK11_MapError(crv)); + PORT_Free(newTemplate); return SECFailure; } if (targetID == CK_INVALID_HANDLE) { @@ -97,7 +101,7 @@ pk11_copyAttributes(PLArenaPool *arena, copyTemplate, copyTemplateCount); } if (newTemplate) { - free(newTemplate); + PORT_Free(newTemplate); } return rv; } @@ -1258,6 +1262,7 @@ pk11_newMergeLogNode(PLArenaPool *arena, /* initialize it */ obj->slot = slot; obj->objectID = id; + obj->owner = PR_FALSE; newLog->object = obj; newLog->error = error; diff --git a/security/nss/lib/pk11wrap/pk11obj.c b/security/nss/lib/pk11wrap/pk11obj.c index 47c56154d..b97caddd4 100644 --- a/security/nss/lib/pk11wrap/pk11obj.c +++ b/security/nss/lib/pk11wrap/pk11obj.c @@ -201,7 +201,6 @@ PK11_GetAttributes(PLArenaPool *arena, PK11SlotInfo *slot, /* make pedantic happy... note that it's only used arena != NULL */ void *mark = NULL; CK_RV crv; - PORT_Assert(slot->session != CK_INVALID_SESSION); if (slot->session == CK_INVALID_SESSION) return CKR_SESSION_HANDLE_INVALID; @@ -1506,6 +1505,7 @@ PK11_FindGenericObjects(PK11SlotInfo *slot, CK_OBJECT_CLASS objClass) /* initialize it */ obj->slot = PK11_ReferenceSlot(slot); obj->objectID = objectIDs[i]; + obj->owner = PR_FALSE; obj->next = NULL; obj->prev = NULL; @@ -1586,6 +1586,9 @@ PK11_DestroyGenericObject(PK11GenericObject *object) PK11_UnlinkGenericObject(object); if (object->slot) { + if (object->owner) { + PK11_DestroyObject(object->slot, object->objectID); + } PK11_FreeSlot(object->slot); } PORT_Free(object); @@ -1627,8 +1630,9 @@ PK11_DestroyGenericObjects(PK11GenericObject *objects) * Hand Create a new object and return the Generic object for our new object. */ PK11GenericObject * -PK11_CreateGenericObject(PK11SlotInfo *slot, const CK_ATTRIBUTE *pTemplate, - int count, PRBool token) +pk11_CreateGenericObjectHelper(PK11SlotInfo *slot, + const CK_ATTRIBUTE *pTemplate, + int count, PRBool token, PRBool owner) { CK_OBJECT_HANDLE objectID; PK11GenericObject *obj; @@ -1652,11 +1656,40 @@ PK11_CreateGenericObject(PK11SlotInfo *slot, const CK_ATTRIBUTE *pTemplate, /* initialize it */ obj->slot = PK11_ReferenceSlot(slot); obj->objectID = objectID; + obj->owner = owner; obj->next = NULL; obj->prev = NULL; return obj; } +/* This is the classic interface. Applications would call this function to + * create new object that would not be destroyed later. This lead to resource + * leaks (and thus memory leaks in the PKCS #11 module). To solve this we have + * a new interface that automatically marks objects created on the fly to be + * destroyed later. + * The old interface is preserved because applications like Mozilla purposefully + * leak the reference to be found later with PK11_FindGenericObjects. New + * applications should use the new interface PK11_CreateManagedGenericObject */ +PK11GenericObject * +PK11_CreateGenericObject(PK11SlotInfo *slot, const CK_ATTRIBUTE *pTemplate, + int count, PRBool token) +{ + return pk11_CreateGenericObjectHelper(slot, pTemplate, count, token, + PR_FALSE); +} + +/* Use this interface. It will automatically destroy any temporary objects + * (token = PR_FALSE) when the PK11GenericObject is freed. Permanent objects still + * need to be destroyed by hand with PK11_DestroyTokenObject. + */ +PK11GenericObject * +PK11_CreateManagedGenericObject(PK11SlotInfo *slot, + const CK_ATTRIBUTE *pTemplate, int count, PRBool token) +{ + return pk11_CreateGenericObjectHelper(slot, pTemplate, count, token, + !token); +} + /* * Change an attribute on a raw object */ diff --git a/security/nss/lib/pk11wrap/pk11pars.c b/security/nss/lib/pk11wrap/pk11pars.c index ee20789cc..fc30222b3 100644 --- a/security/nss/lib/pk11wrap/pk11pars.c +++ b/security/nss/lib/pk11wrap/pk11pars.c @@ -413,8 +413,7 @@ static const policyFlagDef policyFlagList[] = { /* add other signatures in the future */ { CIPHER_NAME("SIGNATURE"), NSS_USE_ALG_IN_CERT_SIGNATURE }, /* enable everything */ - { CIPHER_NAME("ALL"), NSS_USE_ALG_IN_SSL | NSS_USE_ALG_IN_SSL_KX | - NSS_USE_ALG_IN_CERT_SIGNATURE }, + { CIPHER_NAME("ALL"), NSS_USE_ALG_IN_SSL | NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE }, { CIPHER_NAME("NONE"), 0 } }; diff --git a/security/nss/lib/pk11wrap/pk11pbe.c b/security/nss/lib/pk11wrap/pk11pbe.c index bea9333f6..5f68f399e 100644 --- a/security/nss/lib/pk11wrap/pk11pbe.c +++ b/security/nss/lib/pk11wrap/pk11pbe.c @@ -367,7 +367,24 @@ sec_pkcs5v2_key_length(SECAlgorithmID *algid, SECAlgorithmID *cipherAlgId) cipherAlg = SECOID_GetAlgorithmTag(cipherAlgId); if (sec_pkcs5_is_algorithm_v2_aes_algorithm(cipherAlg)) { - length = sec_pkcs5v2_aes_key_length(cipherAlg); + /* Previously, the PKCS#12 files created with the old NSS + * releases encoded the maximum key size of AES (that is 32) + * in the keyLength field of PBKDF2-params. That resulted in + * always performing AES-256 even if AES-128-CBC or + * AES-192-CBC is specified in the encryptionScheme field of + * PBES2-params. This is wrong, but for compatibility reasons, + * check the keyLength field and use the value if it is 32. + */ + if (p5_param.keyLength.data != NULL) { + length = DER_GetInteger(&p5_param.keyLength); + } + /* If the keyLength field is present and contains a value + * other than 32, that means the file is created outside of + * NSS, which we don't care about. Note that the following + * also handles the case when the field is absent. */ + if (length != 32) { + length = sec_pkcs5v2_aes_key_length(cipherAlg); + } } else if (p5_param.keyLength.data != NULL) { length = DER_GetInteger(&p5_param.keyLength); } else { diff --git a/security/nss/lib/pk11wrap/pk11pk12.c b/security/nss/lib/pk11wrap/pk11pk12.c index d753b87e5..035143af8 100644 --- a/security/nss/lib/pk11wrap/pk11pk12.c +++ b/security/nss/lib/pk11wrap/pk11pk12.c @@ -153,7 +153,6 @@ const SEC_ASN1Template SECKEY_DHPrivateKeyExportTemplate[] = { { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.dh.prime) }, }; -#ifndef NSS_DISABLE_ECC SEC_ASN1_MKSUB(SEC_BitStringTemplate) SEC_ASN1_MKSUB(SEC_ObjectIDTemplate) @@ -178,7 +177,6 @@ const SEC_ASN1Template SECKEY_ECPrivateKeyExportTemplate[] = { SEC_ASN1_SUB(SEC_BitStringTemplate) }, { 0 } }; -#endif /* NSS_DISABLE_ECC */ const SEC_ASN1Template SECKEY_EncryptedPrivateKeyInfoTemplate[] = { { SEC_ASN1_SEQUENCE, @@ -346,16 +344,13 @@ PK11_ImportAndReturnPrivateKey(PK11SlotInfo *slot, SECKEYRawPrivateKey *lpk, switch (lpk->keyType) { case rsaKey: keyType = CKK_RSA; - PK11_SETATTRS(attrs, CKA_UNWRAP, (keyUsage & KU_KEY_ENCIPHERMENT) ? &cktrue - : &ckfalse, + PK11_SETATTRS(attrs, CKA_UNWRAP, (keyUsage & KU_KEY_ENCIPHERMENT) ? &cktrue : &ckfalse, sizeof(CK_BBOOL)); attrs++; - PK11_SETATTRS(attrs, CKA_DECRYPT, (keyUsage & KU_DATA_ENCIPHERMENT) ? &cktrue - : &ckfalse, + PK11_SETATTRS(attrs, CKA_DECRYPT, (keyUsage & KU_DATA_ENCIPHERMENT) ? &cktrue : &ckfalse, sizeof(CK_BBOOL)); attrs++; - PK11_SETATTRS(attrs, CKA_SIGN, (keyUsage & KU_DIGITAL_SIGNATURE) ? &cktrue - : &ckfalse, + PK11_SETATTRS(attrs, CKA_SIGN, (keyUsage & KU_DIGITAL_SIGNATURE) ? &cktrue : &ckfalse, sizeof(CK_BBOOL)); attrs++; PK11_SETATTRS(attrs, CKA_SIGN_RECOVER, @@ -482,7 +477,6 @@ PK11_ImportAndReturnPrivateKey(PK11SlotInfo *slot, SECKEYRawPrivateKey *lpk, lpk->u.dh.privateValue.len); attrs++; break; -#ifndef NSS_DISABLE_ECC case ecKey: keyType = CKK_EC; if (lpk->u.ec.publicValue.len == 0) { @@ -494,8 +488,7 @@ PK11_ImportAndReturnPrivateKey(PK11SlotInfo *slot, SECKEYRawPrivateKey *lpk, lpk->u.ec.publicValue.len); attrs++; } - PK11_SETATTRS(attrs, CKA_SIGN, (keyUsage & KU_DIGITAL_SIGNATURE) ? &cktrue - : &ckfalse, + PK11_SETATTRS(attrs, CKA_SIGN, (keyUsage & KU_DIGITAL_SIGNATURE) ? &cktrue : &ckfalse, sizeof(CK_BBOOL)); attrs++; PK11_SETATTRS(attrs, CKA_SIGN_RECOVER, @@ -503,8 +496,7 @@ PK11_ImportAndReturnPrivateKey(PK11SlotInfo *slot, SECKEYRawPrivateKey *lpk, : &ckfalse, sizeof(CK_BBOOL)); attrs++; - PK11_SETATTRS(attrs, CKA_DERIVE, (keyUsage & KU_KEY_AGREEMENT) ? &cktrue - : &ckfalse, + PK11_SETATTRS(attrs, CKA_DERIVE, (keyUsage & KU_KEY_AGREEMENT) ? &cktrue : &ckfalse, sizeof(CK_BBOOL)); attrs++; ck_id = PK11_MakeIDFromPubKey(&lpk->u.ec.publicValue); @@ -525,7 +517,6 @@ PK11_ImportAndReturnPrivateKey(PK11SlotInfo *slot, SECKEYRawPrivateKey *lpk, lpk->u.ec.publicValue.len); attrs++; break; -#endif /* NSS_DISABLE_ECC */ default: PORT_SetError(SEC_ERROR_BAD_KEY); goto loser; @@ -606,7 +597,6 @@ PK11_ImportPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot, paramDest = NULL; lpk->keyType = dhKey; break; -#ifndef NSS_DISABLE_ECC case SEC_OID_ANSIX962_EC_PUBLIC_KEY: prepare_ec_priv_key_export_for_asn1(lpk); keyTemplate = SECKEY_ECPrivateKeyExportTemplate; @@ -614,7 +604,6 @@ PK11_ImportPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot, paramDest = NULL; lpk->keyType = ecKey; break; -#endif /* NSS_DISABLE_ECC */ default: keyTemplate = NULL; @@ -633,7 +622,6 @@ PK11_ImportPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot, goto loser; } -#ifndef NSS_DISABLE_ECC if (lpk->keyType == ecKey) { /* Convert length in bits to length in bytes. */ lpk->u.ec.publicValue.len >>= 3; @@ -645,7 +633,6 @@ PK11_ImportPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot, goto loser; } } -#endif /* NSS_DISABLE_ECC */ if (paramDest && paramTemplate) { rv = SEC_ASN1DecodeItem(arena, paramDest, paramTemplate, diff --git a/security/nss/lib/pk11wrap/pk11pub.h b/security/nss/lib/pk11wrap/pk11pub.h index edfe82f5a..dbd8da092 100644 --- a/security/nss/lib/pk11wrap/pk11pub.h +++ b/security/nss/lib/pk11wrap/pk11pub.h @@ -831,6 +831,10 @@ SECStatus PK11_LinkGenericObject(PK11GenericObject *list, PK11GenericObject *object); SECStatus PK11_DestroyGenericObjects(PK11GenericObject *object); SECStatus PK11_DestroyGenericObject(PK11GenericObject *object); +PK11GenericObject *PK11_CreateManagedGenericObject(PK11SlotInfo *slot, + const CK_ATTRIBUTE *pTemplate, + int count, PRBool token); +/* deprecated */ PK11GenericObject *PK11_CreateGenericObject(PK11SlotInfo *slot, const CK_ATTRIBUTE *pTemplate, int count, PRBool token); diff --git a/security/nss/lib/pk11wrap/pk11skey.c b/security/nss/lib/pk11wrap/pk11skey.c index 1ef53e1d7..cf2a40a2f 100644 --- a/security/nss/lib/pk11wrap/pk11skey.c +++ b/security/nss/lib/pk11wrap/pk11skey.c @@ -182,6 +182,10 @@ PK11_FreeSymKey(PK11SymKey *symKey) PK11SlotInfo *slot; PRBool freeit = PR_TRUE; + if (!symKey) { + return; + } + if (PR_ATOMIC_DECREMENT(&symKey->refCount) == 0) { PK11SymKey *parent = symKey->parent; diff --git a/security/nss/lib/pk11wrap/pk11slot.c b/security/nss/lib/pk11wrap/pk11slot.c index 0a6ed6c08..c39abe17e 100644 --- a/security/nss/lib/pk11wrap/pk11slot.c +++ b/security/nss/lib/pk11wrap/pk11slot.c @@ -1182,7 +1182,7 @@ PK11_InitToken(PK11SlotInfo *slot, PRBool loadCerts) /* set the slot flags to the current token values */ slot->series++; /* allow other objects to detect that the - * slot is different */ + * slot is different */ slot->flags = slot->tokenInfo.flags; slot->needLogin = ((slot->tokenInfo.flags & CKF_LOGIN_REQUIRED) ? PR_TRUE : PR_FALSE); slot->readOnly = ((slot->tokenInfo.flags & CKF_WRITE_PROTECTED) ? PR_TRUE : PR_FALSE); @@ -1471,6 +1471,9 @@ PK11_InitSlot(SECMODModule *mod, CK_SLOT_ID slotID, PK11SlotInfo *slot) slot->hasRootCerts = PR_TRUE; } } + if ((slotInfo.flags & CKF_USER_PIN_INITIALIZED) != 0) { + slot->flags |= CKF_USER_PIN_INITIALIZED; + } } /********************************************************************* diff --git a/security/nss/lib/pk11wrap/pk11util.c b/security/nss/lib/pk11wrap/pk11util.c index a962e9bb3..e316f1f1a 100644 --- a/security/nss/lib/pk11wrap/pk11util.c +++ b/security/nss/lib/pk11wrap/pk11util.c @@ -437,6 +437,11 @@ SECMOD_DeleteInternalModule(const char *name) return rv; } +#ifdef NSS_FIPS_DISABLED + PORT_SetError(PR_OPERATION_NOT_SUPPORTED_ERROR); + return rv; +#endif + SECMOD_GetWriteLock(moduleLock); for (mlpp = &modules, mlp = modules; mlp != NULL; mlpp = &mlp->next, mlp = *mlpp) { @@ -955,7 +960,11 @@ SECMOD_DestroyModuleList(SECMODModuleList *list) PRBool SECMOD_CanDeleteInternalModule(void) { +#ifdef NSS_FIPS_DISABLED + return PR_FALSE; +#else return (PRBool)(pendingModule == NULL); +#endif } /* diff --git a/security/nss/lib/pk11wrap/secmodi.h b/security/nss/lib/pk11wrap/secmodi.h index 1225661ad..84f5f2a30 100644 --- a/security/nss/lib/pk11wrap/secmodi.h +++ b/security/nss/lib/pk11wrap/secmodi.h @@ -164,6 +164,7 @@ CERTCertificate *PK11_MakeCertFromHandle(PK11SlotInfo *slot, SECItem *pk11_GenerateNewParamWithKeyLen(CK_MECHANISM_TYPE type, int keyLen); SECItem *pk11_ParamFromIVWithLen(CK_MECHANISM_TYPE type, SECItem *iv, int keyLen); +SECItem *pk11_mkcertKeyID(CERTCertificate *cert); SEC_END_PROTOS diff --git a/security/nss/lib/pk11wrap/secmodti.h b/security/nss/lib/pk11wrap/secmodti.h index 63c207929..260e6387d 100644 --- a/security/nss/lib/pk11wrap/secmodti.h +++ b/security/nss/lib/pk11wrap/secmodti.h @@ -175,6 +175,7 @@ struct PK11GenericObjectStr { PK11GenericObject *next; PK11SlotInfo *slot; CK_OBJECT_HANDLE objectID; + PRBool owner; }; #define MAX_TEMPL_ATTRS 16 /* maximum attributes in template */ diff --git a/security/nss/lib/pkcs12/p12d.c b/security/nss/lib/pkcs12/p12d.c index 57333ac37..34362db2d 100644 --- a/security/nss/lib/pkcs12/p12d.c +++ b/security/nss/lib/pkcs12/p12d.c @@ -3,6 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nssrenam.h" +#include "nss.h" #include "p12t.h" #include "p12.h" #include "plarena.h" @@ -126,6 +127,7 @@ struct SEC_PKCS12DecoderContextStr { SECKEYGetPasswordKey pwfn; void *pwfnarg; PRBool swapUnicodeBytes; + PRBool forceUnicode; /* import information */ PRBool bagsVerified; @@ -192,8 +194,18 @@ sec_pkcs12_decoder_get_decrypt_key(void *arg, SECAlgorithmID *algid) } algorithm = SECOID_GetAlgorithmTag(algid); - if (!sec_pkcs12_decode_password(NULL, &pwitem, algorithm, p12dcx->pwitem)) - return NULL; + + if (p12dcx->forceUnicode) { + if (SECITEM_CopyItem(NULL, &pwitem, p12dcx->pwitem) != SECSuccess) { + PK11_FreeSlot(slot); + return NULL; + } + } else { + if (!sec_pkcs12_decode_password(NULL, &pwitem, algorithm, p12dcx->pwitem)) { + PK11_FreeSlot(slot); + return NULL; + } + } bulkKey = PK11_PBEKeyGen(slot, algid, &pwitem, PR_FALSE, p12dcx->wincx); /* some tokens can't generate PBE keys on their own, generate the @@ -801,6 +813,7 @@ sec_pkcs12_decoder_asafes_notify(void *arg, PRBool before, void *dest, unsigned int cnt = p12dcx->safeContentsCnt - 1; safeContentsCtx = p12dcx->safeContentsList[cnt]; if (safeContentsCtx->safeContentsA1Dcx) { + SEC_ASN1DecoderClearFilterProc(p12dcx->aSafeA1Dcx); SEC_ASN1DecoderFinish(safeContentsCtx->safeContentsA1Dcx); safeContentsCtx->safeContentsA1Dcx = NULL; } @@ -1164,6 +1177,8 @@ SEC_PKCS12DecoderStart(SECItem *pwitem, PK11SlotInfo *slot, void *wincx, { SEC_PKCS12DecoderContext *p12dcx; PLArenaPool *arena; + PRInt32 forceUnicode = PR_FALSE; + SECStatus rv; arena = PORT_NewArena(2048); /* different size? */ if (!arena) { @@ -1196,6 +1211,11 @@ SEC_PKCS12DecoderStart(SECItem *pwitem, PK11SlotInfo *slot, void *wincx, #else p12dcx->swapUnicodeBytes = PR_FALSE; #endif + rv = NSS_OptionGet(__NSS_PKCS12_DECODE_FORCE_UNICODE, &forceUnicode); + if (rv != SECSuccess) { + goto loser; + } + p12dcx->forceUnicode = forceUnicode; p12dcx->errorValue = 0; p12dcx->error = PR_FALSE; @@ -2428,7 +2448,7 @@ sec_pkcs12_get_public_value_and_type(SECKEYPublicKey *pubKey, KeyType *type); static SECStatus sec_pkcs12_add_key(sec_PKCS12SafeBag *key, SECKEYPublicKey *pubKey, unsigned int keyUsage, - SECItem *nickName, void *wincx) + SECItem *nickName, PRBool forceUnicode, void *wincx) { SECStatus rv; SECItem *publicValue = NULL; @@ -2466,9 +2486,21 @@ sec_pkcs12_add_key(sec_PKCS12SafeBag *key, SECKEYPublicKey *pubKey, &key->safeBagContent.pkcs8ShroudedKeyBag->algorithm; SECOidTag algorithm = SECOID_GetAlgorithmTag(algid); - if (!sec_pkcs12_decode_password(NULL, &pwitem, algorithm, - key->pwitem)) - return SECFailure; + if (forceUnicode) { + if (SECITEM_CopyItem(NULL, &pwitem, key->pwitem) != SECSuccess) { + key->error = SEC_ERROR_PKCS12_UNABLE_TO_IMPORT_KEY; + key->problem = PR_TRUE; + return SECFailure; + } + } else { + if (!sec_pkcs12_decode_password(NULL, &pwitem, algorithm, + key->pwitem)) { + key->error = SEC_ERROR_PKCS12_UNABLE_TO_IMPORT_KEY; + key->problem = PR_TRUE; + return SECFailure; + } + } + rv = PK11_ImportEncryptedPrivateKeyInfo(key->slot, key->safeBagContent.pkcs8ShroudedKeyBag, &pwitem, nickName, publicValue, @@ -2923,7 +2955,8 @@ sec_pkcs12_get_public_value_and_type(SECKEYPublicKey *pubKey, * two passes in sec_pkcs12_validate_bags. */ static SECStatus -sec_pkcs12_install_bags(sec_PKCS12SafeBag **safeBags, void *wincx) +sec_pkcs12_install_bags(sec_PKCS12SafeBag **safeBags, PRBool forceUnicode, + void *wincx) { sec_PKCS12SafeBag **keyList; int i; @@ -2976,7 +3009,8 @@ sec_pkcs12_install_bags(sec_PKCS12SafeBag **safeBags, void *wincx) key->problem = PR_TRUE; rv = SECFailure; } else { - rv = sec_pkcs12_add_key(key, pubKey, keyUsage, nickName, wincx); + rv = sec_pkcs12_add_key(key, pubKey, keyUsage, nickName, + forceUnicode, wincx); } if (pubKey) { SECKEY_DestroyPublicKey(pubKey); @@ -3053,6 +3087,9 @@ sec_pkcs12_install_bags(sec_PKCS12SafeBag **safeBags, void *wincx) SECStatus SEC_PKCS12DecoderImportBags(SEC_PKCS12DecoderContext *p12dcx) { + PRBool forceUnicode = PR_FALSE; + SECStatus rv; + if (!p12dcx || p12dcx->error) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; @@ -3062,7 +3099,16 @@ SEC_PKCS12DecoderImportBags(SEC_PKCS12DecoderContext *p12dcx) return SECFailure; } - return sec_pkcs12_install_bags(p12dcx->safeBags, p12dcx->wincx); + /* We need to check the option here as well as in + * SEC_PKCS12DecoderStart, because different PBE's could be used + * for PKCS #7 and PKCS #8 */ + rv = NSS_OptionGet(__NSS_PKCS12_DECODE_FORCE_UNICODE, &forceUnicode); + if (rv != SECSuccess) { + return SECFailure; + } + + return sec_pkcs12_install_bags(p12dcx->safeBags, forceUnicode, + p12dcx->wincx); } PRBool diff --git a/security/nss/lib/pkcs12/p12local.c b/security/nss/lib/pkcs12/p12local.c index a94c08be1..53e3aa6bb 100644 --- a/security/nss/lib/pkcs12/p12local.c +++ b/security/nss/lib/pkcs12/p12local.c @@ -267,8 +267,7 @@ sec_pkcs12_generate_key_from_password(SECOidTag algorithm, return NULL; } - pre_hash = (unsigned char *)PORT_ArenaZAlloc(poolp, sizeof(char) * - (salt->len + password->len)); + pre_hash = (unsigned char *)PORT_ArenaZAlloc(poolp, sizeof(char) * (salt->len + password->len)); if (pre_hash == NULL) { PORT_SetError(SEC_ERROR_NO_MEMORY); goto loser; diff --git a/security/nss/lib/pkcs7/p7create.c b/security/nss/lib/pkcs7/p7create.c index 96ada5c0f..f19330386 100644 --- a/security/nss/lib/pkcs7/p7create.c +++ b/security/nss/lib/pkcs7/p7create.c @@ -18,7 +18,13 @@ #include "secder.h" #include "secpkcs5.h" -const int NSS_PBE_DEFAULT_ITERATION_COUNT = 2000; /* used in p12e.c too */ +const int NSS_PBE_DEFAULT_ITERATION_COUNT = /* used in p12e.c too */ +#ifdef DEBUG + 10000 +#else + 600000 +#endif + ; static SECStatus sec_pkcs7_init_content_info(SEC_PKCS7ContentInfo *cinfo, PLArenaPool *poolp, diff --git a/security/nss/lib/pkcs7/p7decode.c b/security/nss/lib/pkcs7/p7decode.c index 658c61e44..4f17b8e84 100644 --- a/security/nss/lib/pkcs7/p7decode.c +++ b/security/nss/lib/pkcs7/p7decode.c @@ -560,6 +560,7 @@ sec_pkcs7_decoder_start_decrypt(SEC_PKCS7DecoderContext *p7dcx, int depth, return SECSuccess; no_decryption: + PK11_FreeSymKey(bulkkey); /* * For some reason (error set already, if appropriate), we cannot * decrypt the content. I am not sure what exactly is the right @@ -1031,6 +1032,11 @@ SECStatus SEC_PKCS7DecoderUpdate(SEC_PKCS7DecoderContext *p7dcx, const char *buf, unsigned long len) { + if (!p7dcx) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + if (p7dcx->cinfo != NULL && p7dcx->dcx != NULL) { PORT_Assert(p7dcx->error == 0); if (p7dcx->error == 0) { diff --git a/security/nss/lib/pki/pki3hack.c b/security/nss/lib/pki/pki3hack.c index 548853970..fb3110a23 100644 --- a/security/nss/lib/pki/pki3hack.c +++ b/security/nss/lib/pki/pki3hack.c @@ -180,16 +180,18 @@ STAN_RemoveModuleFromDefaultTrustDomain( NSSTrustDomain *td; int i; td = STAN_GetDefaultTrustDomain(); - NSSRWLock_LockWrite(td->tokensLock); for (i = 0; i < module->slotCount; i++) { token = PK11Slot_GetNSSToken(module->slots[i]); if (token) { nssToken_NotifyCertsNotVisible(token); + NSSRWLock_LockWrite(td->tokensLock); nssList_Remove(td->tokenList, token); + NSSRWLock_UnlockWrite(td->tokensLock); PK11Slot_SetNSSToken(module->slots[i], NULL); nssToken_Destroy(token); } } + NSSRWLock_LockWrite(td->tokensLock); nssListIterator_Destroy(td->tokens); td->tokens = nssList_CreateIterator(td->tokenList); NSSRWLock_UnlockWrite(td->tokensLock); diff --git a/security/nss/lib/pki/pkibase.c b/security/nss/lib/pki/pkibase.c index 4082a37bd..f58a262cf 100644 --- a/security/nss/lib/pki/pkibase.c +++ b/security/nss/lib/pki/pkibase.c @@ -923,9 +923,11 @@ nssPKIObjectCollection_AddInstanceAsObject( return PR_FAILURE; } if (!node->haveObject) { + nssPKIObject *original = node->object; node->object = (*collection->createObject)(node->object); if (!node->object) { /*remove bogus object from list*/ + nssPKIObject_Destroy(original); nssPKIObjectCollection_RemoveNode(collection, node); return PR_FAILURE; } diff --git a/security/nss/lib/smime/cmsdecode.c b/security/nss/lib/smime/cmsdecode.c index d96511171..62b4ebfe5 100644 --- a/security/nss/lib/smime/cmsdecode.c +++ b/security/nss/lib/smime/cmsdecode.c @@ -87,8 +87,7 @@ nss_cms_decoder_notify(void *arg, PRBool before, void *dest, int depth) /* XXX error handling: need to set p7dcx->error */ #ifdef CMSDEBUG - fprintf(stderr, "%6.6s, dest = 0x%08x, depth = %d\n", before ? "before" - : "after", + fprintf(stderr, "%6.6s, dest = 0x%08x, depth = %d\n", before ? "before" : "after", dest, depth); #endif diff --git a/security/nss/lib/smime/cmsencode.c b/security/nss/lib/smime/cmsencode.c index a4414e008..0d723e865 100644 --- a/security/nss/lib/smime/cmsencode.c +++ b/security/nss/lib/smime/cmsencode.c @@ -134,8 +134,7 @@ nss_cms_encoder_notify(void *arg, PRBool before, void *dest, int depth) rootcinfo = &(p7ecx->cmsg->contentInfo); #ifdef CMSDEBUG - fprintf(stderr, "%6.6s, dest = 0x%08x, depth = %d\n", before ? "before" - : "after", + fprintf(stderr, "%6.6s, dest = 0x%08x, depth = %d\n", before ? "before" : "after", dest, depth); #endif diff --git a/security/nss/lib/softoken/fipstest.c b/security/nss/lib/softoken/fipstest.c index 3563bd2d2..0cca74d6e 100644 --- a/security/nss/lib/softoken/fipstest.c +++ b/security/nss/lib/softoken/fipstest.c @@ -5,6 +5,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#ifndef NSS_FIPS_DISABLED #include "seccomon.h" #include "blapi.h" #include "softoken.h" @@ -652,3 +653,11 @@ sftk_FIPSEntryOK() } return CKR_OK; } +#else +#include "pkcs11t.h" +CK_RV +sftk_FIPSEntryOK() +{ + return CKR_DEVICE_ERROR; +} +#endif /* NSS_FIPS_DISABLED */ diff --git a/security/nss/lib/softoken/fipstokn.c b/security/nss/lib/softoken/fipstokn.c index fd4fd4207..ca7d7998a 100644 --- a/security/nss/lib/softoken/fipstokn.c +++ b/security/nss/lib/softoken/fipstokn.c @@ -540,7 +540,10 @@ FC_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo) crv = NSC_GetTokenInfo(slotID, pInfo); if (crv == CKR_OK) { - if ((pInfo->flags & CKF_LOGIN_REQUIRED) == 0) { + /* use the global database to figure out if we are running in + * FIPS 140 Level 1 or Level 2 */ + if (slotID == FIPS_SLOT_ID && + (pInfo->flags & CKF_LOGIN_REQUIRED) == 0) { isLevel2 = PR_FALSE; } } @@ -616,7 +619,8 @@ FC_InitPIN(CK_SESSION_HANDLE hSession, * we need to make sure the pin meets FIPS requirements */ if ((ulPinLen == 0) || ((rv = sftk_newPinCheck(pPin, ulPinLen)) == CKR_OK)) { rv = NSC_InitPIN(hSession, pPin, ulPinLen); - if (rv == CKR_OK) { + if ((rv == CKR_OK) && + (sftk_SlotIDFromSessionHandle(hSession) == FIPS_SLOT_ID)) { isLevel2 = (ulPinLen > 0) ? PR_TRUE : PR_FALSE; } } @@ -644,7 +648,8 @@ FC_SetPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin, if ((rv = sftk_fipsCheck()) == CKR_OK && (rv = sftk_newPinCheck(pNewPin, usNewLen)) == CKR_OK) { rv = NSC_SetPIN(hSession, pOldPin, usOldLen, pNewPin, usNewLen); - if (rv == CKR_OK) { + if ((rv == CKR_OK) && + (sftk_SlotIDFromSessionHandle(hSession) == FIPS_SLOT_ID)) { /* if we set the password in level1 we now go * to level2. NOTE: we don't allow the user to * go from level2 to level1 */ @@ -705,11 +710,23 @@ FC_GetSessionInfo(CK_SESSION_HANDLE hSession, rv = NSC_GetSessionInfo(hSession, pInfo); if (rv == CKR_OK) { - if ((isLoggedIn) && (pInfo->state == CKS_RO_PUBLIC_SESSION)) { - pInfo->state = CKS_RO_USER_FUNCTIONS; - } - if ((isLoggedIn) && (pInfo->state == CKS_RW_PUBLIC_SESSION)) { - pInfo->state = CKS_RW_USER_FUNCTIONS; + /* handle the case where the auxilary slot doesn't require login. + * piggy back on the main token's login state */ + if (isLoggedIn && + ((pInfo->state == CKS_RO_PUBLIC_SESSION) || + (pInfo->state == CKS_RW_PUBLIC_SESSION))) { + CK_RV crv; + CK_TOKEN_INFO tInfo; + crv = NSC_GetTokenInfo(sftk_SlotIDFromSessionHandle(hSession), + &tInfo); + /* if the token doesn't login, use our global login state */ + if ((crv == CKR_OK) && ((tInfo.flags & CKF_LOGIN_REQUIRED) == 0)) { + if (pInfo->state == CKS_RO_PUBLIC_SESSION) { + pInfo->state = CKS_RO_USER_FUNCTIONS; + } else { + pInfo->state = CKS_RW_USER_FUNCTIONS; + } + } } } return rv; diff --git a/security/nss/lib/softoken/legacydb/keydb.c b/security/nss/lib/softoken/legacydb/keydb.c index 178e333ec..b4aa7754b 100644 --- a/security/nss/lib/softoken/legacydb/keydb.c +++ b/security/nss/lib/softoken/legacydb/keydb.c @@ -1137,12 +1137,10 @@ nsslowkey_KeyForCertExists(NSSLOWKEYDBHandle *handle, NSSLOWCERTCertificate *cer namekey.data = pubkey->u.dh.publicValue.data; namekey.size = pubkey->u.dh.publicValue.len; break; -#ifndef NSS_DISABLE_ECC case NSSLOWKEYECKey: namekey.data = pubkey->u.ec.publicValue.data; namekey.size = pubkey->u.ec.publicValue.len; break; -#endif /* NSS_DISABLE_ECC */ default: /* XXX We don't do Fortezza or DH yet. */ return PR_FALSE; @@ -1467,12 +1465,10 @@ seckey_encrypt_private_key(PLArenaPool *permarena, NSSLOWKEYPrivateKey *pk, SECItem *der_item = NULL; SECItem *cipherText = NULL; SECItem *dummy = NULL; -#ifndef NSS_DISABLE_ECC #ifdef EC_DEBUG SECItem *fordebug = NULL; #endif int savelen; -#endif temparena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); if (temparena == NULL) @@ -1548,7 +1544,6 @@ seckey_encrypt_private_key(PLArenaPool *permarena, NSSLOWKEYPrivateKey *pk, goto loser; } break; -#ifndef NSS_DISABLE_ECC case NSSLOWKEYECKey: lg_prepare_low_ec_priv_key_for_asn1(pk); /* Public value is encoded as a bit string so adjust length @@ -1589,7 +1584,6 @@ seckey_encrypt_private_key(PLArenaPool *permarena, NSSLOWKEYPrivateKey *pk, #endif break; -#endif /* NSS_DISABLE_ECC */ default: /* We don't support DH or Fortezza private keys yet */ PORT_Assert(PR_FALSE); @@ -1809,7 +1803,6 @@ seckey_decrypt_private_key(SECItem *epki, lg_nsslowkey_DHPrivateKeyTemplate, &newPrivateKey); break; -#ifndef NSS_DISABLE_ECC case SEC_OID_ANSIX962_EC_PUBLIC_KEY: pk->keyType = NSSLOWKEYECKey; lg_prepare_low_ec_priv_key_for_asn1(pk); @@ -1849,7 +1842,6 @@ seckey_decrypt_private_key(SECItem *epki, } break; -#endif /* NSS_DISABLE_ECC */ default: rv = SECFailure; break; diff --git a/security/nss/lib/softoken/legacydb/lgattr.c b/security/nss/lib/softoken/legacydb/lgattr.c index 5c2cbdbc6..542b0c968 100644 --- a/security/nss/lib/softoken/legacydb/lgattr.c +++ b/security/nss/lib/softoken/legacydb/lgattr.c @@ -133,7 +133,7 @@ lg_CopyAttribute(CK_ATTRIBUTE *attr, CK_ATTRIBUTE_TYPE type, attr->ulValueLen = (CK_ULONG)-1; return CKR_BUFFER_TOO_SMALL; } - if (value != NULL) { + if (len > 0 && value != NULL) { PORT_Memcpy(attr->pValue, value, len); } attr->ulValueLen = len; @@ -421,11 +421,9 @@ lg_GetPubItem(NSSLOWKEYPublicKey *pubKey) case NSSLOWKEYDHKey: pubItem = &pubKey->u.dh.publicValue; break; -#ifndef NSS_DISABLE_ECC case NSSLOWKEYECKey: pubItem = &pubKey->u.ec.publicValue; break; -#endif /* NSS_DISABLE_ECC */ default: break; } @@ -544,7 +542,6 @@ lg_FindDHPublicKeyAttribute(NSSLOWKEYPublicKey *key, CK_ATTRIBUTE_TYPE type, return lg_invalidAttribute(attribute); } -#ifndef NSS_DISABLE_ECC static CK_RV lg_FindECPublicKeyAttribute(NSSLOWKEYPublicKey *key, CK_ATTRIBUTE_TYPE type, CK_ATTRIBUTE *attribute) @@ -594,7 +591,6 @@ lg_FindECPublicKeyAttribute(NSSLOWKEYPublicKey *key, CK_ATTRIBUTE_TYPE type, } return lg_invalidAttribute(attribute); } -#endif /* NSS_DISABLE_ECC */ static CK_RV lg_FindPublicKeyAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type, @@ -645,10 +641,8 @@ lg_FindPublicKeyAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type, return lg_FindDSAPublicKeyAttribute(key, type, attribute); case NSSLOWKEYDHKey: return lg_FindDHPublicKeyAttribute(key, type, attribute); -#ifndef NSS_DISABLE_ECC case NSSLOWKEYECKey: return lg_FindECPublicKeyAttribute(key, type, attribute); -#endif /* NSS_DISABLE_ECC */ default: break; } @@ -935,7 +929,6 @@ lg_FindDHPrivateKeyAttribute(NSSLOWKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type, return lg_invalidAttribute(attribute); } -#ifndef NSS_DISABLE_ECC static CK_RV lg_FindECPrivateKeyAttribute(NSSLOWKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type, CK_ATTRIBUTE *attribute, SDB *sdbpw) @@ -973,7 +966,6 @@ lg_FindECPrivateKeyAttribute(NSSLOWKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type, } return lg_invalidAttribute(attribute); } -#endif /* NSS_DISABLE_ECC */ static CK_RV lg_FindPrivateKeyAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type, @@ -1020,10 +1012,8 @@ lg_FindPrivateKeyAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type, return lg_FindDSAPrivateKeyAttribute(key, type, attribute, obj->sdb); case NSSLOWKEYDHKey: return lg_FindDHPrivateKeyAttribute(key, type, attribute, obj->sdb); -#ifndef NSS_DISABLE_ECC case NSSLOWKEYECKey: return lg_FindECPrivateKeyAttribute(key, type, attribute, obj->sdb); -#endif /* NSS_DISABLE_ECC */ default: break; } diff --git a/security/nss/lib/softoken/legacydb/lgcreate.c b/security/nss/lib/softoken/legacydb/lgcreate.c index a0d2b2e57..f2b2aa634 100644 --- a/security/nss/lib/softoken/legacydb/lgcreate.c +++ b/security/nss/lib/softoken/legacydb/lgcreate.c @@ -398,21 +398,17 @@ lg_createPublicKeyObject(SDB *sdb, CK_KEY_TYPE key_type, NSSLOWKEYPrivateKey *priv; SECItem pubKeySpace = { siBuffer, NULL, 0 }; SECItem *pubKey; -#ifndef NSS_DISABLE_ECC SECItem pubKey2Space = { siBuffer, NULL, 0 }; PLArenaPool *arena = NULL; -#endif /* NSS_DISABLE_ECC */ NSSLOWKEYDBHandle *keyHandle = NULL; switch (key_type) { case CKK_RSA: pubKeyAttr = CKA_MODULUS; break; -#ifndef NSS_DISABLE_ECC case CKK_EC: pubKeyAttr = CKA_EC_POINT; break; -#endif /* NSS_DISABLE_ECC */ case CKK_DSA: case CKK_DH: break; @@ -425,7 +421,6 @@ lg_createPublicKeyObject(SDB *sdb, CK_KEY_TYPE key_type, if (crv != CKR_OK) return crv; -#ifndef NSS_DISABLE_ECC if (key_type == CKK_EC) { SECStatus rv; /* @@ -448,7 +443,6 @@ lg_createPublicKeyObject(SDB *sdb, CK_KEY_TYPE key_type, pubKey = &pubKey2Space; } } -#endif /* NSS_DISABLE_ECC */ PORT_Assert(pubKey->data); if (pubKey->data == NULL) { @@ -469,14 +463,12 @@ lg_createPublicKeyObject(SDB *sdb, CK_KEY_TYPE key_type, /* make sure the associated private key already exists */ /* only works if we are logged in */ priv = nsslowkey_FindKeyByPublicKey(keyHandle, pubKey, sdb /*password*/); -#ifndef NSS_DISABLE_ECC if (priv == NULL && pubKey == &pubKey2Space) { /* no match on the decoded key, match the original pubkey */ pubKey = &pubKeySpace; priv = nsslowkey_FindKeyByPublicKey(keyHandle, pubKey, sdb /*password*/); } -#endif if (priv == NULL) { /* the legacy database can only 'store' public keys which already * have their corresponding private keys in the database */ @@ -490,10 +482,9 @@ lg_createPublicKeyObject(SDB *sdb, CK_KEY_TYPE key_type, done: PORT_Free(pubKeySpace.data); -#ifndef NSS_DISABLE_ECC - if (arena) + if (arena) { PORT_FreeArena(arena, PR_FALSE); -#endif + } return crv; } @@ -613,7 +604,6 @@ lg_mkPrivKey(SDB *sdb, const CK_ATTRIBUTE *templ, CK_ULONG count, } break; -#ifndef NSS_DISABLE_ECC case CKK_EC: privKey->keyType = NSSLOWKEYECKey; crv = lg_Attribute2SSecItem(arena, CKA_EC_PARAMS, templ, count, @@ -646,7 +636,6 @@ lg_mkPrivKey(SDB *sdb, const CK_ATTRIBUTE *templ, CK_ULONG count, if (rv != SECSuccess) crv = CKR_HOST_MEMORY; break; -#endif /* NSS_DISABLE_ECC */ default: crv = CKR_KEY_TYPE_INCONSISTENT; diff --git a/security/nss/lib/softoken/legacydb/lgfips.c b/security/nss/lib/softoken/legacydb/lgfips.c index b017424db..b991dcf8e 100644 --- a/security/nss/lib/softoken/legacydb/lgfips.c +++ b/security/nss/lib/softoken/legacydb/lgfips.c @@ -6,6 +6,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* $Id: fipstest.c,v 1.31 2012/06/28 17:55:06 rrelyea%redhat.com Exp $ */ +#ifndef NSS_FIPS_DISABLED + #include "seccomon.h" #include "lgdb.h" #include "blapi.h" @@ -113,3 +115,5 @@ lg_FIPSEntryOK() #endif return lg_self_tests_success; } + +#endif /* NSS_FIPS_DISABLED */ diff --git a/security/nss/lib/softoken/legacydb/lginit.c b/security/nss/lib/softoken/legacydb/lginit.c index 6913eea50..4f0b53f52 100644 --- a/security/nss/lib/softoken/legacydb/lginit.c +++ b/security/nss/lib/softoken/legacydb/lginit.c @@ -586,11 +586,15 @@ legacy_Open(const char *configdir, const char *certPrefix, #define NSS_VERSION_VARIABLE __nss_dbm_version #include "verref.h" +#ifndef NSS_FIPS_DISABLED if (flags & SDB_FIPS) { + /* We shouldn't get here when FIPS is not enabled on the database. But + * we also don't care when this NSS build doesn't support FIPS. */ if (!lg_FIPSEntryOK()) { return CKR_DEVICE_ERROR; } } +#endif rv = SECOID_Init(); if (SECSuccess != rv) { diff --git a/security/nss/lib/softoken/legacydb/lowcert.c b/security/nss/lib/softoken/legacydb/lowcert.c index 2906120ee..5a349f0aa 100644 --- a/security/nss/lib/softoken/legacydb/lowcert.c +++ b/security/nss/lib/softoken/legacydb/lowcert.c @@ -823,7 +823,6 @@ nsslowcert_ExtractPublicKey(NSSLOWCERTCertificate *cert) if (rv == SECSuccess) return pubk; break; -#ifndef NSS_DISABLE_ECC case SEC_OID_ANSIX962_EC_PUBLIC_KEY: pubk->keyType = NSSLOWKEYECKey; /* Since PKCS#11 directly takes the DER encoding of EC params @@ -845,7 +844,6 @@ nsslowcert_ExtractPublicKey(NSSLOWCERTCertificate *cert) if (rv == SECSuccess) return pubk; break; -#endif /* NSS_DISABLE_ECC */ default: rv = SECFailure; break; diff --git a/security/nss/lib/softoken/legacydb/lowkey.c b/security/nss/lib/softoken/legacydb/lowkey.c index 7de4197a1..a9b7cce3d 100644 --- a/security/nss/lib/softoken/legacydb/lowkey.c +++ b/security/nss/lib/softoken/legacydb/lowkey.c @@ -99,8 +99,6 @@ const SEC_ASN1Template lg_nsslowkey_DHPrivateKeyTemplate[] = { { 0 } }; -#ifndef NSS_DISABLE_ECC - /* NOTE: The SECG specification allows the private key structure * to contain curve parameters but recommends that they be stored * in the PrivateKeyAlgorithmIdentifier field of the PrivateKeyInfo @@ -193,7 +191,6 @@ LGEC_CopyParams(PLArenaPool *arena, ECParams *dstParams, loser: return SECFailure; } -#endif /* NSS_DISABLE_ECC */ /* * See bugzilla bug 125359 * Since NSS (via PKCS#11) wants to handle big integers as unsigned ints, @@ -243,7 +240,6 @@ lg_prepare_low_dh_priv_key_for_asn1(NSSLOWKEYPrivateKey *key) key->u.dh.privateValue.type = siUnsignedInteger; } -#ifndef NSS_DISABLE_ECC void lg_prepare_low_ecparams_for_asn1(ECParams *params) { @@ -260,7 +256,6 @@ lg_prepare_low_ec_priv_key_for_asn1(NSSLOWKEYPrivateKey *key) key->u.ec.privateValue.type = siUnsignedInteger; key->u.ec.publicValue.type = siUnsignedInteger; } -#endif /* NSS_DISABLE_ECC */ void lg_nsslowkey_DestroyPrivateKey(NSSLOWKEYPrivateKey *privk) @@ -362,7 +357,6 @@ lg_nsslowkey_ConvertToPublicKey(NSSLOWKEYPrivateKey *privk) return pubk; } break; -#ifndef NSS_DISABLE_ECC case NSSLOWKEYECKey: pubk = (NSSLOWKEYPublicKey *)PORT_ArenaZAlloc(arena, sizeof(NSSLOWKEYPublicKey)); @@ -383,7 +377,6 @@ lg_nsslowkey_ConvertToPublicKey(NSSLOWKEYPrivateKey *privk) return pubk; } break; -#endif /* NSS_DISABLE_ECC */ /* No Fortezza in Low Key implementations (Fortezza keys aren't * stored in our data base */ default: diff --git a/security/nss/lib/softoken/legacydb/lowkeyi.h b/security/nss/lib/softoken/legacydb/lowkeyi.h index 5136b56a5..4a5bcfa91 100644 --- a/security/nss/lib/softoken/legacydb/lowkeyi.h +++ b/security/nss/lib/softoken/legacydb/lowkeyi.h @@ -26,10 +26,8 @@ extern void lg_prepare_low_rsa_priv_key_for_asn1(NSSLOWKEYPrivateKey *key); extern void lg_prepare_low_pqg_params_for_asn1(PQGParams *params); extern void lg_prepare_low_dsa_priv_key_for_asn1(NSSLOWKEYPrivateKey *key); extern void lg_prepare_low_dh_priv_key_for_asn1(NSSLOWKEYPrivateKey *key); -#ifndef NSS_DISABLE_ECC extern void lg_prepare_low_ec_priv_key_for_asn1(NSSLOWKEYPrivateKey *key); extern void lg_prepare_low_ecparams_for_asn1(ECParams *params); -#endif /* NSS_DISABLE_ECC */ typedef char *(*NSSLOWKEYDBNameFunc)(void *arg, int dbVersion); @@ -134,7 +132,6 @@ extern char * nsslowkey_FindKeyNicknameByPublicKey(NSSLOWKEYDBHandle *handle, SECItem *modulus, SDB *sdb); -#ifndef NSS_DISABLE_ECC /* * smaller version of EC_FillParams. In this code, we only need * oid and DER data. @@ -145,7 +142,7 @@ SECStatus LGEC_FillParams(PLArenaPool *arena, const SECItem *encodedParams, /* Copy all of the fields from srcParams into dstParams */ SECStatus LGEC_CopyParams(PLArenaPool *arena, ECParams *dstParams, const ECParams *srcParams); -#endif + SEC_END_PROTOS #endif /* _LOWKEYI_H_ */ diff --git a/security/nss/lib/softoken/legacydb/lowkeyti.h b/security/nss/lib/softoken/legacydb/lowkeyti.h index ef92689e0..2fd5d4e29 100644 --- a/security/nss/lib/softoken/legacydb/lowkeyti.h +++ b/security/nss/lib/softoken/legacydb/lowkeyti.h @@ -42,10 +42,8 @@ extern const SEC_ASN1Template lg_nsslowkey_RSAPrivateKeyTemplate2[]; extern const SEC_ASN1Template lg_nsslowkey_DSAPrivateKeyTemplate[]; extern const SEC_ASN1Template lg_nsslowkey_DHPrivateKeyTemplate[]; extern const SEC_ASN1Template lg_nsslowkey_DHPrivateKeyExportTemplate[]; -#ifndef NSS_DISABLE_ECC #define NSSLOWKEY_EC_PRIVATE_KEY_VERSION 1 /* as per SECG 1 C.4 */ extern const SEC_ASN1Template lg_nsslowkey_ECPrivateKeyTemplate[]; -#endif /* NSS_DISABLE_ECC */ extern const SEC_ASN1Template lg_nsslowkey_PrivateKeyInfoTemplate[]; extern const SEC_ASN1Template nsslowkey_EncryptedPrivateKeyInfoTemplate[]; diff --git a/security/nss/lib/softoken/legacydb/pcertdb.c b/security/nss/lib/softoken/legacydb/pcertdb.c index f1444bf04..2e8b650ee 100644 --- a/security/nss/lib/softoken/legacydb/pcertdb.c +++ b/security/nss/lib/softoken/legacydb/pcertdb.c @@ -1854,6 +1854,8 @@ DecodeDBSMimeEntry(certDBEntrySMime *entry, SECItem *dbentry, char *emailAddr) &dbentry->data[DB_SMIME_ENTRY_HEADER_LEN + entry->subjectName.len], entry->smimeOptions.len); + } else { + entry->smimeOptions.data = NULL; } if (entry->optionsDate.len) { entry->optionsDate.data = @@ -1868,6 +1870,8 @@ DecodeDBSMimeEntry(certDBEntrySMime *entry, SECItem *dbentry, char *emailAddr) entry->subjectName.len + entry->smimeOptions.len], entry->optionsDate.len); + } else { + entry->optionsDate.data = NULL; } /* both options and options date must either exist or not exist */ @@ -2014,7 +2018,7 @@ nsslowcert_ReadDBSMimeEntry(NSSLOWCERTCertDBHandle *handle, char *emailAddr) { PLArenaPool *arena = NULL; PLArenaPool *tmparena = NULL; - certDBEntrySMime *entry; + certDBEntrySMime *entry = NULL; SECItem dbkey; SECItem dbentry; SECStatus rv; @@ -2031,8 +2035,8 @@ nsslowcert_ReadDBSMimeEntry(NSSLOWCERTCertDBHandle *handle, char *emailAddr) goto loser; } - entry = (certDBEntrySMime *)PORT_ArenaAlloc(arena, - sizeof(certDBEntrySMime)); + entry = (certDBEntrySMime *)PORT_ArenaZAlloc(arena, + sizeof(certDBEntrySMime)); if (entry == NULL) { PORT_SetError(SEC_ERROR_NO_MEMORY); goto loser; diff --git a/security/nss/lib/softoken/lowkey.c b/security/nss/lib/softoken/lowkey.c index 73b1dc971..295d55f40 100644 --- a/security/nss/lib/softoken/lowkey.c +++ b/security/nss/lib/softoken/lowkey.c @@ -8,10 +8,7 @@ #include "base64.h" #include "secasn1.h" #include "secerr.h" - -#ifndef NSS_DISABLE_ECC #include "softoken.h" -#endif SEC_ASN1_MKSUB(SEC_AnyTemplate) SEC_ASN1_MKSUB(SEC_BitStringTemplate) @@ -90,8 +87,6 @@ const SEC_ASN1Template nsslowkey_DHPrivateKeyTemplate[] = { { 0 } }; -#ifndef NSS_DISABLE_ECC - /* NOTE: The SECG specification allows the private key structure * to contain curve parameters but recommends that they be stored * in the PrivateKeyAlgorithmIdentifier field of the PrivateKeyInfo @@ -117,7 +112,6 @@ const SEC_ASN1Template nsslowkey_ECPrivateKeyTemplate[] = { SEC_ASN1_SUB(SEC_BitStringTemplate) }, { 0 } }; -#endif /* NSS_DISABLE_ECC */ /* * See bugzilla bug 125359 * Since NSS (via PKCS#11) wants to handle big integers as unsigned ints, @@ -173,7 +167,6 @@ prepare_low_dh_priv_key_for_asn1(NSSLOWKEYPrivateKey *key) key->u.dh.privateValue.type = siUnsignedInteger; } -#ifndef NSS_DISABLE_ECC void prepare_low_ecparams_for_asn1(ECParams *params) { @@ -190,7 +183,6 @@ prepare_low_ec_priv_key_for_asn1(NSSLOWKEYPrivateKey *key) key->u.ec.privateValue.type = siUnsignedInteger; key->u.ec.publicValue.type = siUnsignedInteger; } -#endif /* NSS_DISABLE_ECC */ void nsslowkey_DestroyPrivateKey(NSSLOWKEYPrivateKey *privk) @@ -325,7 +317,6 @@ nsslowkey_ConvertToPublicKey(NSSLOWKEYPrivateKey *privk) return pubk; } break; -#ifndef NSS_DISABLE_ECC case NSSLOWKEYECKey: pubk = (NSSLOWKEYPublicKey *)PORT_ArenaZAlloc(arena, sizeof(NSSLOWKEYPublicKey)); @@ -346,7 +337,6 @@ nsslowkey_ConvertToPublicKey(NSSLOWKEYPrivateKey *privk) return pubk; } break; -#endif /* NSS_DISABLE_ECC */ /* No Fortezza in Low Key implementations (Fortezza keys aren't * stored in our data base */ default: @@ -463,7 +453,6 @@ nsslowkey_CopyPrivateKey(NSSLOWKEYPrivateKey *privKey) if (rv != SECSuccess) break; break; -#ifndef NSS_DISABLE_ECC case NSSLOWKEYECKey: rv = SECITEM_CopyItem(poolp, &(returnKey->u.ec.version), &(privKey->u.ec.version)); @@ -484,7 +473,6 @@ nsslowkey_CopyPrivateKey(NSSLOWKEYPrivateKey *privKey) if (rv != SECSuccess) break; break; -#endif /* NSS_DISABLE_ECC */ default: rv = SECFailure; } diff --git a/security/nss/lib/softoken/lowkeyi.h b/security/nss/lib/softoken/lowkeyi.h index a5878c2f6..f9ba3a75f 100644 --- a/security/nss/lib/softoken/lowkeyi.h +++ b/security/nss/lib/softoken/lowkeyi.h @@ -25,10 +25,8 @@ extern void prepare_low_pqg_params_for_asn1(PQGParams *params); extern void prepare_low_dsa_priv_key_for_asn1(NSSLOWKEYPrivateKey *key); extern void prepare_low_dsa_priv_key_export_for_asn1(NSSLOWKEYPrivateKey *key); extern void prepare_low_dh_priv_key_for_asn1(NSSLOWKEYPrivateKey *key); -#ifndef NSS_DISABLE_ECC extern void prepare_low_ec_priv_key_for_asn1(NSSLOWKEYPrivateKey *key); extern void prepare_low_ecparams_for_asn1(ECParams *params); -#endif /* NSS_DISABLE_ECC */ /* ** Destroy a private key object. diff --git a/security/nss/lib/softoken/lowkeyti.h b/security/nss/lib/softoken/lowkeyti.h index 2ef16405f..c048b33e7 100644 --- a/security/nss/lib/softoken/lowkeyti.h +++ b/security/nss/lib/softoken/lowkeyti.h @@ -20,10 +20,8 @@ extern const SEC_ASN1Template nsslowkey_DSAPrivateKeyTemplate[]; extern const SEC_ASN1Template nsslowkey_DSAPrivateKeyExportTemplate[]; extern const SEC_ASN1Template nsslowkey_DHPrivateKeyTemplate[]; extern const SEC_ASN1Template nsslowkey_DHPrivateKeyExportTemplate[]; -#ifndef NSS_DISABLE_ECC #define NSSLOWKEY_EC_PRIVATE_KEY_VERSION 1 /* as per SECG 1 C.4 */ extern const SEC_ASN1Template nsslowkey_ECPrivateKeyTemplate[]; -#endif /* NSS_DISABLE_ECC */ extern const SEC_ASN1Template nsslowkey_PrivateKeyInfoTemplate[]; extern const SEC_ASN1Template nsslowkey_EncryptedPrivateKeyInfoTemplate[]; diff --git a/security/nss/lib/softoken/pkcs11.c b/security/nss/lib/softoken/pkcs11.c index a594fd501..77882a274 100644 --- a/security/nss/lib/softoken/pkcs11.c +++ b/security/nss/lib/softoken/pkcs11.c @@ -282,13 +282,11 @@ static const struct mechanismList mechanisms[] = { /* no diffie hellman yet */ { CKM_DH_PKCS_KEY_PAIR_GEN, { DH_MIN_P_BITS, DH_MAX_P_BITS, CKF_GENERATE_KEY_PAIR }, PR_TRUE }, { CKM_DH_PKCS_DERIVE, { DH_MIN_P_BITS, DH_MAX_P_BITS, CKF_DERIVE }, PR_TRUE }, -#ifndef NSS_DISABLE_ECC /* -------------------- Elliptic Curve Operations --------------------- */ { CKM_EC_KEY_PAIR_GEN, { EC_MIN_KEY_BITS, EC_MAX_KEY_BITS, CKF_GENERATE_KEY_PAIR | CKF_EC_BPNU }, PR_TRUE }, { CKM_ECDH1_DERIVE, { EC_MIN_KEY_BITS, EC_MAX_KEY_BITS, CKF_DERIVE | CKF_EC_BPNU }, PR_TRUE }, { CKM_ECDSA, { EC_MIN_KEY_BITS, EC_MAX_KEY_BITS, CKF_SN_VR | CKF_EC_BPNU }, PR_TRUE }, { CKM_ECDSA_SHA1, { EC_MIN_KEY_BITS, EC_MAX_KEY_BITS, CKF_SN_VR | CKF_EC_BPNU }, PR_TRUE }, -#endif /* NSS_DISABLE_ECC */ /* ------------------------- RC2 Operations --------------------------- */ { CKM_RC2_KEY_GEN, { 1, 128, CKF_GENERATE }, PR_TRUE }, { CKM_RC2_ECB, { 1, 128, CKF_EN_DE_WR_UN }, PR_TRUE }, @@ -423,11 +421,20 @@ static const struct mechanismList mechanisms[] = { #endif /* --------------------- Secret Key Operations ------------------------ */ { CKM_GENERIC_SECRET_KEY_GEN, { 1, 32, CKF_GENERATE }, PR_TRUE }, - { CKM_CONCATENATE_BASE_AND_KEY, { 1, 32, CKF_GENERATE }, PR_FALSE }, - { CKM_CONCATENATE_BASE_AND_DATA, { 1, 32, CKF_GENERATE }, PR_FALSE }, - { CKM_CONCATENATE_DATA_AND_BASE, { 1, 32, CKF_GENERATE }, PR_FALSE }, - { CKM_XOR_BASE_AND_DATA, { 1, 32, CKF_GENERATE }, PR_FALSE }, + { CKM_CONCATENATE_BASE_AND_KEY, { 1, 32, CKF_DERIVE }, PR_FALSE }, + { CKM_CONCATENATE_BASE_AND_DATA, { 1, 32, CKF_DERIVE }, PR_FALSE }, + { CKM_CONCATENATE_DATA_AND_BASE, { 1, 32, CKF_DERIVE }, PR_FALSE }, + { CKM_XOR_BASE_AND_DATA, { 1, 32, CKF_DERIVE }, PR_FALSE }, { CKM_EXTRACT_KEY_FROM_KEY, { 1, 32, CKF_DERIVE }, PR_FALSE }, + { CKM_DES3_ECB_ENCRYPT_DATA, { 1, 32, CKF_DERIVE }, PR_FALSE }, + { CKM_DES3_CBC_ENCRYPT_DATA, { 1, 32, CKF_DERIVE }, PR_FALSE }, + { CKM_AES_ECB_ENCRYPT_DATA, { 1, 32, CKF_DERIVE }, PR_FALSE }, + { CKM_AES_CBC_ENCRYPT_DATA, { 1, 32, CKF_DERIVE }, PR_FALSE }, + { CKM_CAMELLIA_ECB_ENCRYPT_DATA, { 1, 32, CKF_DERIVE }, PR_FALSE }, + { CKM_CAMELLIA_CBC_ENCRYPT_DATA, { 1, 32, CKF_DERIVE }, PR_FALSE }, + { CKM_SEED_ECB_ENCRYPT_DATA, { 1, 32, CKF_DERIVE }, PR_FALSE }, + { CKM_SEED_CBC_ENCRYPT_DATA, { 1, 32, CKF_DERIVE }, PR_FALSE }, + /* ---------------------- SSL Key Derivations ------------------------- */ { CKM_SSL3_PRE_MASTER_KEY_GEN, { 48, 48, CKF_GENERATE }, PR_FALSE }, { CKM_SSL3_MASTER_KEY_DERIVE, { 48, 48, CKF_DERIVE }, PR_FALSE }, @@ -931,7 +938,6 @@ sftk_handlePublicKeyObject(SFTKSession *session, SFTKObject *object, recover = CK_FALSE; wrap = CK_FALSE; break; -#ifndef NSS_DISABLE_ECC case CKK_EC: if (!sftk_hasAttribute(object, CKA_EC_PARAMS)) { return CKR_TEMPLATE_INCOMPLETE; @@ -945,7 +951,6 @@ sftk_handlePublicKeyObject(SFTKSession *session, SFTKObject *object, recover = CK_FALSE; wrap = CK_FALSE; break; -#endif /* NSS_DISABLE_ECC */ default: return CKR_ATTRIBUTE_VALUE_INVALID; } @@ -1114,7 +1119,6 @@ sftk_handlePrivateKeyObject(SFTKSession *session, SFTKObject *object, CK_KEY_TYP recover = CK_FALSE; wrap = CK_FALSE; break; -#ifndef NSS_DISABLE_ECC case CKK_EC: if (!sftk_hasAttribute(object, CKA_EC_PARAMS)) { return CKR_TEMPLATE_INCOMPLETE; @@ -1127,7 +1131,6 @@ sftk_handlePrivateKeyObject(SFTKSession *session, SFTKObject *object, CK_KEY_TYP recover = CK_FALSE; wrap = CK_FALSE; break; -#endif /* NSS_DISABLE_ECC */ case CKK_NSS_JPAKE_ROUND1: if (!sftk_hasAttribute(object, CKA_PRIME) || !sftk_hasAttribute(object, CKA_SUBPRIME) || @@ -1778,7 +1781,6 @@ sftk_GetPubKey(SFTKObject *object, CK_KEY_TYPE key_type, crv = sftk_Attribute2SSecItem(arena, &pubKey->u.dh.publicValue, object, CKA_VALUE); break; -#ifndef NSS_DISABLE_ECC case CKK_EC: pubKey->keyType = NSSLOWKEYECKey; crv = sftk_Attribute2SSecItem(arena, @@ -1837,7 +1839,6 @@ sftk_GetPubKey(SFTKObject *object, CK_KEY_TYPE key_type, crv = CKR_ATTRIBUTE_VALUE_INVALID; } break; -#endif /* NSS_DISABLE_ECC */ default: crv = CKR_KEY_TYPE_INCONSISTENT; break; @@ -1947,7 +1948,6 @@ sftk_mkPrivKey(SFTKObject *object, CK_KEY_TYPE key_type, CK_RV *crvp) * if we don't set it explicitly */ break; -#ifndef NSS_DISABLE_ECC case CKK_EC: privKey->keyType = NSSLOWKEYECKey; crv = sftk_Attribute2SSecItem(arena, @@ -1992,7 +1992,6 @@ sftk_mkPrivKey(SFTKObject *object, CK_KEY_TYPE key_type, CK_RV *crvp) #endif } break; -#endif /* NSS_DISABLE_ECC */ default: crv = CKR_KEY_TYPE_INCONSISTENT; @@ -2365,17 +2364,22 @@ sftk_SlotFromID(CK_SLOT_ID slotID, PRBool all) return slot; } -SFTKSlot * -sftk_SlotFromSessionHandle(CK_SESSION_HANDLE handle) +CK_SLOT_ID +sftk_SlotIDFromSessionHandle(CK_SESSION_HANDLE handle) { CK_ULONG slotIDIndex = (handle >> 24) & 0x7f; CK_ULONG moduleIndex = (handle >> 31) & 1; if (slotIDIndex >= nscSlotCount[moduleIndex]) { - return NULL; + return (CK_SLOT_ID)-1; } + return nscSlotList[moduleIndex][slotIDIndex]; +} - return sftk_SlotFromID(nscSlotList[moduleIndex][slotIDIndex], PR_FALSE); +SFTKSlot * +sftk_SlotFromSessionHandle(CK_SESSION_HANDLE handle) +{ + return sftk_SlotFromID(sftk_SlotIDFromSessionHandle(handle), PR_FALSE); } static CK_RV @@ -3305,6 +3309,15 @@ NSC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) } } + /* If there is no key database, this is for example the case when NSS was + * initialized with NSS_NoDbInit(), then there won't be any point in + * requesting a PIN. Set the CKF_USER_PIN_INITIALIZED bit so that + * PK11_NeedUserInit() doesn't indicate that a PIN is needed. + */ + if (slot->keyDB == NULL) { + pInfo->flags |= CKF_USER_PIN_INITIALIZED; + } + /* ok we really should read it out of the keydb file. */ /* pInfo->hardwareVersion.major = NSSLOWKEY_DB_FILE_VERSION; */ pInfo->hardwareVersion.major = SOFTOKEN_VMAJOR; @@ -3566,7 +3579,6 @@ NSC_InitToken(CK_SLOT_ID slotID, CK_CHAR_PTR pPin, { SFTKSlot *slot = sftk_SlotFromID(slotID, PR_FALSE); SFTKDBHandle *handle; - SFTKDBHandle *certHandle; SECStatus rv; unsigned int i; SFTKObject *object; @@ -3614,19 +3626,16 @@ NSC_InitToken(CK_SLOT_ID slotID, CK_CHAR_PTR pPin, } rv = sftkdb_ResetKeyDB(handle); + /* clear the password */ + sftkdb_ClearPassword(handle); + /* update slot->needLogin (should be true now since no password is set) */ + sftk_checkNeedLogin(slot, handle); sftk_freeDB(handle); if (rv != SECSuccess) { return CKR_DEVICE_ERROR; } - /* finally mark all the user certs as non-user certs */ - certHandle = sftk_getCertDB(slot); - if (certHandle == NULL) - return CKR_OK; - - sftk_freeDB(certHandle); - - return CKR_OK; /*is this the right function for not implemented*/ + return CKR_OK; } /* NSC_InitPIN initializes the normal user's PIN. */ @@ -3792,7 +3801,10 @@ NSC_SetPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin, /* Now update our local copy of the pin */ if (rv == SECSuccess) { + PZ_Lock(slot->slotLock); slot->needLogin = (PRBool)(ulNewLen != 0); + slot->isLoggedIn = (PRBool)(sftkdb_PWCached(handle) == SECSuccess); + PZ_Unlock(slot->slotLock); /* Reset login flags. */ if (ulNewLen == 0) { PRBool tokenRemoved = PR_FALSE; diff --git a/security/nss/lib/softoken/pkcs11c.c b/security/nss/lib/softoken/pkcs11c.c index 0234aa431..d675d7331 100644 --- a/security/nss/lib/softoken/pkcs11c.c +++ b/security/nss/lib/softoken/pkcs11c.c @@ -65,7 +65,6 @@ sftk_Null(void *data, PRBool freeit) return; } -#ifndef NSS_DISABLE_ECC #ifdef EC_DEBUG #define SEC_PRINT(str1, str2, num, sitem) \ printf("pkcs11c.c:%s:%s (keytype=%d) [len=%d]\n", \ @@ -78,7 +77,6 @@ sftk_Null(void *data, PRBool freeit) #undef EC_DEBUG #define SEC_PRINT(a, b, c, d) #endif -#endif /* NSS_DISABLE_ECC */ /* * free routines.... Free local type allocated data, and convert @@ -124,7 +122,6 @@ sftk_MapCryptError(int error) return CKR_KEY_SIZE_RANGE; /* the closest error code */ case SEC_ERROR_UNSUPPORTED_EC_POINT_FORM: return CKR_TEMPLATE_INCONSISTENT; - /* EC functions set this error if NSS_DISABLE_ECC is defined */ case SEC_ERROR_UNSUPPORTED_KEYALG: return CKR_MECHANISM_INVALID; case SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE: @@ -1527,8 +1524,7 @@ NSC_DecryptUpdate(CK_SESSION_HANDLE hSession, maxout -= padoutlen; } /* now save the final block for the next decrypt or the final */ - PORT_Memcpy(context->padBuf, &pEncryptedPart[ulEncryptedPartLen - - context->blockSize], + PORT_Memcpy(context->padBuf, &pEncryptedPart[ulEncryptedPartLen - context->blockSize], context->blockSize); context->padDataLength = context->blockSize; ulEncryptedPartLen -= context->padDataLength; @@ -2417,7 +2413,6 @@ nsc_DSA_Sign_Stub(void *ctx, void *sigBuf, return rv; } -#ifndef NSS_DISABLE_ECC static SECStatus nsc_ECDSAVerifyStub(void *ctx, void *sigBuf, unsigned int sigLen, void *dataBuf, unsigned int dataLen) @@ -2452,7 +2447,6 @@ nsc_ECDSASignStub(void *ctx, void *sigBuf, *sigLen = signature.len; return rv; } -#endif /* NSS_DISABLE_ECC */ /* NSC_SignInit setups up the signing operations. There are three basic * types of signing: @@ -2612,7 +2606,6 @@ NSC_SignInit(CK_SESSION_HANDLE hSession, break; -#ifndef NSS_DISABLE_ECC case CKM_ECDSA_SHA1: context->multi = PR_TRUE; crv = sftk_doSubSHA1(context); @@ -2635,7 +2628,6 @@ NSC_SignInit(CK_SESSION_HANDLE hSession, context->maxLen = MAX_ECKEY_LEN * 2; break; -#endif /* NSS_DISABLE_ECC */ #define INIT_HMAC_MECH(mmm) \ case CKM_##mmm##_HMAC_GENERAL: \ @@ -3303,7 +3295,6 @@ NSC_VerifyInit(CK_SESSION_HANDLE hSession, context->verify = (SFTKVerify)nsc_DSA_Verify_Stub; context->destroy = sftk_Null; break; -#ifndef NSS_DISABLE_ECC case CKM_ECDSA_SHA1: context->multi = PR_TRUE; crv = sftk_doSubSHA1(context); @@ -3324,7 +3315,6 @@ NSC_VerifyInit(CK_SESSION_HANDLE hSession, context->verify = (SFTKVerify)nsc_ECDSAVerifyStub; context->destroy = sftk_Null; break; -#endif /* NSS_DISABLE_ECC */ INIT_HMAC_MECH(MD2) INIT_HMAC_MECH(MD5) @@ -4624,12 +4614,10 @@ sftk_PairwiseConsistencyCheck(CK_SESSION_HANDLE hSession, pairwise_digest_length = subPrimeLen; mech.mechanism = CKM_DSA; break; -#ifndef NSS_DISABLE_ECC case CKK_EC: signature_length = MAX_ECKEY_LEN * 2; mech.mechanism = CKM_ECDSA; break; -#endif default: return CKR_DEVICE_ERROR; } @@ -4746,12 +4734,10 @@ NSC_GenerateKeyPair(CK_SESSION_HANDLE hSession, /* Diffie Hellman */ DHPrivateKey *dhPriv; -#ifndef NSS_DISABLE_ECC /* Elliptic Curve Cryptography */ SECItem ecEncodedParams; /* DER Encoded parameters */ ECPrivateKey *ecPriv; ECParams *ecParams; -#endif /* NSS_DISABLE_ECC */ CHECK_FORK(); @@ -5097,7 +5083,6 @@ NSC_GenerateKeyPair(CK_SESSION_HANDLE hSession, PORT_FreeArena(dhPriv->arena, PR_TRUE); break; -#ifndef NSS_DISABLE_ECC case CKM_EC_KEY_PAIR_GEN: sftk_DeleteAttributeType(privateKey, CKA_EC_PARAMS); sftk_DeleteAttributeType(privateKey, CKA_VALUE); @@ -5166,7 +5151,6 @@ NSC_GenerateKeyPair(CK_SESSION_HANDLE hSession, /* should zeroize, since this function doesn't. */ PORT_FreeArena(ecPriv->ecParams.arena, PR_TRUE); break; -#endif /* NSS_DISABLE_ECC */ default: crv = CKR_MECHANISM_INVALID; @@ -5296,12 +5280,10 @@ sftk_PackagePrivateKey(SFTKObject *key, CK_RV *crvp) void *dummy, *param = NULL; SECStatus rv = SECSuccess; SECItem *encodedKey = NULL; -#ifndef NSS_DISABLE_ECC #ifdef EC_DEBUG SECItem *fordebug; #endif int savelen; -#endif if (!key) { *crvp = CKR_KEY_HANDLE_INVALID; /* really can't happen */ @@ -5353,7 +5335,6 @@ sftk_PackagePrivateKey(SFTKObject *key, CK_RV *crvp) nsslowkey_PQGParamsTemplate); algorithm = SEC_OID_ANSIX9_DSA_SIGNATURE; break; -#ifndef NSS_DISABLE_ECC case NSSLOWKEYECKey: prepare_low_ec_priv_key_for_asn1(lk); /* Public value is encoded as a bit string so adjust length @@ -5382,7 +5363,6 @@ sftk_PackagePrivateKey(SFTKObject *key, CK_RV *crvp) algorithm = SEC_OID_ANSIX962_EC_PUBLIC_KEY; break; -#endif /* NSS_DISABLE_ECC */ case NSSLOWKEYDHKey: default: dummy = NULL; @@ -5641,8 +5621,7 @@ sftk_unwrapPrivateKey(SFTKObject *key, SECItem *bpki) prepare_low_dsa_priv_key_export_for_asn1(lpk); prepare_low_pqg_params_for_asn1(&lpk->u.dsa.params); break; -/* case NSSLOWKEYDHKey: */ -#ifndef NSS_DISABLE_ECC + /* case NSSLOWKEYDHKey: */ case SEC_OID_ANSIX962_EC_PUBLIC_KEY: keyTemplate = nsslowkey_ECPrivateKeyTemplate; paramTemplate = NULL; @@ -5651,7 +5630,6 @@ sftk_unwrapPrivateKey(SFTKObject *key, SECItem *bpki) prepare_low_ec_priv_key_for_asn1(lpk); prepare_low_ecparams_for_asn1(&lpk->u.ec.ecParams); break; -#endif /* NSS_DISABLE_ECC */ default: keyTemplate = NULL; paramTemplate = NULL; @@ -5666,7 +5644,6 @@ sftk_unwrapPrivateKey(SFTKObject *key, SECItem *bpki) /* decode the private key and any algorithm parameters */ rv = SEC_QuickDERDecodeItem(arena, lpk, keyTemplate, &pki->privateKey); -#ifndef NSS_DISABLE_ECC if (lpk->keyType == NSSLOWKEYECKey) { /* convert length in bits to length in bytes */ lpk->u.ec.publicValue.len >>= 3; @@ -5677,7 +5654,6 @@ sftk_unwrapPrivateKey(SFTKObject *key, SECItem *bpki) goto loser; } } -#endif /* NSS_DISABLE_ECC */ if (rv != SECSuccess) { goto loser; @@ -5790,8 +5766,7 @@ sftk_unwrapPrivateKey(SFTKObject *key, SECItem *bpki) keyType = CKK_DH; break; #endif -/* what about fortezza??? */ -#ifndef NSS_DISABLE_ECC + /* what about fortezza??? */ case NSSLOWKEYECKey: keyType = CKK_EC; crv = (sftk_hasAttribute(key, CKA_NETSCAPE_DB)) ? CKR_OK : CKR_KEY_TYPE_INCONSISTENT; @@ -5823,7 +5798,6 @@ sftk_unwrapPrivateKey(SFTKObject *key, SECItem *bpki) break; /* XXX Do we need to decode the EC Params here ?? */ break; -#endif /* NSS_DISABLE_ECC */ default: crv = CKR_KEY_TYPE_INCONSISTENT; break; @@ -6153,7 +6127,6 @@ sftk_MapKeySize(CK_KEY_TYPE keyType) return 0; } -#ifndef NSS_DISABLE_ECC /* Inputs: * key_len: Length of derived key to be generated. * SharedSecret: a shared secret that is the output of a key agreement primitive. @@ -6266,7 +6239,43 @@ sftk_ANSI_X9_63_kdf(CK_BYTE **key, CK_ULONG key_len, else return CKR_MECHANISM_INVALID; } -#endif /* NSS_DISABLE_ECC */ + +/* + * Handle the derive from a block encryption cipher + */ +CK_RV +sftk_DeriveEncrypt(SFTKCipher encrypt, void *cipherInfo, + int blockSize, SFTKObject *key, CK_ULONG keySize, + unsigned char *data, CK_ULONG len) +{ + /* large enough for a 512-bit key */ + unsigned char tmpdata[SFTK_MAX_DERIVE_KEY_SIZE]; + SECStatus rv; + unsigned int outLen; + CK_RV crv; + + if ((len % blockSize) != 0) { + return CKR_MECHANISM_PARAM_INVALID; + } + if (len > SFTK_MAX_DERIVE_KEY_SIZE) { + return CKR_MECHANISM_PARAM_INVALID; + } + if (keySize && (len < keySize)) { + return CKR_MECHANISM_PARAM_INVALID; + } + if (keySize == 0) { + keySize = len; + } + + rv = (*encrypt)(cipherInfo, &tmpdata, &outLen, len, data, len); + if (rv != SECSuccess) { + crv = sftk_MapCryptError(PORT_GetError()); + return crv; + } + + crv = sftk_forceAttribute(key, CKA_VALUE, tmpdata, keySize); + return crv; +} /* * SSL Key generation given pre master secret @@ -6926,6 +6935,172 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession, break; } + case CKM_DES3_ECB_ENCRYPT_DATA: + case CKM_DES3_CBC_ENCRYPT_DATA: { + void *cipherInfo; + unsigned char des3key[MAX_DES3_KEY_SIZE]; + CK_DES_CBC_ENCRYPT_DATA_PARAMS *desEncryptPtr; + int mode; + unsigned char *iv; + unsigned char *data; + CK_ULONG len; + + if (mechanism == CKM_DES3_ECB_ENCRYPT_DATA) { + stringPtr = (CK_KEY_DERIVATION_STRING_DATA *) + pMechanism->pParameter; + mode = NSS_DES_EDE3; + iv = NULL; + data = stringPtr->pData; + len = stringPtr->ulLen; + } else { + mode = NSS_DES_EDE3_CBC; + desEncryptPtr = + (CK_DES_CBC_ENCRYPT_DATA_PARAMS *) + pMechanism->pParameter; + iv = desEncryptPtr->iv; + data = desEncryptPtr->pData; + len = desEncryptPtr->length; + } + if (att->attrib.ulValueLen == 16) { + PORT_Memcpy(des3key, att->attrib.pValue, 16); + PORT_Memcpy(des3key + 16, des3key, 8); + } else if (att->attrib.ulValueLen == 24) { + PORT_Memcpy(des3key, att->attrib.pValue, 24); + } else { + crv = CKR_KEY_SIZE_RANGE; + break; + } + cipherInfo = DES_CreateContext(des3key, iv, mode, PR_TRUE); + PORT_Memset(des3key, 0, 24); + if (cipherInfo == NULL) { + crv = CKR_HOST_MEMORY; + break; + } + crv = sftk_DeriveEncrypt((SFTKCipher)DES_Encrypt, + cipherInfo, 8, key, keySize, + data, len); + DES_DestroyContext(cipherInfo, PR_TRUE); + break; + } + + case CKM_AES_ECB_ENCRYPT_DATA: + case CKM_AES_CBC_ENCRYPT_DATA: { + void *cipherInfo; + CK_AES_CBC_ENCRYPT_DATA_PARAMS *aesEncryptPtr; + int mode; + unsigned char *iv; + unsigned char *data; + CK_ULONG len; + + if (mechanism == CKM_AES_ECB_ENCRYPT_DATA) { + mode = NSS_AES; + iv = NULL; + stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)pMechanism->pParameter; + data = stringPtr->pData; + len = stringPtr->ulLen; + } else { + aesEncryptPtr = + (CK_AES_CBC_ENCRYPT_DATA_PARAMS *)pMechanism->pParameter; + mode = NSS_AES_CBC; + iv = aesEncryptPtr->iv; + data = aesEncryptPtr->pData; + len = aesEncryptPtr->length; + } + + cipherInfo = AES_CreateContext((unsigned char *)att->attrib.pValue, + iv, mode, PR_TRUE, + att->attrib.ulValueLen, 16); + if (cipherInfo == NULL) { + crv = CKR_HOST_MEMORY; + break; + } + crv = sftk_DeriveEncrypt((SFTKCipher)AES_Encrypt, + cipherInfo, 16, key, keySize, + data, len); + AES_DestroyContext(cipherInfo, PR_TRUE); + break; + } + + case CKM_CAMELLIA_ECB_ENCRYPT_DATA: + case CKM_CAMELLIA_CBC_ENCRYPT_DATA: { + void *cipherInfo; + CK_AES_CBC_ENCRYPT_DATA_PARAMS *aesEncryptPtr; + int mode; + unsigned char *iv; + unsigned char *data; + CK_ULONG len; + + if (mechanism == CKM_CAMELLIA_ECB_ENCRYPT_DATA) { + stringPtr = (CK_KEY_DERIVATION_STRING_DATA *) + pMechanism->pParameter; + aesEncryptPtr = NULL; + mode = NSS_CAMELLIA; + data = stringPtr->pData; + len = stringPtr->ulLen; + iv = NULL; + } else { + stringPtr = NULL; + aesEncryptPtr = (CK_AES_CBC_ENCRYPT_DATA_PARAMS *) + pMechanism->pParameter; + mode = NSS_CAMELLIA_CBC; + iv = aesEncryptPtr->iv; + data = aesEncryptPtr->pData; + len = aesEncryptPtr->length; + } + + cipherInfo = Camellia_CreateContext((unsigned char *)att->attrib.pValue, + iv, mode, PR_TRUE, + att->attrib.ulValueLen); + if (cipherInfo == NULL) { + crv = CKR_HOST_MEMORY; + break; + } + crv = sftk_DeriveEncrypt((SFTKCipher)Camellia_Encrypt, + cipherInfo, 16, key, keySize, + data, len); + Camellia_DestroyContext(cipherInfo, PR_TRUE); + break; + } + + case CKM_SEED_ECB_ENCRYPT_DATA: + case CKM_SEED_CBC_ENCRYPT_DATA: { + void *cipherInfo; + CK_AES_CBC_ENCRYPT_DATA_PARAMS *aesEncryptPtr; + int mode; + unsigned char *iv; + unsigned char *data; + CK_ULONG len; + + if (mechanism == CKM_SEED_ECB_ENCRYPT_DATA) { + mode = NSS_SEED; + stringPtr = (CK_KEY_DERIVATION_STRING_DATA *) + pMechanism->pParameter; + aesEncryptPtr = NULL; + data = stringPtr->pData; + len = stringPtr->ulLen; + iv = NULL; + } else { + mode = NSS_SEED_CBC; + aesEncryptPtr = (CK_AES_CBC_ENCRYPT_DATA_PARAMS *) + pMechanism->pParameter; + iv = aesEncryptPtr->iv; + data = aesEncryptPtr->pData; + len = aesEncryptPtr->length; + } + + cipherInfo = SEED_CreateContext((unsigned char *)att->attrib.pValue, + iv, mode, PR_TRUE); + if (cipherInfo == NULL) { + crv = CKR_HOST_MEMORY; + break; + } + crv = sftk_DeriveEncrypt((SFTKCipher)SEED_Encrypt, + cipherInfo, 16, key, keySize, + data, len); + SEED_DestroyContext(cipherInfo, PR_TRUE); + break; + } + case CKM_CONCATENATE_BASE_AND_KEY: { SFTKObject *newKey; @@ -7242,7 +7417,6 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession, break; } -#ifndef NSS_DISABLE_ECC case CKM_ECDH1_DERIVE: case CKM_ECDH1_COFACTOR_DERIVE: { SECItem ecScalar, ecPoint; @@ -7382,7 +7556,6 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession, } break; } -#endif /* NSS_DISABLE_ECC */ /* See RFC 5869 and CK_NSS_HKDFParams for documentation. */ case CKM_NSS_HKDF_SHA1: diff --git a/security/nss/lib/softoken/pkcs11i.h b/security/nss/lib/softoken/pkcs11i.h index c5f21c30a..7e57dc5e5 100644 --- a/security/nss/lib/softoken/pkcs11i.h +++ b/security/nss/lib/softoken/pkcs11i.h @@ -667,6 +667,7 @@ extern CK_RV sftk_handleObject(SFTKObject *object, SFTKSession *session); extern SFTKSlot *sftk_SlotFromID(CK_SLOT_ID slotID, PRBool all); extern SFTKSlot *sftk_SlotFromSessionHandle(CK_SESSION_HANDLE handle); +extern CK_SLOT_ID sftk_SlotIDFromSessionHandle(CK_SESSION_HANDLE handle); extern SFTKSession *sftk_SessionFromHandle(CK_SESSION_HANDLE handle); extern void sftk_FreeSession(SFTKSession *session); extern SFTKSession *sftk_NewSession(CK_SLOT_ID slotID, CK_NOTIFY notify, diff --git a/security/nss/lib/softoken/pkcs11u.c b/security/nss/lib/softoken/pkcs11u.c index c51211b6c..27e411759 100644 --- a/security/nss/lib/softoken/pkcs11u.c +++ b/security/nss/lib/softoken/pkcs11u.c @@ -1261,13 +1261,11 @@ static const CK_ATTRIBUTE_TYPE dhPubKeyAttrs[] = { }; static const CK_ULONG dhPubKeyAttrsCount = sizeof(dhPubKeyAttrs) / sizeof(dhPubKeyAttrs[0]); -#ifndef NSS_DISABLE_ECC static const CK_ATTRIBUTE_TYPE ecPubKeyAttrs[] = { CKA_EC_PARAMS, CKA_EC_POINT }; static const CK_ULONG ecPubKeyAttrsCount = sizeof(ecPubKeyAttrs) / sizeof(ecPubKeyAttrs[0]); -#endif static const CK_ATTRIBUTE_TYPE commonPrivKeyAttrs[] = { CKA_DECRYPT, CKA_SIGN, CKA_SIGN_RECOVER, CKA_UNWRAP, CKA_SUBJECT, @@ -1294,13 +1292,11 @@ static const CK_ATTRIBUTE_TYPE dhPrivKeyAttrs[] = { }; static const CK_ULONG dhPrivKeyAttrsCount = sizeof(dhPrivKeyAttrs) / sizeof(dhPrivKeyAttrs[0]); -#ifndef NSS_DISABLE_ECC static const CK_ATTRIBUTE_TYPE ecPrivKeyAttrs[] = { CKA_EC_PARAMS, CKA_VALUE }; static const CK_ULONG ecPrivKeyAttrsCount = sizeof(ecPrivKeyAttrs) / sizeof(ecPrivKeyAttrs[0]); -#endif static const CK_ATTRIBUTE_TYPE certAttrs[] = { CKA_CERTIFICATE_TYPE, CKA_VALUE, CKA_SUBJECT, CKA_ISSUER, CKA_SERIAL_NUMBER @@ -1405,12 +1401,10 @@ stfk_CopyTokenPrivateKey(SFTKObject *destObject, SFTKTokenObject *src_to) crv = stfk_CopyTokenAttributes(destObject, src_to, dhPrivKeyAttrs, dhPrivKeyAttrsCount); break; -#ifndef NSS_DISABLE_ECC case CKK_EC: crv = stfk_CopyTokenAttributes(destObject, src_to, ecPrivKeyAttrs, ecPrivKeyAttrsCount); break; -#endif default: crv = CKR_DEVICE_ERROR; /* shouldn't happen unless we store more types * of token keys into our database. */ @@ -1467,12 +1461,10 @@ stfk_CopyTokenPublicKey(SFTKObject *destObject, SFTKTokenObject *src_to) crv = stfk_CopyTokenAttributes(destObject, src_to, dhPubKeyAttrs, dhPubKeyAttrsCount); break; -#ifndef NSS_DISABLE_ECC case CKK_EC: crv = stfk_CopyTokenAttributes(destObject, src_to, ecPubKeyAttrs, ecPubKeyAttrsCount); break; -#endif default: crv = CKR_DEVICE_ERROR; /* shouldn't happen unless we store more types * of token keys into our database. */ diff --git a/security/nss/lib/softoken/sdb.c b/security/nss/lib/softoken/sdb.c index 8690df34c..96717cb26 100644 --- a/security/nss/lib/softoken/sdb.c +++ b/security/nss/lib/softoken/sdb.c @@ -37,6 +37,7 @@ #elif defined(XP_UNIX) #include <unistd.h> #endif +#include "utilpars.h" #ifdef SQLITE_UNSAFE_THREADS #include "prlock.h" @@ -190,6 +191,34 @@ sdb_done(int err, int *count) return 0; } +#if defined(_WIN32) +/* + * NSPR functions and narrow CRT functions do not handle UTF-8 file paths that + * sqlite3 expects. + */ + +static int +sdb_chmod(const char *filename, int pmode) +{ + int result; + + if (!filename) { + return -1; + } + + wchar_t *filenameWide = _NSSUTIL_UTF8ToWide(filename); + if (!filenameWide) { + return -1; + } + result = _wchmod(filenameWide, pmode); + PORT_Free(filenameWide); + + return result; +} +#else +#define sdb_chmod(filename, pmode) chmod((filename), (pmode)) +#endif + /* * find out where sqlite stores the temp tables. We do this by replicating * the logic from sqlite. @@ -1600,7 +1629,7 @@ loser: return error; } -static const char RESET_CMD[] = "DROP TABLE IF EXISTS %s;"; +static const char RESET_CMD[] = "DELETE FROM %s;"; CK_RV sdb_Reset(SDB *sdb) { @@ -1621,17 +1650,19 @@ sdb_Reset(SDB *sdb) goto loser; } - /* delete the key table */ - newStr = sqlite3_mprintf(RESET_CMD, sdb_p->table); - if (newStr == NULL) { - error = CKR_HOST_MEMORY; - goto loser; - } - sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL); - sqlite3_free(newStr); + if (tableExists(sqlDB, sdb_p->table)) { + /* delete the contents of the key table */ + newStr = sqlite3_mprintf(RESET_CMD, sdb_p->table); + if (newStr == NULL) { + error = CKR_HOST_MEMORY; + goto loser; + } + sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL); + sqlite3_free(newStr); - if (sqlerr != SQLITE_OK) - goto loser; + if (sqlerr != SQLITE_OK) + goto loser; + } /* delete the password entry table */ sqlerr = sqlite3_exec(sqlDB, "DROP TABLE IF EXISTS metaData;", @@ -1737,7 +1768,7 @@ sdb_init(char *dbname, char *table, sdbDataType type, int *inUpdate, * sqlite3 will always create it. */ LOCK_SQLITE(); - create = (PR_Access(dbname, PR_ACCESS_EXISTS) != PR_SUCCESS); + create = (_NSSUTIL_Access(dbname, PR_ACCESS_EXISTS) != PR_SUCCESS); if ((flags == SDB_RDONLY) && create) { error = sdb_mapSQLError(type, SQLITE_CANTOPEN); goto loser; @@ -1754,7 +1785,7 @@ sdb_init(char *dbname, char *table, sdbDataType type, int *inUpdate, * * NO NSPR call for chmod? :( */ - if (create && chmod(dbname, 0600) != 0) { + if (create && sdb_chmod(dbname, 0600) != 0) { error = sdb_mapSQLError(type, SQLITE_CANTOPEN); goto loser; } @@ -1866,30 +1897,29 @@ sdb_init(char *dbname, char *table, sdbDataType type, int *inUpdate, * so we use it for the cache (see sdb_buildCache for how it's done).*/ /* - * we decide whether or not to use the cache based on the following input. - * - * NSS_SDB_USE_CACHE environment variable is non-existant or set to - * anything other than "no" or "yes" ("auto", for instance). - * This is the normal case. NSS will measure the performance of access - * to the temp database versus the access to the users passed in - * database location. If the temp database location is "significantly" - * faster we will use the cache. - * - * NSS_SDB_USE_CACHE environment variable is set to "no": cache will not - * be used. - * - * NSS_SDB_USE_CACHE environment variable is set to "yes": cache will - * always be used. - * - * It is expected that most applications would use the "auto" selection, - * the environment variable is primarily to simplify testing, and to - * correct potential corner cases where */ + * we decide whether or not to use the cache based on the following input. + * + * NSS_SDB_USE_CACHE environment variable is set to anything other than + * "yes" or "no" (for instance, "auto"): NSS will measure the performance + * of access to the temp database versus the access to the user's + * passed-in database location. If the temp database location is + * "significantly" faster we will use the cache. + * + * NSS_SDB_USE_CACHE environment variable is nonexistent or set to "no": + * cache will not be used. + * + * NSS_SDB_USE_CACHE environment variable is set to "yes": cache will + * always be used. + * + * It is expected that most applications will not need this feature, and + * thus it is disabled by default. + */ env = PR_GetEnvSecure("NSS_SDB_USE_CACHE"); - if (env && PORT_Strcasecmp(env, "no") == 0) { + if (!env || PORT_Strcasecmp(env, "no") == 0) { enableCache = PR_FALSE; - } else if (env && PORT_Strcasecmp(env, "yes") == 0) { + } else if (PORT_Strcasecmp(env, "yes") == 0) { enableCache = PR_TRUE; } else { char *tempDir = NULL; @@ -2035,10 +2065,11 @@ s_open(const char *directory, const char *certPrefix, const char *keyPrefix, { char *env; env = PR_GetEnvSecure("NSS_SDB_USE_CACHE"); - /* If the environment variable is set to yes or no, sdb_init() will - * ignore the value of accessOps, and we can skip the measuring.*/ - if (!env || ((PORT_Strcasecmp(env, "no") != 0) && - (PORT_Strcasecmp(env, "yes") != 0))) { + /* If the environment variable is undefined or set to yes or no, + * sdb_init() will ignore the value of accessOps, and we can skip the + * measuring.*/ + if (env && PORT_Strcasecmp(env, "no") != 0 && + PORT_Strcasecmp(env, "yes") != 0) { accessOps = sdb_measureAccess(directory); } } diff --git a/security/nss/lib/softoken/sdb.h b/security/nss/lib/softoken/sdb.h index 04b873e02..8ff254bf7 100644 --- a/security/nss/lib/softoken/sdb.h +++ b/security/nss/lib/softoken/sdb.h @@ -83,6 +83,10 @@ CK_RV s_open(const char *directory, const char *certPrefix, int flags, SDB **certdb, SDB **keydb, int *newInit); CK_RV s_shutdown(); +#if defined(_WIN32) +wchar_t *sdb_UTF8ToWide(const char *buf); +#endif + /* flags */ #define SDB_RDONLY 1 #define SDB_RDWR 2 diff --git a/security/nss/lib/softoken/sftkdb.c b/security/nss/lib/softoken/sftkdb.c index 52e516117..2ae084068 100644 --- a/security/nss/lib/softoken/sftkdb.c +++ b/security/nss/lib/softoken/sftkdb.c @@ -28,6 +28,9 @@ #include "utilpars.h" #include "secerr.h" #include "softoken.h" +#if defined(_WIN32) +#include <windows.h> +#endif /* * We want all databases to have the same binary representation independent of @@ -40,7 +43,7 @@ */ #define BBP 8 -static PRBool +PRBool sftkdb_isULONGAttribute(CK_ATTRIBUTE_TYPE type) { switch (type) { @@ -1370,7 +1373,8 @@ sftkdb_SetAttributeValue(SFTKDBHandle *handle, SFTKObject *object, } /* make sure we don't have attributes that conflict with the existing DB */ - crv = sftkdb_checkConflicts(db, object->objclass, template, count, objectID); + crv = sftkdb_checkConflicts(db, object->objclass, ntemplate, count, + objectID); if (crv != CKR_OK) { goto loser; } @@ -1386,8 +1390,8 @@ sftkdb_SetAttributeValue(SFTKDBHandle *handle, SFTKObject *object, goto loser; } inTransaction = PR_TRUE; - crv = sftkdb_setAttributeValue(arena, handle, db, - objectID, template, count); + crv = sftkdb_setAttributeValue(arena, handle, db, objectID, ntemplate, + count); if (crv != CKR_OK) { goto loser; } @@ -2311,6 +2315,13 @@ loser: crv = (*handle->update->sdb_GetMetaData)(handle->update, "password", &item1, &item2); if (crv != CKR_OK) { + /* if we get here, neither the source, nor the target has been initialized + * with a password entry. Create a metadata table now so that we don't + * mistake this for a partially updated database */ + item1.data[0] = 0; + item2.data[0] = 0; + item1.len = item2.len = 1; + crv = (*handle->db->sdb_PutMetaData)(handle->db, "empty", &item1, &item2); goto done; } crv = (*handle->db->sdb_PutMetaData)(handle->db, "password", &item1, @@ -2501,6 +2512,53 @@ sftk_oldVersionExists(const char *dir, int version) return PR_FALSE; } +#if defined(_WIN32) +/* + * Convert an sdb path (encoded in UTF-8) to a legacy path (encoded in the + * current system codepage). Fails if the path contains a character outside + * the current system codepage. + */ +static char * +sftk_legacyPathFromSDBPath(const char *confdir) +{ + wchar_t *confdirWide; + DWORD size; + char *nconfdir; + BOOL unmappable; + + if (!confdir) { + return NULL; + } + confdirWide = _NSSUTIL_UTF8ToWide(confdir); + if (!confdirWide) { + return NULL; + } + + size = WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, confdirWide, -1, + NULL, 0, NULL, &unmappable); + if (size == 0 || unmappable) { + PORT_Free(confdirWide); + return NULL; + } + nconfdir = PORT_Alloc(sizeof(char) * size); + if (!nconfdir) { + PORT_Free(confdirWide); + return NULL; + } + size = WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, confdirWide, -1, + nconfdir, size, NULL, &unmappable); + PORT_Free(confdirWide); + if (size == 0 || unmappable) { + PORT_Free(nconfdir); + return NULL; + } + + return nconfdir; +} +#else +#define sftk_legacyPathFromSDBPath(confdir) PORT_Strdup((confdir)) +#endif + static PRBool sftk_hasLegacyDB(const char *confdir, const char *certPrefix, const char *keyPrefix, int certVersion, int keyVersion) @@ -2560,6 +2618,7 @@ sftk_DBInit(const char *configdir, const char *certPrefix, int flags = SDB_RDONLY; PRBool newInit = PR_FALSE; PRBool needUpdate = PR_FALSE; + char *nconfdir = NULL; if (!readOnly) { flags = SDB_CREATE; @@ -2598,11 +2657,14 @@ sftk_DBInit(const char *configdir, const char *certPrefix, * the exists. */ if (crv != CKR_OK) { - if (((flags & SDB_RDONLY) == SDB_RDONLY) && - sftk_hasLegacyDB(confdir, certPrefix, keyPrefix, 8, 3)) { + if ((flags & SDB_RDONLY) == SDB_RDONLY) { + nconfdir = sftk_legacyPathFromSDBPath(confdir); + } + if (nconfdir && + sftk_hasLegacyDB(nconfdir, certPrefix, keyPrefix, 8, 3)) { /* we have legacy databases, if we failed to open the new format * DB's read only, just use the legacy ones */ - crv = sftkdbCall_open(confdir, certPrefix, + crv = sftkdbCall_open(nconfdir, certPrefix, keyPrefix, 8, 3, flags, noCertDB ? NULL : &certSDB, noKeyDB ? NULL : &keySDB); } @@ -2631,7 +2693,10 @@ sftk_DBInit(const char *configdir, const char *certPrefix, /* if the new format DB was also a newly created DB, and we * succeeded, then need to update that new database with data * from the existing legacy DB */ - if (sftk_hasLegacyDB(confdir, certPrefix, keyPrefix, 8, 3)) { + nconfdir = sftk_legacyPathFromSDBPath(confdir); + if (nconfdir && + sftk_hasLegacyDB(nconfdir, certPrefix, keyPrefix, 8, 3)) { + confdir = nconfdir; needUpdate = PR_TRUE; } } @@ -2704,6 +2769,9 @@ done: if (appName) { PORT_Free(appName); } + if (nconfdir) { + PORT_Free(nconfdir); + } return forceOpen ? CKR_OK : crv; } diff --git a/security/nss/lib/softoken/sftkdbti.h b/security/nss/lib/softoken/sftkdbti.h index 4942e1b12..7b1db4560 100644 --- a/security/nss/lib/softoken/sftkdbti.h +++ b/security/nss/lib/softoken/sftkdbti.h @@ -49,6 +49,7 @@ SECStatus sftkdb_VerifyAttribute(SECItem *passKey, CK_ATTRIBUTE_TYPE attrType, SECItem *plainText, SECItem *sigText); +PRBool sftkdb_isULONGAttribute(CK_ATTRIBUTE_TYPE type); void sftk_ULong2SDBULong(unsigned char *data, CK_ULONG value); CK_RV sftkdb_Update(SFTKDBHandle *handle, SECItem *key); CK_RV sftkdb_PutAttributeSignature(SFTKDBHandle *handle, diff --git a/security/nss/lib/softoken/sftkpwd.c b/security/nss/lib/softoken/sftkpwd.c index 0b8c91bfd..e0d2df9ab 100644 --- a/security/nss/lib/softoken/sftkpwd.c +++ b/security/nss/lib/softoken/sftkpwd.c @@ -926,6 +926,13 @@ sftk_updateMacs(PLArenaPool *arena, SFTKDBHandle *handle, continue; } + if (authAttrs[i].ulValueLen == sizeof(CK_ULONG) && + sftkdb_isULONGAttribute(authAttrs[i].type)) { + CK_ULONG value = *(CK_ULONG *)authAttrs[i].pValue; + sftk_ULong2SDBULong(authAttrs[i].pValue, value); + authAttrs[i].ulValueLen = SDB_ULONG_SIZE; + } + plainText.data = authAttrs[i].pValue; plainText.len = authAttrs[i].ulValueLen; rv = sftkdb_SignAttribute(arena, newKey, id, diff --git a/security/nss/lib/softoken/softkver.h b/security/nss/lib/softoken/softkver.h index fb2e5bda5..f760ba21d 100644 --- a/security/nss/lib/softoken/softkver.h +++ b/security/nss/lib/softoken/softkver.h @@ -8,11 +8,7 @@ #ifndef _SOFTKVER_H_ #define _SOFTKVER_H_ -#ifndef NSS_DISABLE_ECC #define SOFTOKEN_ECC_STRING " Basic ECC" -#else -#define SOFTOKEN_ECC_STRING "" -#endif /* * Softoken's major version, minor version, patch level, build number, @@ -21,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.32.1" SOFTOKEN_ECC_STRING +#define SOFTOKEN_VERSION "3.36.4" SOFTOKEN_ECC_STRING #define SOFTOKEN_VMAJOR 3 -#define SOFTOKEN_VMINOR 32 -#define SOFTOKEN_VPATCH 1 +#define SOFTOKEN_VMINOR 36 +#define SOFTOKEN_VPATCH 4 #define SOFTOKEN_VBUILD 0 #define SOFTOKEN_BETA PR_FALSE diff --git a/security/nss/lib/softoken/softoknt.h b/security/nss/lib/softoken/softoknt.h index 071689842..03c92361c 100644 --- a/security/nss/lib/softoken/softoknt.h +++ b/security/nss/lib/softoken/softoknt.h @@ -9,6 +9,9 @@ #define _SOFTOKNT_H_ #define NSS_SOFTOKEN_DEFAULT_CHUNKSIZE 2048 +#define DES_BLOCK_SIZE 8 /* bytes */ +#define MAX_DES3_KEY_SIZE 24 /* DES_BLOCK_SIZE * 3 */ +#define SFTK_MAX_DERIVE_KEY_SIZE 64 /* * FIPS 140-2 auditing diff --git a/security/nss/lib/ssl/SSLerrs.h b/security/nss/lib/ssl/SSLerrs.h index b73fb6bd0..d3f087544 100644 --- a/security/nss/lib/ssl/SSLerrs.h +++ b/security/nss/lib/ssl/SSLerrs.h @@ -473,8 +473,7 @@ ER3(SSL_ERROR_RX_MALFORMED_PRE_SHARED_KEY, (SSL_ERROR_BASE + 147), ER3(SSL_ERROR_RX_MALFORMED_EARLY_DATA, (SSL_ERROR_BASE + 148), "SSL received an invalid EarlyData extension.") -ER3(SSL_ERROR_END_OF_EARLY_DATA_ALERT, (SSL_ERROR_BASE + 149), - "SSL received an unexpected end of early data alert.") +UNUSED_ERROR(149) ER3(SSL_ERROR_MISSING_ALPN_EXTENSION, (SSL_ERROR_BASE + 150), "SSL didn't receive an expected ALPN extension.") @@ -511,3 +510,36 @@ ER3(SSL_ERROR_DOWNGRADE_WITH_EARLY_DATA, (SSL_ERROR_BASE + 160), ER3(SSL_ERROR_TOO_MUCH_EARLY_DATA, (SSL_ERROR_BASE + 161), "SSL received more early data than permitted.") + +ER3(SSL_ERROR_RX_UNEXPECTED_END_OF_EARLY_DATA, (SSL_ERROR_BASE + 162), + "SSL received an unexpected End of Early Data message.") + +ER3(SSL_ERROR_RX_MALFORMED_END_OF_EARLY_DATA, (SSL_ERROR_BASE + 163), + "SSL received a malformed End of Early Data message.") + +ER3(SSL_ERROR_UNSUPPORTED_EXPERIMENTAL_API, (SSL_ERROR_BASE + 164), + "An experimental API was called, but not supported.") + +ER3(SSL_ERROR_APPLICATION_ABORT, (SSL_ERROR_BASE + 165), + "SSL handshake aborted by the application.") + +ER3(SSL_ERROR_APP_CALLBACK_ERROR, (SSL_ERROR_BASE + 166), + "An application callback produced an invalid response.") + +ER3(SSL_ERROR_NO_TIMERS_ERROR, (SSL_ERROR_BASE + 167), + "No timers are currently running.") + +ER3(SSL_ERROR_MISSING_COOKIE_EXTENSION, (SSL_ERROR_BASE + 168), + "A second ClientHello was received without a cookie extension.") + +ER3(SSL_ERROR_RX_UNEXPECTED_KEY_UPDATE, (SSL_ERROR_BASE + 169), + "SSL received an unexpected key update message.") + +ER3(SSL_ERROR_RX_MALFORMED_KEY_UPDATE, (SSL_ERROR_BASE + 170), + "SSL received a malformed key update message.") + +ER3(SSL_ERROR_TOO_MANY_KEY_UPDATES, (SSL_ERROR_BASE + 171), + "SSL attempted too many key updates.") + +ER3(SSL_ERROR_HANDSHAKE_FAILED, (SSL_ERROR_BASE + 172), + "SSL handshake has already failed. No more operations possible.") diff --git a/security/nss/lib/ssl/authcert.c b/security/nss/lib/ssl/authcert.c index 88c7c084a..2765c8342 100644 --- a/security/nss/lib/ssl/authcert.c +++ b/security/nss/lib/ssl/authcert.c @@ -17,6 +17,7 @@ #include "nss.h" #include "ssl.h" #include "pk11func.h" /* for PK11_ function calls */ +#include "sslimpl.h" /* * This callback used by SSL to pull client sertificate upon @@ -63,7 +64,7 @@ NSS_GetClientAuthData(void *arg, if (!cert) continue; /* Only check unexpired certs */ - if (CERT_CheckCertValidTimes(cert, PR_Now(), PR_TRUE) != + if (CERT_CheckCertValidTimes(cert, ssl_TimeUsec(), PR_TRUE) != secCertTimeValid) { CERT_DestroyCertificate(cert); continue; diff --git a/security/nss/lib/ssl/config.mk b/security/nss/lib/ssl/config.mk index c8b053cab..d13613f78 100644 --- a/security/nss/lib/ssl/config.mk +++ b/security/nss/lib/ssl/config.mk @@ -57,11 +57,6 @@ endif endif -ifdef NSS_SSL_ENABLE_ZLIB -DEFINES += -DNSS_SSL_ENABLE_ZLIB -include $(CORE_DEPTH)/coreconf/zlib.mk -endif - ifdef NSS_DISABLE_TLS_1_3 DEFINES += -DNSS_DISABLE_TLS_1_3 endif diff --git a/security/nss/lib/ssl/dtls13con.c b/security/nss/lib/ssl/dtls13con.c new file mode 100644 index 000000000..aba0f62ab --- /dev/null +++ b/security/nss/lib/ssl/dtls13con.c @@ -0,0 +1,457 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* 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/. */ + +/* + * DTLS 1.3 Protocol + */ + +#include "ssl.h" +#include "sslimpl.h" +#include "sslproto.h" + +/* 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 + * sender. We use the same structure on the receiver for convenience + * but the only value we actually use is |record|. + */ +typedef struct DTLSHandshakeRecordEntryStr { + PRCList link; + PRUint16 messageSeq; /* The handshake message sequence number. */ + PRUint32 offset; /* The offset into the handshake message. */ + PRUint32 length; /* The length of the fragment. */ + sslSequenceNumber record; /* The record (includes epoch). */ + PRBool acked; /* Has this packet been acked. */ +} DTLSHandshakeRecordEntry; + +/* Combine the epoch and sequence number into a single value. */ +static inline sslSequenceNumber +dtls_CombineSequenceNumber(DTLSEpoch epoch, sslSequenceNumber seqNum) +{ + PORT_Assert(seqNum <= RECORD_SEQ_MAX); + return ((sslSequenceNumber)epoch << 48) | seqNum; +} + +SECStatus +dtls13_RememberFragment(sslSocket *ss, + PRCList *list, + PRUint32 sequence, + PRUint32 offset, + PRUint32 length, + DTLSEpoch epoch, + sslSequenceNumber record) +{ + DTLSHandshakeRecordEntry *entry; + + PORT_Assert(IS_DTLS(ss)); + /* We should never send an empty fragment with offset > 0. */ + PORT_Assert(length || !offset); + + if (!tls13_MaybeTls13(ss)) { + return SECSuccess; + } + + SSL_TRC(20, ("%d: SSL3[%d]: %s remembering %s record=%llx msg=%d offset=%d", + SSL_GETPID(), ss->fd, + SSL_ROLE(ss), + list == &ss->ssl3.hs.dtlsSentHandshake ? "sent" : "received", + dtls_CombineSequenceNumber(epoch, record), sequence, offset)); + + entry = PORT_ZAlloc(sizeof(DTLSHandshakeRecordEntry)); + if (!entry) { + return SECFailure; + } + + entry->messageSeq = sequence; + entry->offset = offset; + entry->length = length; + entry->record = dtls_CombineSequenceNumber(epoch, record); + entry->acked = PR_FALSE; + + PR_APPEND_LINK(&entry->link, list); + + return SECSuccess; +} + +SECStatus +dtls13_SendAck(sslSocket *ss) +{ + sslBuffer buf = SSL_BUFFER_EMPTY; + SECStatus rv = SECSuccess; + PRCList *cursor; + PRInt32 sent; + + SSL_TRC(10, ("%d: SSL3[%d]: Sending ACK", + SSL_GETPID(), ss->fd)); + + for (cursor = PR_LIST_HEAD(&ss->ssl3.hs.dtlsRcvdHandshake); + cursor != &ss->ssl3.hs.dtlsRcvdHandshake; + cursor = PR_NEXT_LINK(cursor)) { + DTLSHandshakeRecordEntry *entry = (DTLSHandshakeRecordEntry *)cursor; + + SSL_TRC(10, ("%d: SSL3[%d]: ACK for record=%llx", + SSL_GETPID(), ss->fd, entry->record)); + rv = sslBuffer_AppendNumber(&buf, entry->record, 8); + if (rv != SECSuccess) { + goto loser; + } + } + + ssl_GetXmitBufLock(ss); + sent = ssl3_SendRecord(ss, NULL, content_ack, + buf.buf, buf.len, 0); + ssl_ReleaseXmitBufLock(ss); + if (sent != buf.len) { + rv = SECFailure; + if (sent != -1) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + } + } + +loser: + sslBuffer_Clear(&buf); + return rv; +} + +void +dtls13_SendAckCb(sslSocket *ss) +{ + if (!IS_DTLS(ss)) { + return; + } + (void)dtls13_SendAck(ss); +} + +/* Zero length messages are very simple to check. */ +static PRBool +dtls_IsEmptyMessageAcknowledged(sslSocket *ss, PRUint16 msgSeq, PRUint32 offset) +{ + PRCList *cursor; + + for (cursor = PR_LIST_HEAD(&ss->ssl3.hs.dtlsSentHandshake); + cursor != &ss->ssl3.hs.dtlsSentHandshake; + cursor = PR_NEXT_LINK(cursor)) { + DTLSHandshakeRecordEntry *entry = (DTLSHandshakeRecordEntry *)cursor; + if (!entry->acked || msgSeq != entry->messageSeq) { + continue; + } + /* Empty fragments are always offset 0. */ + if (entry->length == 0) { + PORT_Assert(!entry->offset); + return PR_TRUE; + } + } + return PR_FALSE; +} + +/* Take a range starting at |*start| and that start forwards based on the + * contents of the acknowedgement in |entry|. Only move if the acknowledged + * range overlaps |*start|. Return PR_TRUE if it moves. */ +static PRBool +dtls_MoveUnackedStartForward(DTLSHandshakeRecordEntry *entry, PRUint32 *start) +{ + /* This entry starts too late. */ + if (*start < entry->offset) { + return PR_FALSE; + } + /* This entry ends too early. */ + if (*start >= entry->offset + entry->length) { + return PR_FALSE; + } + *start = entry->offset + entry->length; + return PR_TRUE; +} + +/* Take a range ending at |*end| and move that end backwards based on the + * contents of the acknowedgement in |entry|. Only move if the acknowledged + * range overlaps |*end|. Return PR_TRUE if it moves. */ +static PRBool +dtls_MoveUnackedEndBackward(DTLSHandshakeRecordEntry *entry, PRUint32 *end) +{ + /* This entry ends too early. */ + if (*end > entry->offset + entry->length) { + return PR_FALSE; + } + /* This entry starts too late. */ + if (*end <= entry->offset) { + return PR_FALSE; + } + *end = entry->offset; + return PR_TRUE; +} + +/* Get the next contiguous range of unacknowledged bytes from the handshake + * message identified by |msgSeq|. The search starts at the offset in |offset|. + * |len| contains the full length of the message. + * + * Returns PR_TRUE if there is an unacknowledged range. In this case, values at + * |start| and |end| are modified to contain the range. + * + * Returns PR_FALSE if the message is entirely acknowledged from |offset| + * onwards. + */ +PRBool +dtls_NextUnackedRange(sslSocket *ss, PRUint16 msgSeq, PRUint32 offset, + PRUint32 len, PRUint32 *startOut, PRUint32 *endOut) +{ + PRCList *cur_p; + PRBool done = PR_FALSE; + DTLSHandshakeRecordEntry *entry; + PRUint32 start; + PRUint32 end; + + PORT_Assert(IS_DTLS(ss)); + + *startOut = offset; + *endOut = len; + if (!tls13_MaybeTls13(ss)) { + return PR_TRUE; + } + + /* The message is empty. Use a simple search. */ + if (!len) { + PORT_Assert(!offset); + return !dtls_IsEmptyMessageAcknowledged(ss, msgSeq, offset); + } + + /* This iterates multiple times over the acknowledgments and only terminates + * when an entire iteration happens without start or end moving. If that + * happens without start and end crossing each other, then there is a range + * of unacknowledged data. If they meet, then the message is fully + * acknowledged. */ + start = offset; + end = len; + while (!done) { + done = PR_TRUE; + for (cur_p = PR_LIST_HEAD(&ss->ssl3.hs.dtlsSentHandshake); + cur_p != &ss->ssl3.hs.dtlsSentHandshake; + cur_p = PR_NEXT_LINK(cur_p)) { + entry = (DTLSHandshakeRecordEntry *)cur_p; + if (!entry->acked || msgSeq != entry->messageSeq) { + continue; + } + + if (dtls_MoveUnackedStartForward(entry, &start) || + dtls_MoveUnackedEndBackward(entry, &end)) { + if (start >= end) { + /* The message is all acknowledged. */ + return PR_FALSE; + } + /* Start over again and keep going until we don't move either + * start or end. */ + done = PR_FALSE; + break; + } + } + } + PORT_Assert(start < end); + + *startOut = start; + *endOut = end; + return PR_TRUE; +} + +SECStatus +dtls13_SetupAcks(sslSocket *ss) +{ + if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) { + return SECSuccess; + } + + if (ss->ssl3.hs.endOfFlight) { + dtls_CancelTimer(ss, ss->ssl3.hs.ackTimer); + + if (ss->ssl3.hs.ws == idle_handshake && ss->sec.isServer) { + SSL_TRC(10, ("%d: SSL3[%d]: dtls_HandleHandshake, sending ACK", + SSL_GETPID(), ss->fd)); + return dtls13_SendAck(ss); + } + return SECSuccess; + } + + /* We need to send an ACK. */ + if (!ss->ssl3.hs.ackTimer->cb) { + /* We're not armed, so arm. */ + SSL_TRC(10, ("%d: SSL3[%d]: dtls_HandleHandshake, arming ack timer", + SSL_GETPID(), ss->fd)); + return dtls_StartTimer(ss, ss->ssl3.hs.ackTimer, + DTLS_RETRANSMIT_INITIAL_MS / 4, + dtls13_SendAckCb); + } + /* The ack timer is already armed, so just return. */ + return SECSuccess; +} + +/* + * Special case processing for out-of-epoch records. + * This can only handle ACKs for now and everything else generates + * an error. In future, may also handle KeyUpdate. + * + * The error checking here is as follows: + * + * - If it's not encrypted, out of epoch stuff is just discarded. + * - If it's encrypted, out of epoch stuff causes an error. + */ +SECStatus +dtls13_HandleOutOfEpochRecord(sslSocket *ss, const ssl3CipherSpec *spec, + SSL3ContentType rType, + sslBuffer *databuf) +{ + SECStatus rv; + sslBuffer buf = *databuf; + + databuf->len = 0; /* Discard data whatever happens. */ + PORT_Assert(IS_DTLS(ss)); + PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_TLS_1_3); + /* Can't happen, but double check. */ + if (!IS_DTLS(ss) || (ss->version < SSL_LIBRARY_VERSION_TLS_1_3)) { + tls13_FatalError(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error); + return SECFailure; + } + SSL_TRC(10, ("%d: DTLS13[%d]: handle out of epoch record: type=%d", SSL_GETPID(), + ss->fd, rType)); + + if (rType == content_ack) { + ssl_GetSSL3HandshakeLock(ss); + rv = dtls13_HandleAck(ss, &buf); + ssl_ReleaseSSL3HandshakeLock(ss); + PORT_Assert(databuf->len == 0); + return rv; + } + + switch (spec->epoch) { + case TrafficKeyClearText: + /* Drop. */ + return SECSuccess; + + case TrafficKeyHandshake: + /* Drop out of order handshake messages, but if we are the + * server, we might have processed the client's Finished and + * moved on to application data keys, but the client has + * retransmitted Finished (e.g., because our ACK got lost.) + * We just retransmit the previous Finished to let the client + * complete. */ + if (rType == content_handshake) { + if ((ss->sec.isServer) && + (ss->ssl3.hs.ws == idle_handshake)) { + PORT_Assert(dtls_TimerActive(ss, ss->ssl3.hs.hdTimer)); + return dtls13_SendAck(ss); + } + return SECSuccess; + } + + /* This isn't a handshake record, so shouldn't be encrypted + * under the handshake key. */ + break; + + default: + /* Any other epoch is forbidden. */ + break; + } + + SSL_TRC(10, ("%d: SSL3[%d]: unexpected out of epoch record type %d", SSL_GETPID(), + ss->fd, rType)); + + (void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter); + PORT_SetError(SSL_ERROR_RX_UNKNOWN_RECORD_TYPE); + return SECFailure; +} + +SECStatus +dtls13_HandleAck(sslSocket *ss, sslBuffer *databuf) +{ + PRUint8 *b = databuf->buf; + PRUint32 l = databuf->len; + SECStatus rv; + + /* Ensure we don't loop. */ + databuf->len = 0; + + PORT_Assert(IS_DTLS(ss)); + if (!tls13_MaybeTls13(ss)) { + tls13_FatalError(ss, SSL_ERROR_RX_UNKNOWN_RECORD_TYPE, illegal_parameter); + return SECSuccess; + } + + SSL_TRC(10, ("%d: SSL3[%d]: Handling ACK", SSL_GETPID(), ss->fd)); + while (l > 0) { + PRUint64 seq; + PRCList *cursor; + + rv = ssl3_ConsumeHandshakeNumber64(ss, &seq, 8, &b, &l); + if (rv != SECSuccess) { + return SECFailure; + } + + for (cursor = PR_LIST_HEAD(&ss->ssl3.hs.dtlsSentHandshake); + cursor != &ss->ssl3.hs.dtlsSentHandshake; + cursor = PR_NEXT_LINK(cursor)) { + DTLSHandshakeRecordEntry *entry = (DTLSHandshakeRecordEntry *)cursor; + + if (entry->record == seq) { + SSL_TRC(10, ( + "%d: SSL3[%d]: Marking record=%llx message %d offset %d length=%d as ACKed", + SSL_GETPID(), ss->fd, + seq, entry->messageSeq, entry->offset, entry->length)); + entry->acked = PR_TRUE; + } + } + } + + /* Try to flush. */ + rv = dtls_TransmitMessageFlight(ss); + if (rv != SECSuccess) { + return SECFailure; + } + + /* Reset the retransmit timer. */ + if (ss->ssl3.hs.rtTimer->cb) { + (void)dtls_RestartTimer(ss, ss->ssl3.hs.rtTimer); + } + + /* If there are no more messages to send, cleanup. */ + if (PR_CLIST_IS_EMPTY(&ss->ssl3.hs.lastMessageFlight)) { + SSL_TRC(10, ("%d: SSL3[%d]: No more unacked handshake messages", + SSL_GETPID(), ss->fd)); + + dtls_CancelTimer(ss, ss->ssl3.hs.rtTimer); + ssl_ClearPRCList(&ss->ssl3.hs.dtlsSentHandshake, NULL); + /* If the handshake is finished, and we're the client then + * also clean up the handshake read cipher spec. Any ACKs + * we receive will be with the application data cipher spec. + * The server needs to keep the handshake cipher spec around + * for the holddown period to process retransmitted Finisheds. + */ + if (!ss->sec.isServer && (ss->ssl3.hs.ws == idle_handshake)) { + ssl_CipherSpecReleaseByEpoch(ss, CipherSpecRead, + TrafficKeyHandshake); + } + } + return SECSuccess; +} + +/* Clean up the read timer for the handshake cipher suites on the + * server. + * + * In DTLS 1.3, the client speaks last (Finished), and will retransmit + * until the server ACKs that message (using application data cipher + * suites). I.e., + * + * - The client uses the retransmit timer and retransmits using the + * saved write handshake cipher suite. + * - The server keeps the saved read handshake cipher suite around + * for the holddown period in case it needs to read the Finished. + * + * After the holddown period, the server assumes the client is happy + * and discards the handshake read cipher suite. + */ +void +dtls13_HolddownTimerCb(sslSocket *ss) +{ + SSL_TRC(10, ("%d: SSL3[%d]: holddown timer fired", + SSL_GETPID(), ss->fd)); + ssl_CipherSpecReleaseByEpoch(ss, CipherSpecRead, TrafficKeyHandshake); + ssl_ClearPRCList(&ss->ssl3.hs.dtlsRcvdHandshake, NULL); +} diff --git a/security/nss/lib/ssl/dtls13con.h b/security/nss/lib/ssl/dtls13con.h new file mode 100644 index 000000000..bf14d3bd2 --- /dev/null +++ b/security/nss/lib/ssl/dtls13con.h @@ -0,0 +1,29 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is PRIVATE to SSL. + * + * 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 __dtls13con_h_ +#define __dtls13con_h_ + +SECStatus dtls13_RememberFragment(sslSocket *ss, PRCList *list, + PRUint32 sequence, PRUint32 offset, + PRUint32 length, DTLSEpoch epoch, + sslSequenceNumber record); +PRBool dtls_NextUnackedRange(sslSocket *ss, PRUint16 msgSeq, PRUint32 offset, + PRUint32 len, PRUint32 *startOut, PRUint32 *endOut); +SECStatus dtls13_SetupAcks(sslSocket *ss); +SECStatus dtls13_HandleOutOfEpochRecord(sslSocket *ss, const ssl3CipherSpec *spec, + SSL3ContentType rType, + sslBuffer *databuf); +SECStatus dtls13_HandleAck(sslSocket *ss, sslBuffer *databuf); + +SECStatus dtls13_SendAck(sslSocket *ss); +void dtls13_SendAckCb(sslSocket *ss); +void dtls13_HolddownTimerCb(sslSocket *ss); +void dtls_ReceivedFirstMessageInFlight(sslSocket *ss); + +#endif diff --git a/security/nss/lib/ssl/dtlscon.c b/security/nss/lib/ssl/dtlscon.c index fbd1779db..2f335f924 100644 --- a/security/nss/lib/ssl/dtlscon.c +++ b/security/nss/lib/ssl/dtlscon.c @@ -10,16 +10,17 @@ #include "ssl.h" #include "sslimpl.h" #include "sslproto.h" +#include "dtls13con.h" #ifndef PR_ARRAY_SIZE #define PR_ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) #endif -static SECStatus dtls_TransmitMessageFlight(sslSocket *ss); static SECStatus dtls_StartRetransmitTimer(sslSocket *ss); static void dtls_RetransmitTimerExpiredCb(sslSocket *ss); static SECStatus dtls_SendSavedWriteData(sslSocket *ss); static void dtls_FinishedTimerCb(sslSocket *ss); +static void dtls_CancelAllTimers(sslSocket *ss); /* -28 adjusts for the IP/UDP header */ static const PRUint16 COMMON_MTU_VALUES[] = { @@ -30,6 +31,9 @@ static const PRUint16 COMMON_MTU_VALUES[] = { }; #define DTLS_COOKIE_BYTES 32 +/* Maximum DTLS expansion = header + IV + max CBC padding + + * maximum MAC. */ +#define DTLS_MAX_EXPANSION (DTLS_RECORD_HEADER_LENGTH + 16 + 16 + 32) /* List copied from ssl3con.c:cipherSuites */ static const ssl3CipherSuite nonDTLSSuites[] = { @@ -119,9 +123,9 @@ static DTLSQueuedMessage * dtls_AllocQueuedMessage(ssl3CipherSpec *cwSpec, SSL3ContentType type, const unsigned char *data, PRUint32 len) { - DTLSQueuedMessage *msg = NULL; + DTLSQueuedMessage *msg; - msg = PORT_ZAlloc(sizeof(DTLSQueuedMessage)); + msg = PORT_ZNew(DTLSQueuedMessage); if (!msg) return NULL; @@ -137,7 +141,7 @@ dtls_AllocQueuedMessage(ssl3CipherSpec *cwSpec, SSL3ContentType type, msg->type = type; /* Safe if we are < 1.3, since the refct is * already very high. */ - tls13_CipherSpecAddRef(cwSpec); + ssl_CipherSpecAddRef(cwSpec); return msg; } @@ -155,7 +159,7 @@ dtls_FreeHandshakeMessage(DTLSQueuedMessage *msg) /* Safe if we are < 1.3, since the refct is * already very high. */ - tls13_CipherSpecRelease(msg->cwSpec); + ssl_CipherSpecRelease(msg->cwSpec); PORT_ZFree(msg->data, msg->len); PORT_Free(msg); } @@ -184,37 +188,38 @@ dtls_FreeHandshakeMessages(PRCList *list) static SECStatus dtls_RetransmitDetected(sslSocket *ss) { + dtlsTimer *timer = ss->ssl3.hs.rtTimer; SECStatus rv = SECSuccess; PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss)); PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); - if (ss->ssl3.hs.rtTimerCb == dtls_RetransmitTimerExpiredCb) { + if (timer->cb == dtls_RetransmitTimerExpiredCb) { /* Check to see if we retransmitted recently. If so, * suppress the triggered retransmit. This avoids * retransmit wars after packet loss. * This is not in RFC 5346 but it should be. */ - if ((PR_IntervalNow() - ss->ssl3.hs.rtTimerStarted) > - (ss->ssl3.hs.rtTimeoutMs / 4)) { + if ((PR_IntervalNow() - timer->started) > + (timer->timeout / 4)) { SSL_TRC(30, ("%d: SSL3[%d]: Shortcutting retransmit timer", SSL_GETPID(), ss->fd)); /* Cancel the timer and call the CB, * which re-arms the timer */ - dtls_CancelTimer(ss); + dtls_CancelTimer(ss, ss->ssl3.hs.rtTimer); dtls_RetransmitTimerExpiredCb(ss); } else { SSL_TRC(30, ("%d: SSL3[%d]: Ignoring retransmission: " "last retransmission %dms ago, suppressed for %dms", SSL_GETPID(), ss->fd, - PR_IntervalNow() - ss->ssl3.hs.rtTimerStarted, - ss->ssl3.hs.rtTimeoutMs / 4)); + PR_IntervalNow() - timer->started, + timer->timeout / 4)); } - } else if (ss->ssl3.hs.rtTimerCb == dtls_FinishedTimerCb) { + } else if (timer->cb == dtls_FinishedTimerCb) { SSL_TRC(30, ("%d: SSL3[%d]: Retransmit detected in holddown", SSL_GETPID(), ss->fd)); /* Retransmit the messages and re-arm the timer @@ -222,14 +227,14 @@ dtls_RetransmitDetected(sslSocket *ss) * The spec isn't clear and my reasoning is that this * may be a re-ordered packet rather than slowness, * so let's be aggressive. */ - dtls_CancelTimer(ss); + dtls_CancelTimer(ss, ss->ssl3.hs.rtTimer); rv = dtls_TransmitMessageFlight(ss); if (rv == SECSuccess) { rv = dtls_StartHolddownTimer(ss); } } else { - PORT_Assert(ss->ssl3.hs.rtTimerCb == NULL); + PORT_Assert(timer->cb == NULL); /* ... and ignore it. */ } return rv; @@ -238,19 +243,8 @@ dtls_RetransmitDetected(sslSocket *ss) static SECStatus dtls_HandleHandshakeMessage(sslSocket *ss, PRUint8 *data, PRBool last) { - - /* At this point we are advancing our state machine, so we can free our last - * flight of messages. */ - dtls_FreeHandshakeMessages(&ss->ssl3.hs.lastMessageFlight); ss->ssl3.hs.recvdHighWater = -1; - /* Reset the timer to the initial value if the retry counter - * is 0, per Sec. 4.2.4.1 */ - dtls_CancelTimer(ss); - if (ss->ssl3.hs.rtRetries == 0) { - ss->ssl3.hs.rtTimeoutMs = DTLS_RETRANSMIT_INITIAL_MS; - } - return ssl3_HandleHandshakeMessage(ss, data, ss->ssl3.hs.msg_len, last); } @@ -273,7 +267,8 @@ dtls_HandleHandshakeMessage(sslSocket *ss, PRUint8 *data, PRBool last) #define OFFSET_MASK(o) (1 << (o % 8)) SECStatus -dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf) +dtls_HandleHandshake(sslSocket *ss, DTLSEpoch epoch, sslSequenceNumber seqNum, + sslBuffer *origBuf) { /* XXX OK for now. * This doesn't work properly with asynchronous certificate validation. @@ -283,6 +278,9 @@ dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf) */ sslBuffer buf = *origBuf; SECStatus rv = SECSuccess; + PRBool discarded = PR_FALSE; + + ss->ssl3.hs.endOfFlight = PR_FALSE; PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss)); PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); @@ -298,7 +296,7 @@ dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf) if (buf.len < 12) { PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE); rv = SECFailure; - break; + goto loser; } /* Parse the header */ @@ -323,14 +321,28 @@ dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf) if (buf.len < fragment_length) { PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE); rv = SECFailure; - break; + goto loser; } /* Sanity check the packet contents */ if ((fragment_length + fragment_offset) > message_length) { PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE); rv = SECFailure; - break; + goto loser; + } + + /* If we're a server and we receive what appears to be a retried + * ClientHello, and we are expecting a ClientHello, move the receive + * sequence number forward. This allows for a retried ClientHello if we + * send a stateless HelloRetryRequest. */ + if (message_seq > ss->ssl3.hs.recvMessageSeq && + message_seq == 1 && + fragment_offset == 0 && + ss->ssl3.hs.ws == wait_client_hello && + (SSLHandshakeType)type == ssl_hs_client_hello) { + SSL_TRC(5, ("%d: DTLS[%d]: Received apparent 2nd ClientHello", + SSL_GETPID(), ss->fd)); + ss->ssl3.hs.recvMessageSeq = 1; } /* There are three ways we could not be ready for this packet. @@ -346,20 +358,20 @@ dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf) (fragment_offset == 0) && (fragment_length == message_length)) { /* Complete next message. Process immediately */ - ss->ssl3.hs.msg_type = (SSL3HandshakeType)type; + ss->ssl3.hs.msg_type = (SSLHandshakeType)type; ss->ssl3.hs.msg_len = message_length; rv = dtls_HandleHandshakeMessage(ss, buf.buf, buf.len == fragment_length); if (rv == SECFailure) { - break; /* Discard the remainder of the record. */ + goto loser; } } else { if (message_seq < ss->ssl3.hs.recvMessageSeq) { /* Case 3: we do an immediate retransmit if we're * in a waiting state. */ rv = dtls_RetransmitDetected(ss); - break; + goto loser; } else if (message_seq > ss->ssl3.hs.recvMessageSeq) { /* Case 2 * @@ -369,7 +381,12 @@ dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf) * * XXX OK for now. Maybe do something smarter at some point? */ + SSL_TRC(10, ("%d: SSL3[%d]: dtls_HandleHandshake, discarding handshake message", + SSL_GETPID(), ss->fd)); + discarded = PR_TRUE; } else { + PRInt32 end = fragment_offset + fragment_length; + /* Case 1 * * Buffer the fragment for reassembly @@ -380,18 +397,18 @@ dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf) rv = sslBuffer_Grow(&ss->ssl3.hs.msg_body, message_length); if (rv != SECSuccess) - break; + goto loser; /* Make room for the fragment map */ rv = sslBuffer_Grow(&ss->ssl3.hs.recvdFragments, map_length); if (rv != SECSuccess) - break; + goto loser; /* Reset the reassembly map */ ss->ssl3.hs.recvdHighWater = 0; PORT_Memset(ss->ssl3.hs.recvdFragments.buf, 0, ss->ssl3.hs.recvdFragments.space); - ss->ssl3.hs.msg_type = (SSL3HandshakeType)type; + ss->ssl3.hs.msg_type = (SSLHandshakeType)type; ss->ssl3.hs.msg_len = message_length; } @@ -403,14 +420,14 @@ dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf) ss->ssl3.hs.recvdHighWater = -1; PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE); rv = SECFailure; - break; + goto loser; } - /* Now copy this fragment into the buffer */ - PORT_Assert((fragment_offset + fragment_length) <= - ss->ssl3.hs.msg_body.space); - PORT_Memcpy(ss->ssl3.hs.msg_body.buf + fragment_offset, - buf.buf, fragment_length); + /* Now copy this fragment into the buffer. */ + if (end > ss->ssl3.hs.recvdHighWater) { + PORT_Memcpy(ss->ssl3.hs.msg_body.buf + fragment_offset, + buf.buf, fragment_length); + } /* This logic is a bit tricky. We have two values for * reassembly state: @@ -426,12 +443,11 @@ dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf) if (fragment_offset <= (unsigned int)ss->ssl3.hs.recvdHighWater) { /* Either this is the adjacent fragment or an overlapping * fragment */ - ss->ssl3.hs.recvdHighWater = fragment_offset + - fragment_length; + if (end > ss->ssl3.hs.recvdHighWater) { + ss->ssl3.hs.recvdHighWater = end; + } } else { - for (offset = fragment_offset; - offset < fragment_offset + fragment_length; - offset++) { + for (offset = fragment_offset; offset < end; offset++) { ss->ssl3.hs.recvdFragments.buf[OFFSET_BYTE(offset)] |= OFFSET_MASK(offset); } @@ -457,7 +473,7 @@ dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf) buf.len == fragment_length); if (rv == SECFailure) { - break; /* Discard the rest of the record. */ + goto loser; } } } @@ -467,6 +483,26 @@ dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf) buf.len -= fragment_length; } + // This should never happen, but belt and suspenders. + if (rv == SECFailure) { + PORT_Assert(0); + goto loser; + } + + /* If we processed all the fragments in this message, then mark it as remembered. + * TODO(ekr@rtfm.com): Store out of order messages for DTLS 1.3 so ACKs work + * better. Bug 1392620.*/ + if (!discarded && tls13_MaybeTls13(ss)) { + rv = dtls13_RememberFragment(ss, &ss->ssl3.hs.dtlsRcvdHandshake, + 0, 0, 0, epoch, seqNum); + } + if (rv != SECSuccess) { + goto loser; + } + + rv = dtls13_SetupAcks(ss); + +loser: origBuf->len = 0; /* So ssl3_GatherAppDataRecord will keep looping. */ /* XXX OK for now. In future handle rv == SECWouldBlock safely in order @@ -560,6 +596,8 @@ dtls_FlushHandshakeMessages(sslSocket *ss, PRInt32 flags) if (!(flags & ssl_SEND_FLAG_NO_RETRANSMIT)) { rv = dtls_StartRetransmitTimer(ss); + } else { + PORT_Assert(ss->version < SSL_LIBRARY_VERSION_TLS_1_3); } } @@ -576,7 +614,7 @@ static void dtls_RetransmitTimerExpiredCb(sslSocket *ss) { SECStatus rv; - + dtlsTimer *timer = ss->ssl3.hs.rtTimer; ss->ssl3.hs.rtRetries++; if (!(ss->ssl3.hs.rtRetries % 3)) { @@ -589,175 +627,239 @@ dtls_RetransmitTimerExpiredCb(sslSocket *ss) rv = dtls_TransmitMessageFlight(ss); if (rv == SECSuccess) { /* Re-arm the timer */ - ss->ssl3.hs.rtTimeoutMs *= 2; - if (ss->ssl3.hs.rtTimeoutMs > DTLS_RETRANSMIT_MAX_MS) { - ss->ssl3.hs.rtTimeoutMs = DTLS_RETRANSMIT_MAX_MS; + timer->timeout *= 2; + if (timer->timeout > DTLS_RETRANSMIT_MAX_MS) { + timer->timeout = DTLS_RETRANSMIT_MAX_MS; } - ss->ssl3.hs.rtTimerStarted = PR_IntervalNow(); - ss->ssl3.hs.rtTimerCb = dtls_RetransmitTimerExpiredCb; + timer->started = PR_IntervalNow(); + timer->cb = dtls_RetransmitTimerExpiredCb; SSL_TRC(30, ("%d: SSL3[%d]: Retransmit #%d, next in %d", SSL_GETPID(), ss->fd, - ss->ssl3.hs.rtRetries, ss->ssl3.hs.rtTimeoutMs)); + ss->ssl3.hs.rtRetries, timer->timeout)); } /* else: OK for now. In future maybe signal the stack that we couldn't * transmit. For now, let the read handle any real network errors */ } +#define DTLS_HS_HDR_LEN 12 +#define DTLS_MIN_FRAGMENT (DTLS_HS_HDR_LEN + 1 + DTLS_MAX_EXPANSION) + +/* Encrypt and encode a handshake message fragment. Flush the data out to the + * network if there is insufficient space for any fragment. */ +static SECStatus +dtls_SendFragment(sslSocket *ss, DTLSQueuedMessage *msg, PRUint8 *data, + unsigned int len) +{ + PRInt32 sent; + SECStatus rv; + + PRINT_BUF(40, (ss, "dtls_SendFragment", data, len)); + sent = ssl3_SendRecord(ss, msg->cwSpec, msg->type, data, len, + ssl_SEND_FLAG_FORCE_INTO_BUFFER); + if (sent != len) { + if (sent != -1) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + } + return SECFailure; + } + + /* If another fragment won't fit, flush. */ + if (ss->ssl3.mtu < ss->pendingBuf.len + DTLS_MIN_FRAGMENT) { + SSL_TRC(20, ("%d: DTLS[%d]: dtls_SendFragment: flush", + SSL_GETPID(), ss->fd)); + rv = dtls_SendSavedWriteData(ss); + if (rv != SECSuccess) { + return SECFailure; + } + } + return SECSuccess; +} + +/* Fragment a handshake message into multiple records and send them. */ +static SECStatus +dtls_FragmentHandshake(sslSocket *ss, DTLSQueuedMessage *msg) +{ + PRBool fragmentWritten = PR_FALSE; + PRUint16 msgSeq; + PRUint8 *fragment; + PRUint32 fragmentOffset = 0; + PRUint32 fragmentLen; + const PRUint8 *content = msg->data + DTLS_HS_HDR_LEN; + PRUint32 contentLen = msg->len - DTLS_HS_HDR_LEN; + SECStatus rv; + + /* The headers consume 12 bytes so the smallest possible message (i.e., an + * empty one) is 12 bytes. */ + PORT_Assert(msg->len >= DTLS_HS_HDR_LEN); + + /* DTLS only supports fragmenting handshaking messages. */ + PORT_Assert(msg->type == content_handshake); + + msgSeq = (msg->data[4] << 8) | msg->data[5]; + + /* do {} while() so that empty messages are sent at least once. */ + do { + PRUint8 buf[DTLS_MAX_MTU]; /* >= than largest plausible MTU */ + PRBool hasUnackedRange; + PRUint32 end; + + hasUnackedRange = dtls_NextUnackedRange(ss, msgSeq, + fragmentOffset, contentLen, + &fragmentOffset, &end); + if (!hasUnackedRange) { + SSL_TRC(20, ("%d: SSL3[%d]: FragmentHandshake %d: all acknowledged", + SSL_GETPID(), ss->fd, msgSeq)); + break; + } + + SSL_TRC(20, ("%d: SSL3[%d]: FragmentHandshake %d: unacked=%u-%u", + SSL_GETPID(), ss->fd, msgSeq, fragmentOffset, end)); + + /* Cut down to the data we have available. */ + PORT_Assert(fragmentOffset <= contentLen); + PORT_Assert(fragmentOffset <= end); + 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. */ + fragmentLen = PR_MIN(fragmentLen, + ss->ssl3.mtu - /* MTU estimate. */ + ss->pendingBuf.len - /* Less unsent records. */ + DTLS_MAX_EXPANSION - /* Allow for expansion. */ + DTLS_HS_HDR_LEN); /* + handshake header. */ + PORT_Assert(fragmentLen > 0 || fragmentOffset == 0); + + /* Make totally sure that we will fit in the buffer. This should be + * impossible; DTLS_MAX_MTU should always be more than ss->ssl3.mtu. */ + if (fragmentLen >= (DTLS_MAX_MTU - DTLS_HS_HDR_LEN)) { + PORT_Assert(0); + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + + if (fragmentLen == contentLen) { + fragment = msg->data; + } else { + sslBuffer tmp = SSL_BUFFER_FIXED(buf, sizeof(buf)); + + /* Construct an appropriate-sized fragment */ + /* Type, length, sequence */ + rv = sslBuffer_Append(&tmp, msg->data, 6); + if (rv != SECSuccess) { + return SECFailure; + } + /* Offset. */ + rv = sslBuffer_AppendNumber(&tmp, fragmentOffset, 3); + if (rv != SECSuccess) { + return SECFailure; + } + /* Length. */ + rv = sslBuffer_AppendNumber(&tmp, fragmentLen, 3); + if (rv != SECSuccess) { + return SECFailure; + } + /* Data. */ + rv = sslBuffer_Append(&tmp, content + fragmentOffset, fragmentLen); + if (rv != SECSuccess) { + return SECFailure; + } + + fragment = SSL_BUFFER_BASE(&tmp); + } + + /* Record that we are sending first, because encrypting + * increments the sequence number. */ + rv = dtls13_RememberFragment(ss, &ss->ssl3.hs.dtlsSentHandshake, + msgSeq, fragmentOffset, fragmentLen, + msg->cwSpec->epoch, + msg->cwSpec->seqNum); + if (rv != SECSuccess) { + return SECFailure; + } + + rv = dtls_SendFragment(ss, msg, fragment, + fragmentLen + DTLS_HS_HDR_LEN); + if (rv != SECSuccess) { + return SECFailure; + } + + fragmentWritten = PR_TRUE; + fragmentOffset += fragmentLen; + } while (fragmentOffset < contentLen); + + if (!fragmentWritten) { + /* Nothing was written if we got here, so the whole message must have + * been acknowledged. Discard it. */ + SSL_TRC(10, ("%d: SSL3[%d]: FragmentHandshake %d: removed", + SSL_GETPID(), ss->fd, msgSeq)); + PR_REMOVE_LINK(&msg->link); + dtls_FreeHandshakeMessage(msg); + } + + return SECSuccess; +} + /* Transmit a flight of handshake messages, stuffing them - * into as few records as seems reasonable + * into as few records as seems reasonable. + * + * TODO: Space separate UDP packets out a little. * * Called from: * dtls_FlushHandshake() * dtls_RetransmitTimerExpiredCb() */ -static SECStatus +SECStatus dtls_TransmitMessageFlight(sslSocket *ss) { SECStatus rv = SECSuccess; PRCList *msg_p; - PRUint16 room_left = ss->ssl3.mtu; - PRInt32 sent; + + SSL_TRC(10, ("%d: SSL3[%d]: dtls_TransmitMessageFlight", + SSL_GETPID(), ss->fd)); ssl_GetXmitBufLock(ss); ssl_GetSpecReadLock(ss); - /* DTLS does not buffer its handshake messages in - * ss->pendingBuf, but rather in the lastMessageFlight - * structure. This is just a sanity check that - * some programming error hasn't inadvertantly - * stuffed something in ss->pendingBuf + /* DTLS does not buffer its handshake messages in ss->pendingBuf, but rather + * in the lastMessageFlight structure. This is just a sanity check that some + * programming error hasn't inadvertantly stuffed something in + * ss->pendingBuf. This function uses ss->pendingBuf temporarily and it + * needs to be empty to start. */ PORT_Assert(!ss->pendingBuf.len); + for (msg_p = PR_LIST_HEAD(&ss->ssl3.hs.lastMessageFlight); - msg_p != &ss->ssl3.hs.lastMessageFlight; - msg_p = PR_NEXT_LINK(msg_p)) { + msg_p != &ss->ssl3.hs.lastMessageFlight;) { DTLSQueuedMessage *msg = (DTLSQueuedMessage *)msg_p; - /* The logic here is: - * - * 1. If this is a message that will not fit into the remaining - * space, then flush. - * 2. If the message will now fit into the remaining space, - * encrypt, buffer, and loop. - * 3. If the message will not fit, then fragment. - * - * At the end of the function, flush. - */ - if ((msg->len + SSL3_BUFFER_FUDGE) > room_left) { - /* The message will not fit into the remaining space, so flush */ - rv = dtls_SendSavedWriteData(ss); - if (rv != SECSuccess) - break; - - room_left = ss->ssl3.mtu; - } + /* Move the pointer forward so that the functions below are free to + * remove messages from the list. */ + msg_p = PR_NEXT_LINK(msg_p); - if ((msg->len + SSL3_BUFFER_FUDGE) <= room_left) { - /* The message will fit, so encrypt and then continue with the - * next packet */ - sent = ssl3_SendRecord(ss, msg->cwSpec, msg->type, - msg->data, msg->len, - ssl_SEND_FLAG_FORCE_INTO_BUFFER); - if (sent != msg->len) { - rv = SECFailure; - if (sent != -1) { - PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); - } - break; - } + /* Note: This function fragments messages so that each record is close + * to full. This produces fewer records, but it means that messages can + * be quite fragmented. Adding an extra flush here would push new + * messages into new records and reduce fragmentation. */ - room_left = ss->ssl3.mtu - ss->pendingBuf.len; + if (msg->type == content_handshake) { + rv = dtls_FragmentHandshake(ss, msg); } else { - /* The message will not fit, so fragment. - * - * XXX OK for now. Arrange to coalesce the last fragment - * of this message with the next message if possible. - * That would be more efficient. - */ - PRUint32 fragment_offset = 0; - unsigned char fragment[DTLS_MAX_MTU]; /* >= than largest - * plausible MTU */ - - /* Assert that we have already flushed */ - PORT_Assert(room_left == ss->ssl3.mtu); - - /* Case 3: We now need to fragment this message - * DTLS only supports fragmenting handshaking messages */ - PORT_Assert(msg->type == content_handshake); - - /* The headers consume 12 bytes so the smalles possible - * message (i.e., an empty one) is 12 bytes - */ - PORT_Assert(msg->len >= 12); - - while ((fragment_offset + 12) < msg->len) { - PRUint32 fragment_len; - const unsigned char *content = msg->data + 12; - PRUint32 content_len = msg->len - 12; - - /* The reason we use 8 here is that that's the length of - * the new DTLS data that we add to the header */ - fragment_len = PR_MIN((PRUint32)room_left - (SSL3_BUFFER_FUDGE + 8), - content_len - fragment_offset); - PORT_Assert(fragment_len < DTLS_MAX_MTU - 12); - /* Make totally sure that we are within the buffer. - * Note that the only way that fragment len could get - * adjusted here is if - * - * (a) we are in release mode so the PORT_Assert is compiled out - * (b) either the MTU table is inconsistent with DTLS_MAX_MTU - * or ss->ssl3.mtu has become corrupt. - */ - fragment_len = PR_MIN(fragment_len, DTLS_MAX_MTU - 12); - - /* Construct an appropriate-sized fragment */ - /* Type, length, sequence */ - PORT_Memcpy(fragment, msg->data, 6); - - /* Offset */ - fragment[6] = (fragment_offset >> 16) & 0xff; - fragment[7] = (fragment_offset >> 8) & 0xff; - fragment[8] = (fragment_offset)&0xff; - - /* Fragment length */ - fragment[9] = (fragment_len >> 16) & 0xff; - fragment[10] = (fragment_len >> 8) & 0xff; - fragment[11] = (fragment_len)&0xff; - - PORT_Memcpy(fragment + 12, content + fragment_offset, - fragment_len); - - /* - * Send the record. We do this in two stages - * 1. Encrypt - */ - sent = ssl3_SendRecord(ss, msg->cwSpec, msg->type, - fragment, fragment_len + 12, - ssl_SEND_FLAG_FORCE_INTO_BUFFER); - if (sent != (fragment_len + 12)) { - rv = SECFailure; - if (sent != -1) { - PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); - } - break; - } - - /* 2. Flush */ - rv = dtls_SendSavedWriteData(ss); - if (rv != SECSuccess) - break; - - fragment_offset += fragment_len; - } + PORT_Assert(!tls13_MaybeTls13(ss)); + rv = dtls_SendFragment(ss, msg, msg->data, msg->len); + } + if (rv != SECSuccess) { + break; } } - /* Finally, we need to flush */ - if (rv == SECSuccess) + /* Finally, flush any data that wasn't flushed already. */ + if (rv == SECSuccess) { rv = dtls_SendSavedWriteData(ss); + } /* Give up the locks */ ssl_ReleaseSpecReadLock(ss); @@ -796,23 +898,59 @@ dtls_SendSavedWriteData(sslSocket *ss) return SECSuccess; } -static SECStatus -dtls_StartTimer(sslSocket *ss, PRUint32 time, DTLSTimerCb cb) +void +dtls_InitTimers(sslSocket *ss) { - PORT_Assert(ss->ssl3.hs.rtTimerCb == NULL); + unsigned int i; + dtlsTimer **timers[PR_ARRAY_SIZE(ss->ssl3.hs.timers)] = { + &ss->ssl3.hs.rtTimer, + &ss->ssl3.hs.ackTimer, + &ss->ssl3.hs.hdTimer + }; + static const char *timerLabels[] = { + "retransmit", "ack", "holddown" + }; + + PORT_Assert(PR_ARRAY_SIZE(timers) == PR_ARRAY_SIZE(timerLabels)); + for (i = 0; i < PR_ARRAY_SIZE(ss->ssl3.hs.timers); ++i) { + *timers[i] = &ss->ssl3.hs.timers[i]; + ss->ssl3.hs.timers[i].label = timerLabels[i]; + } +} - ss->ssl3.hs.rtRetries = 0; - ss->ssl3.hs.rtTimerStarted = PR_IntervalNow(); - ss->ssl3.hs.rtTimeoutMs = time; - ss->ssl3.hs.rtTimerCb = cb; +SECStatus +dtls_StartTimer(sslSocket *ss, dtlsTimer *timer, PRUint32 time, DTLSTimerCb cb) +{ + PORT_Assert(timer->cb == NULL); + + SSL_TRC(10, ("%d: SSL3[%d]: %s dtls_StartTimer %s timeout=%d", + SSL_GETPID(), ss->fd, SSL_ROLE(ss), timer->label, time)); + + timer->started = PR_IntervalNow(); + timer->timeout = time; + timer->cb = cb; return SECSuccess; } +SECStatus +dtls_RestartTimer(sslSocket *ss, dtlsTimer *timer) +{ + timer->started = PR_IntervalNow(); + return SECSuccess; +} + +PRBool +dtls_TimerActive(sslSocket *ss, dtlsTimer *timer) +{ + return timer->cb != NULL; +} /* Start a timer for retransmission. */ static SECStatus dtls_StartRetransmitTimer(sslSocket *ss) { - return dtls_StartTimer(ss, DTLS_RETRANSMIT_INITIAL_MS, + ss->ssl3.hs.rtRetries = 0; + return dtls_StartTimer(ss, ss->ssl3.hs.rtTimer, + DTLS_RETRANSMIT_INITIAL_MS, dtls_RetransmitTimerExpiredCb); } @@ -820,7 +958,9 @@ dtls_StartRetransmitTimer(sslSocket *ss) SECStatus dtls_StartHolddownTimer(sslSocket *ss) { - return dtls_StartTimer(ss, DTLS_RETRANSMIT_FINISHED_MS, + ss->ssl3.hs.rtRetries = 0; + return dtls_StartTimer(ss, ss->ssl3.hs.rtTimer, + DTLS_RETRANSMIT_FINISHED_MS, dtls_FinishedTimerCb); } @@ -831,11 +971,25 @@ dtls_StartHolddownTimer(sslSocket *ss) * dtls_CheckTimer() */ void -dtls_CancelTimer(sslSocket *ss) +dtls_CancelTimer(sslSocket *ss, dtlsTimer *timer) { + SSL_TRC(30, ("%d: SSL3[%d]: %s dtls_CancelTimer %s", + SSL_GETPID(), ss->fd, SSL_ROLE(ss), + timer->label)); + PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss)); - ss->ssl3.hs.rtTimerCb = NULL; + timer->cb = NULL; +} + +static void +dtls_CancelAllTimers(sslSocket *ss) +{ + unsigned int i; + + for (i = 0; i < PR_ARRAY_SIZE(ss->ssl3.hs.timers); ++i) { + dtls_CancelTimer(ss, &ss->ssl3.hs.timers[i]); + } } /* Check the pending timer and fire the callback if it expired @@ -845,22 +999,33 @@ dtls_CancelTimer(sslSocket *ss) void dtls_CheckTimer(sslSocket *ss) { + unsigned int i; + SSL_TRC(30, ("%d: SSL3[%d]: dtls_CheckTimer (%s)", + SSL_GETPID(), ss->fd, ss->sec.isServer ? "server" : "client")); + ssl_GetSSL3HandshakeLock(ss); - if (!ss->ssl3.hs.rtTimerCb) { - ssl_ReleaseSSL3HandshakeLock(ss); - return; - } - if ((PR_IntervalNow() - ss->ssl3.hs.rtTimerStarted) > - PR_MillisecondsToInterval(ss->ssl3.hs.rtTimeoutMs)) { - /* Timer has expired */ - DTLSTimerCb cb = ss->ssl3.hs.rtTimerCb; + for (i = 0; i < PR_ARRAY_SIZE(ss->ssl3.hs.timers); ++i) { + dtlsTimer *timer = &ss->ssl3.hs.timers[i]; + if (!timer->cb) { + continue; + } + + if ((PR_IntervalNow() - timer->started) >= + PR_MillisecondsToInterval(timer->timeout)) { + /* Timer has expired */ + DTLSTimerCb cb = timer->cb; + + SSL_TRC(10, ("%d: SSL3[%d]: %s firing timer %s", + SSL_GETPID(), ss->fd, SSL_ROLE(ss), + timer->label)); - /* Cancel the timer so that we can call the CB safely */ - dtls_CancelTimer(ss); + /* Cancel the timer so that we can call the CB safely */ + dtls_CancelTimer(ss, timer); - /* Now call the CB */ - cb(ss); + /* Now call the CB */ + cb(ss); + } } ssl_ReleaseSSL3HandshakeLock(ss); } @@ -874,9 +1039,6 @@ static void dtls_FinishedTimerCb(sslSocket *ss) { dtls_FreeHandshakeMessages(&ss->ssl3.hs.lastMessageFlight); - if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) { - ssl3_DestroyCipherSpec(ss->ssl3.pwSpec, PR_FALSE); - } } /* Cancel the Finished hold-down timer and destroy the @@ -895,8 +1057,8 @@ dtls_RehandshakeCleanup(sslSocket *ss) return; } PORT_Assert((ss->version < SSL_LIBRARY_VERSION_TLS_1_3)); - dtls_CancelTimer(ss); - ssl3_DestroyCipherSpec(ss->ssl3.pwSpec, PR_FALSE); + dtls_CancelAllTimers(ss); + dtls_FreeHandshakeMessages(&ss->ssl3.hs.lastMessageFlight); ss->ssl3.hs.sendMessageSeq = 0; ss->ssl3.hs.recvMessageSeq = 0; } @@ -959,6 +1121,8 @@ dtls_HandleHelloVerifyRequest(sslSocket *ss, PRUint8 *b, PRUint32 length) goto alert_loser; } + dtls_ReceivedFirstMessageInFlight(ss); + /* The version. * * RFC 4347 required that you verify that the server versions @@ -1103,27 +1267,53 @@ SECStatus DTLS_GetHandshakeTimeout(PRFileDesc *socket, PRIntervalTime *timeout) { sslSocket *ss = NULL; - PRIntervalTime elapsed; - PRIntervalTime desired; + PRBool found = PR_FALSE; + PRIntervalTime now = PR_IntervalNow(); + PRIntervalTime to; + unsigned int i; + + *timeout = PR_INTERVAL_NO_TIMEOUT; ss = ssl_FindSocket(socket); - if (!ss) + if (!ss) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; + } - if (!IS_DTLS(ss)) + if (!IS_DTLS(ss)) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; + } - if (!ss->ssl3.hs.rtTimerCb) - return SECFailure; + for (i = 0; i < PR_ARRAY_SIZE(ss->ssl3.hs.timers); ++i) { + PRIntervalTime elapsed; + PRIntervalTime desired; + dtlsTimer *timer = &ss->ssl3.hs.timers[i]; - elapsed = PR_IntervalNow() - ss->ssl3.hs.rtTimerStarted; - desired = PR_MillisecondsToInterval(ss->ssl3.hs.rtTimeoutMs); - if (elapsed > desired) { - /* Timer expired */ - *timeout = PR_INTERVAL_NO_WAIT; - } else { - *timeout = desired - elapsed; + if (!timer->cb) { + continue; + } + found = PR_TRUE; + + elapsed = now - timer->started; + desired = PR_MillisecondsToInterval(timer->timeout); + if (elapsed > desired) { + /* Timer expired */ + *timeout = PR_INTERVAL_NO_WAIT; + return SECSuccess; + } else { + to = desired - elapsed; + } + + if (*timeout > to) { + *timeout = to; + } + } + + if (!found) { + PORT_SetError(SSL_ERROR_NO_TIMERS_FOUND); + return SECFailure; } return SECSuccess; @@ -1137,72 +1327,50 @@ DTLS_GetHandshakeTimeout(PRFileDesc *socket, PRIntervalTime *timeout) * seems like a good tradeoff for implementation effort and is * consistent with the guidance of RFC 6347 Sections 4.1 and 4.2.4.1. * - * If the packet is not relevant, this function returns PR_FALSE. - * If the packet is relevant, this function returns PR_TRUE - * and sets |*seqNum| to the packet sequence number. + * If the packet is not relevant, this function returns PR_FALSE. If the packet + * is relevant, this function returns PR_TRUE and sets |*seqNumOut| to the + * packet sequence number (removing the epoch). */ PRBool -dtls_IsRelevant(sslSocket *ss, const SSL3Ciphertext *cText, - PRBool *sameEpoch, PRUint64 *seqNum) +dtls_IsRelevant(sslSocket *ss, const ssl3CipherSpec *spec, + const SSL3Ciphertext *cText, + sslSequenceNumber *seqNumOut) { - const ssl3CipherSpec *crSpec = ss->ssl3.crSpec; - DTLSEpoch epoch; - sslSequenceNumber dtls_seq_num; - - epoch = cText->seq_num >> 48; - *sameEpoch = crSpec->epoch == epoch; - if (!*sameEpoch) { - SSL_DBG(("%d: SSL3[%d]: dtls_IsRelevant, received packet " - "from irrelevant epoch %d", - SSL_GETPID(), ss->fd, epoch)); - return PR_FALSE; - } - - dtls_seq_num = cText->seq_num & RECORD_SEQ_MAX; - if (dtls_RecordGetRecvd(&crSpec->recvdRecords, dtls_seq_num) != 0) { - SSL_DBG(("%d: SSL3[%d]: dtls_IsRelevant, rejecting " - "potentially replayed packet", - SSL_GETPID(), ss->fd)); + sslSequenceNumber seqNum = cText->seq_num & RECORD_SEQ_MASK; + if (dtls_RecordGetRecvd(&spec->recvdRecords, seqNum) != 0) { + SSL_TRC(10, ("%d: SSL3[%d]: dtls_IsRelevant, rejecting " + "potentially replayed packet", + SSL_GETPID(), ss->fd)); return PR_FALSE; } - *seqNum = dtls_seq_num; + *seqNumOut = seqNum; return PR_TRUE; } -/* In TLS 1.3, a client that receives a retransmission of the server's first - * flight will reject that message and discard it (see dtls_IsRelevant() above). - * However, we need to trigger retransmission to prevent loss of the client's - * last flight from causing the connection to fail. - * - * This only triggers for a retransmitted ServerHello. Other (encrypted) - * handshake messages do not trigger retransmission, so we are a little more - * exposed to loss than is ideal. - * - * Note: This isn't an issue in earlier versions because the second-to-last - * flight (sent by the server) includes the Finished message, which is not - * dropped because it has the same epoch that the client currently expects. - */ -SECStatus -dtls_MaybeRetransmitHandshake(sslSocket *ss, const SSL3Ciphertext *cText, - PRBool sameEpoch) +void +dtls_ReceivedFirstMessageInFlight(sslSocket *ss) { - SECStatus rv = SECSuccess; - DTLSEpoch messageEpoch = cText->seq_num >> 48; - - /* Drop messages from other epochs if we are ignoring things. */ - if (!sameEpoch && ss->ssl3.hs.zeroRttIgnore != ssl_0rtt_ignore_none) { - return SECSuccess; - } + if (!IS_DTLS(ss)) + return; - if (!ss->sec.isServer && ss->version >= SSL_LIBRARY_VERSION_TLS_1_3 && - messageEpoch == 0 && cText->type == content_handshake) { - ssl_GetSSL3HandshakeLock(ss); - if (ss->ssl3.hs.rtTimerCb == dtls_FinishedTimerCb && - ss->ssl3.hs.ws == idle_handshake) { - rv = dtls_RetransmitDetected(ss); + /* At this point we are advancing our state machine, so we can free our last + * flight of messages. */ + if (ss->ssl3.hs.ws != idle_handshake || + ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) { + /* We need to keep our last flight around in DTLS 1.2 and below, + * so we can retransmit it in response to other people's + * retransmits. */ + dtls_FreeHandshakeMessages(&ss->ssl3.hs.lastMessageFlight); + + /* Reset the timer to the initial value if the retry counter + * is 0, per RFC 6347, Sec. 4.2.4.1 */ + dtls_CancelTimer(ss, ss->ssl3.hs.rtTimer); + if (ss->ssl3.hs.rtRetries == 0) { + ss->ssl3.hs.rtTimer->timeout = DTLS_RETRANSMIT_INITIAL_MS; } - ssl_ReleaseSSL3HandshakeLock(ss); } - return rv; + + /* Empty the ACK queue (TLS 1.3 only). */ + ssl_ClearPRCList(&ss->ssl3.hs.dtlsRcvdHandshake, NULL); } diff --git a/security/nss/lib/ssl/dtlscon.h b/security/nss/lib/ssl/dtlscon.h new file mode 100644 index 000000000..d094380f8 --- /dev/null +++ b/security/nss/lib/ssl/dtlscon.h @@ -0,0 +1,48 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is PRIVATE to SSL. + * + * 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 __dtlscon_h_ +#define __dtlscon_h_ + +extern void dtls_FreeHandshakeMessage(DTLSQueuedMessage *msg); +extern void dtls_FreeHandshakeMessages(PRCList *lst); +SECStatus dtls_TransmitMessageFlight(sslSocket *ss); +void dtls_InitTimers(sslSocket *ss); +SECStatus dtls_StartTimer(sslSocket *ss, dtlsTimer *timer, + PRUint32 time, DTLSTimerCb cb); +SECStatus dtls_RestartTimer(sslSocket *ss, dtlsTimer *timer); +PRBool dtls_TimerActive(sslSocket *ss, dtlsTimer *timer); +extern SECStatus dtls_HandleHandshake(sslSocket *ss, DTLSEpoch epoch, + sslSequenceNumber seqNum, + sslBuffer *origBuf); +extern SECStatus dtls_HandleHelloVerifyRequest(sslSocket *ss, + PRUint8 *b, PRUint32 length); +extern SECStatus dtls_StageHandshakeMessage(sslSocket *ss); +extern SECStatus dtls_QueueMessage(sslSocket *ss, SSL3ContentType type, + const PRUint8 *pIn, PRInt32 nIn); +extern SECStatus dtls_FlushHandshakeMessages(sslSocket *ss, PRInt32 flags); +SECStatus ssl3_DisableNonDTLSSuites(sslSocket *ss); +extern SECStatus dtls_StartHolddownTimer(sslSocket *ss); +extern void dtls_CheckTimer(sslSocket *ss); +extern void dtls_CancelTimer(sslSocket *ss, dtlsTimer *timer); +extern void dtls_SetMTU(sslSocket *ss, PRUint16 advertised); +extern void dtls_InitRecvdRecords(DTLSRecvdRecords *records); +extern int dtls_RecordGetRecvd(const DTLSRecvdRecords *records, + sslSequenceNumber seq); +extern void dtls_RecordSetRecvd(DTLSRecvdRecords *records, + sslSequenceNumber seq); +extern void dtls_RehandshakeCleanup(sslSocket *ss); +extern SSL3ProtocolVersion +dtls_TLSVersionToDTLSVersion(SSL3ProtocolVersion tlsv); +extern SSL3ProtocolVersion +dtls_DTLSVersionToTLSVersion(SSL3ProtocolVersion dtlsv); +extern PRBool dtls_IsRelevant(sslSocket *ss, const ssl3CipherSpec *spec, + const SSL3Ciphertext *cText, + sslSequenceNumber *seqNum); +void dtls_ReceivedFirstMessageInFlight(sslSocket *ss); +#endif diff --git a/security/nss/lib/ssl/exports.gyp b/security/nss/lib/ssl/exports.gyp index e2123af84..c3b34c6cc 100644 --- a/security/nss/lib/ssl/exports.gyp +++ b/security/nss/lib/ssl/exports.gyp @@ -15,6 +15,7 @@ 'preenc.h', 'ssl.h', 'sslerr.h', + 'sslexp.h', 'sslproto.h', 'sslt.h' ], diff --git a/security/nss/lib/ssl/manifest.mn b/security/nss/lib/ssl/manifest.mn index fbb88baff..ca9b9ee7b 100644 --- a/security/nss/lib/ssl/manifest.mn +++ b/security/nss/lib/ssl/manifest.mn @@ -10,6 +10,7 @@ EXPORTS = \ ssl.h \ sslt.h \ sslerr.h \ + sslexp.h \ sslproto.h \ preenc.h \ $(NULL) @@ -19,13 +20,15 @@ MAPFILE = $(OBJDIR)/ssl.def CSRCS = \ dtlscon.c \ + dtls13con.c \ prelib.c \ ssl3con.c \ ssl3gthr.c \ sslauth.c \ + sslbloom.c \ sslcon.c \ ssldef.c \ - ssl3encode.c \ + sslencode.c \ sslenum.c \ sslerr.c \ sslerrstrs.c \ @@ -38,6 +41,7 @@ CSRCS = \ sslsecur.c \ sslsnce.c \ sslsock.c \ + sslspec.c \ ssltrace.c \ sslver.c \ authcert.c \ @@ -47,7 +51,9 @@ CSRCS = \ ssl3ecc.c \ tls13con.c \ tls13exthandle.c \ + tls13hashstate.c \ tls13hkdf.c \ + tls13replay.c \ sslcert.c \ sslgrp.c \ $(NULL) diff --git a/security/nss/lib/ssl/selfencrypt.c b/security/nss/lib/ssl/selfencrypt.c index 6d6e25cfc..1c70f7635 100644 --- a/security/nss/lib/ssl/selfencrypt.c +++ b/security/nss/lib/ssl/selfencrypt.c @@ -11,7 +11,6 @@ #include "pk11func.h" #include "ssl.h" #include "sslt.h" -#include "ssl3encode.h" #include "sslimpl.h" #include "selfencrypt.h" @@ -121,12 +120,11 @@ ssl_SelfEncryptProtectInt( PRUint8 *out, unsigned int *outLen, unsigned int maxOutLen) { unsigned int len; + unsigned int lenOffset; unsigned char iv[AES_BLOCK_SIZE]; SECItem ivItem = { siBuffer, iv, sizeof(iv) }; - unsigned char mac[SHA256_LENGTH]; /* SHA-256 */ - unsigned int macLen; - SECItem outItem = { siBuffer, out, maxOutLen }; - SECItem lengthBytesItem; + /* Write directly to out. */ + sslBuffer buf = SSL_BUFFER_FIXED(out, maxOutLen); SECStatus rv; /* Generate a random IV */ @@ -137,52 +135,54 @@ ssl_SelfEncryptProtectInt( } /* Add header. */ - rv = ssl3_AppendToItem(&outItem, keyName, SELF_ENCRYPT_KEY_NAME_LEN); + rv = sslBuffer_Append(&buf, keyName, SELF_ENCRYPT_KEY_NAME_LEN); if (rv != SECSuccess) { return SECFailure; } - rv = ssl3_AppendToItem(&outItem, iv, sizeof(iv)); + rv = sslBuffer_Append(&buf, iv, sizeof(iv)); if (rv != SECSuccess) { return SECFailure; } - /* Skip forward by two so we can encode the ciphertext in place. */ - lengthBytesItem = outItem; - rv = ssl3_AppendNumberToItem(&outItem, 0, 2); + /* Leave space for the length of the ciphertext. */ + rv = sslBuffer_Skip(&buf, 2, &lenOffset); if (rv != SECSuccess) { return SECFailure; } + /* Encode the ciphertext in place. */ rv = PK11_Encrypt(encKey, CKM_AES_CBC_PAD, &ivItem, - outItem.data, &len, outItem.len, in, inLen); + SSL_BUFFER_NEXT(&buf), &len, + SSL_BUFFER_SPACE(&buf), in, inLen); + if (rv != SECSuccess) { + return SECFailure; + } + rv = sslBuffer_Skip(&buf, len, NULL); if (rv != SECSuccess) { return SECFailure; } - outItem.data += len; - outItem.len -= len; - - /* Now encode the ciphertext length. */ - rv = ssl3_AppendNumberToItem(&lengthBytesItem, len, 2); + rv = sslBuffer_InsertLength(&buf, lenOffset, 2); if (rv != SECSuccess) { return SECFailure; } - /* MAC the entire output buffer and append the MAC to the end. */ + /* MAC the entire output buffer into the output. */ + PORT_Assert(buf.space - buf.len >= SHA256_LENGTH); rv = ssl_MacBuffer(macKey, CKM_SHA256_HMAC, - out, outItem.data - out, - mac, &macLen, sizeof(mac)); + SSL_BUFFER_BASE(&buf), /* input */ + SSL_BUFFER_LEN(&buf), + SSL_BUFFER_NEXT(&buf), &len, /* output */ + SHA256_LENGTH); if (rv != SECSuccess) { return SECFailure; } - PORT_Assert(macLen == sizeof(mac)); - - rv = ssl3_AppendToItem(&outItem, mac, macLen); + rv = sslBuffer_Skip(&buf, len, NULL); if (rv != SECSuccess) { return SECFailure; } - *outLen = outItem.data - out; + *outLen = SSL_BUFFER_LEN(&buf); return SECSuccess; } @@ -192,75 +192,71 @@ ssl_SelfEncryptUnprotectInt( const PRUint8 *in, unsigned int inLen, PRUint8 *out, unsigned int *outLen, unsigned int maxOutLen) { - unsigned char *encodedKeyName; - unsigned char *iv; - SECItem ivItem = { siBuffer, NULL, 0 }; - SECItem inItem = { siBuffer, (unsigned char *)in, inLen }; - unsigned char *cipherText; - PRUint32 cipherTextLen; - unsigned char *encodedMac; - unsigned char computedMac[SHA256_LENGTH]; - unsigned int computedMacLen; - unsigned int bytesToMac; - SECStatus rv; + sslReader reader = SSL_READER(in, inLen); - rv = ssl3_ConsumeFromItem(&inItem, &encodedKeyName, - SELF_ENCRYPT_KEY_NAME_LEN); + sslReadBuffer encodedKeyNameBuffer = { 0 }; + SECStatus rv = sslRead_Read(&reader, SELF_ENCRYPT_KEY_NAME_LEN, + &encodedKeyNameBuffer); if (rv != SECSuccess) { return SECFailure; } - rv = ssl3_ConsumeFromItem(&inItem, &iv, AES_BLOCK_SIZE); + sslReadBuffer ivBuffer = { 0 }; + rv = sslRead_Read(&reader, AES_BLOCK_SIZE, &ivBuffer); if (rv != SECSuccess) { return SECFailure; } - rv = ssl3_ConsumeNumberFromItem(&inItem, &cipherTextLen, 2); + PRUint64 cipherTextLen = 0; + rv = sslRead_ReadNumber(&reader, 2, &cipherTextLen); if (rv != SECSuccess) { return SECFailure; } - rv = ssl3_ConsumeFromItem(&inItem, &cipherText, cipherTextLen); + sslReadBuffer cipherTextBuffer = { 0 }; + rv = sslRead_Read(&reader, (unsigned int)cipherTextLen, &cipherTextBuffer); if (rv != SECSuccess) { return SECFailure; } - bytesToMac = inItem.data - in; + unsigned int bytesToMac = reader.offset; - rv = ssl3_ConsumeFromItem(&inItem, &encodedMac, SHA256_LENGTH); + sslReadBuffer encodedMacBuffer = { 0 }; + rv = sslRead_Read(&reader, SHA256_LENGTH, &encodedMacBuffer); if (rv != SECSuccess) { return SECFailure; } /* Make sure we're at the end of the block. */ - if (inItem.len) { + if (reader.offset != reader.buf.len) { PORT_SetError(SEC_ERROR_BAD_DATA); return SECFailure; } /* Now that everything is decoded, we can make progress. */ /* 1. Check that we have the right key. */ - if (PORT_Memcmp(keyName, encodedKeyName, SELF_ENCRYPT_KEY_NAME_LEN)) { + if (PORT_Memcmp(keyName, encodedKeyNameBuffer.buf, SELF_ENCRYPT_KEY_NAME_LEN)) { PORT_SetError(SEC_ERROR_NOT_A_RECIPIENT); return SECFailure; } /* 2. Check the MAC */ + unsigned char computedMac[SHA256_LENGTH]; + unsigned int computedMacLen = 0; rv = ssl_MacBuffer(macKey, CKM_SHA256_HMAC, in, bytesToMac, computedMac, &computedMacLen, sizeof(computedMac)); if (rv != SECSuccess) { return SECFailure; } PORT_Assert(computedMacLen == SHA256_LENGTH); - if (NSS_SecureMemcmp(computedMac, encodedMac, computedMacLen) != 0) { + if (NSS_SecureMemcmp(computedMac, encodedMacBuffer.buf, computedMacLen) != 0) { PORT_SetError(SEC_ERROR_BAD_DATA); return SECFailure; } /* 3. OK, it verifies, now decrypt. */ - ivItem.data = iv; - ivItem.len = AES_BLOCK_SIZE; + SECItem ivItem = { siBuffer, (unsigned char *)ivBuffer.buf, AES_BLOCK_SIZE }; rv = PK11_Decrypt(encKey, CKM_AES_CBC_PAD, &ivItem, - out, outLen, maxOutLen, cipherText, cipherTextLen); + out, outLen, maxOutLen, cipherTextBuffer.buf, cipherTextLen); if (rv != SECSuccess) { return SECFailure; } @@ -269,6 +265,17 @@ ssl_SelfEncryptUnprotectInt( } #endif +/* Predict the size of the encrypted data, including padding */ +unsigned int +ssl_SelfEncryptGetProtectedSize(unsigned int inLen) +{ + return SELF_ENCRYPT_KEY_NAME_LEN + + AES_BLOCK_SIZE + + 2 + + ((inLen / AES_BLOCK_SIZE) + 1) * AES_BLOCK_SIZE + /* Padded */ + SHA256_LENGTH; +} + SECStatus ssl_SelfEncryptProtect( sslSocket *ss, const PRUint8 *in, unsigned int inLen, diff --git a/security/nss/lib/ssl/selfencrypt.h b/security/nss/lib/ssl/selfencrypt.h index 5bc8e4348..5415ac09f 100644 --- a/security/nss/lib/ssl/selfencrypt.h +++ b/security/nss/lib/ssl/selfencrypt.h @@ -11,6 +11,7 @@ #include "secmodt.h" +unsigned int ssl_SelfEncryptGetProtectedSize(unsigned int inLen); SECStatus ssl_SelfEncryptProtect( sslSocket *ss, const PRUint8 *in, unsigned int inLen, PRUint8 *out, unsigned int *outLen, unsigned int maxOutLen); diff --git a/security/nss/lib/ssl/ssl.def b/security/nss/lib/ssl/ssl.def index 94d304223..9a447dbef 100644 --- a/security/nss/lib/ssl/ssl.def +++ b/security/nss/lib/ssl/ssl.def @@ -234,3 +234,9 @@ SSL_AlertSentCallback; ;+ local: ;+*; ;+}; +;+NSS_3.33 { # NSS 3.33 release +;+ global: +SSL_GetExperimentalAPI; +;+ local: +;+*; +;+}; diff --git a/security/nss/lib/ssl/ssl.gyp b/security/nss/lib/ssl/ssl.gyp index 03b2d6014..3694ab91a 100644 --- a/security/nss/lib/ssl/ssl.gyp +++ b/security/nss/lib/ssl/ssl.gyp @@ -13,18 +13,20 @@ 'authcert.c', 'cmpcert.c', 'dtlscon.c', + 'dtls13con.c', 'prelib.c', 'selfencrypt.c', 'ssl3con.c', 'ssl3ecc.c', - 'ssl3encode.c', 'ssl3ext.c', 'ssl3exthandle.c', 'ssl3gthr.c', 'sslauth.c', + 'sslbloom.c', 'sslcert.c', 'sslcon.c', 'ssldef.c', + 'sslencode.c', 'sslenum.c', 'sslerr.c', 'sslerrstrs.c', @@ -37,11 +39,14 @@ 'sslsecur.c', 'sslsnce.c', 'sslsock.c', + 'sslspec.c', 'ssltrace.c', 'sslver.c', 'tls13con.c', 'tls13exthandle.c', + 'tls13hashstate.c', 'tls13hkdf.c', + 'tls13replay.c', ], 'conditions': [ [ 'OS=="win"', { @@ -57,14 +62,6 @@ 'unix_err.c' ], }], - [ 'ssl_enable_zlib==1', { - 'dependencies': [ - '<(DEPTH)/lib/zlib/zlib.gyp:nss_zlib' - ], - 'defines': [ - 'NSS_SSL_ENABLE_ZLIB', - ], - }], [ 'fuzz_tls==1', { 'defines': [ 'UNSAFE_FUZZER_MODE', diff --git a/security/nss/lib/ssl/ssl.h b/security/nss/lib/ssl/ssl.h index 7e538ac1f..25aabbaa2 100644 --- a/security/nss/lib/ssl/ssl.h +++ b/security/nss/lib/ssl/ssl.h @@ -107,8 +107,7 @@ SSL_IMPORT PRFileDesc *DTLS_ImportFD(PRFileDesc *model, PRFileDesc *fd); #define SSL_NO_LOCKS 17 /* Don't use locks for protection */ #define SSL_ENABLE_SESSION_TICKETS 18 /* Enable TLS SessionTicket */ /* extension (off by default) */ -#define SSL_ENABLE_DEFLATE 19 /* Enable TLS compression with */ - /* DEFLATE (off by default) */ +#define SSL_ENABLE_DEFLATE 19 /* (unsupported, deprecated, off) */ #define SSL_ENABLE_RENEGOTIATION 20 /* Values below (default: never) */ #define SSL_REQUIRE_SAFE_NEGOTIATION 21 /* Peer must send Signaling */ /* Cipher Suite Value (SCSV) or */ @@ -231,25 +230,46 @@ SSL_IMPORT PRFileDesc *DTLS_ImportFD(PRFileDesc *model, PRFileDesc *fd); * parameters. * * The transition between the 0-RTT and 1-RTT modes is marked by the - * handshake callback. + * handshake callback. However, it is possible to force the completion + * of the handshake (and cause the handshake callback to be called) + * prior to reading all 0-RTT data using SSL_ForceHandshake(). To + * ensure that all early data is read before the handshake callback, any + * time that SSL_ForceHandshake() returns a PR_WOULD_BLOCK_ERROR, use + * PR_Read() to read all available data. If PR_Read() is called + * multiple times, this will result in the handshake completing, but the + * handshake callback will occur after early data has all been read. * * WARNING: 0-RTT data has different anti-replay and PFS properties than - * the rest of the TLS data. See [draft-ietf-tls-tls13; Section 6.2.3] + * the rest of the TLS data. See [draft-ietf-tls-tls13; Section 8] * for more details. + * + * Note: when DTLS 1.3 is in use, any 0-RTT data received after EndOfEarlyData + * (e.g., because of reordering) is discarded. */ #define SSL_ENABLE_0RTT_DATA 33 +/* 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 + #ifdef SSL_DEPRECATED_FUNCTION /* Old deprecated function names */ -SSL_IMPORT SECStatus SSL_Enable(PRFileDesc *fd, int option, PRBool on); -SSL_IMPORT SECStatus SSL_EnableDefault(int option, PRBool on); +SSL_IMPORT SECStatus SSL_Enable(PRFileDesc *fd, int option, PRIntn on); +SSL_IMPORT SECStatus SSL_EnableDefault(int option, PRIntn on); #endif -/* New function names */ -SSL_IMPORT SECStatus SSL_OptionSet(PRFileDesc *fd, PRInt32 option, PRBool on); -SSL_IMPORT SECStatus SSL_OptionGet(PRFileDesc *fd, PRInt32 option, PRBool *on); -SSL_IMPORT SECStatus SSL_OptionSetDefault(PRInt32 option, PRBool on); -SSL_IMPORT SECStatus SSL_OptionGetDefault(PRInt32 option, PRBool *on); +/* Set (and get) options for sockets and defaults for newly created sockets. + * + * While the |val| parameter of these methods is PRIntn, options only support + * two values by default: PR_TRUE or PR_FALSE. The documentation of specific + * options will explain if other values are permitted. + */ +SSL_IMPORT SECStatus SSL_OptionSet(PRFileDesc *fd, PRInt32 option, PRIntn val); +SSL_IMPORT SECStatus SSL_OptionGet(PRFileDesc *fd, PRInt32 option, PRIntn *val); +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 @@ -1374,6 +1394,13 @@ extern const char *NSSSSL_GetVersion(void); */ SSL_IMPORT SECStatus SSL_AuthCertificateComplete(PRFileDesc *fd, PRErrorCode error); + +/* + * This is used to access experimental APIs. Don't call this directly. This is + * used to enable the experimental APIs that are defined in "sslexp.h". + */ +SSL_IMPORT void *SSL_GetExperimentalAPI(const char *name); + SEC_END_PROTOS #endif /* __ssl_h_ */ diff --git a/security/nss/lib/ssl/ssl3con.c b/security/nss/lib/ssl/ssl3con.c index 5cbe2bd09..2593bbacc 100644 --- a/security/nss/lib/ssl/ssl3con.c +++ b/security/nss/lib/ssl/ssl3con.c @@ -34,14 +34,13 @@ #include "blapi.h" #include <stdio.h> -#ifdef NSS_SSL_ENABLE_ZLIB -#include "zlib.h" -#endif static PK11SymKey *ssl3_GenerateRSAPMS(sslSocket *ss, ssl3CipherSpec *spec, PK11SlotInfo *serverKeySlot); -static SECStatus ssl3_DeriveMasterSecret(sslSocket *ss, PK11SymKey *pms); -static SECStatus ssl3_DeriveConnectionKeys(sslSocket *ss); +static SECStatus ssl3_ComputeMasterSecret(sslSocket *ss, PK11SymKey *pms, + PK11SymKey **msp); +static SECStatus ssl3_DeriveConnectionKeys(sslSocket *ss, + PK11SymKey *masterSecret); static SECStatus ssl3_HandshakeFailure(sslSocket *ss); static SECStatus ssl3_SendCertificate(sslSocket *ss); static SECStatus ssl3_SendCertificateRequest(sslSocket *ss); @@ -51,27 +50,28 @@ static SECStatus ssl3_SendServerHelloDone(sslSocket *ss); static SECStatus ssl3_SendServerKeyExchange(sslSocket *ss); static SECStatus ssl3_HandleClientHelloPart2(sslSocket *ss, SECItem *suites, - SECItem *comps, - sslSessionID *sid); + sslSessionID *sid, + const PRUint8 *msg, + unsigned int len); static SECStatus ssl3_HandleServerHelloPart2(sslSocket *ss, const SECItem *sidBytes, int *retErrCode); static SECStatus ssl3_HandlePostHelloHandshakeMessage(sslSocket *ss, PRUint8 *b, - PRUint32 length, - SSL3Hashes *hashesPtr); + PRUint32 length); static SECStatus ssl3_FlushHandshakeMessages(sslSocket *ss, PRInt32 flags); -static SECStatus Null_Cipher(void *ctx, unsigned char *output, int *outputLen, - int maxOutputLen, const unsigned char *input, - int inputLen); - static CK_MECHANISM_TYPE ssl3_GetHashMechanismByHashType(SSLHashType hashType); static CK_MECHANISM_TYPE ssl3_GetMgfMechanismByHashType(SSLHashType hash); PRBool ssl_IsRsaPssSignatureScheme(SSLSignatureScheme scheme); -#define MAX_SEND_BUF_LENGTH 32000 /* watch for 16-bit integer overflow */ -#define MIN_SEND_BUF_LENGTH 4000 +const PRUint8 ssl_hello_retry_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 +}; +PR_STATIC_ASSERT(PR_ARRAY_SIZE(ssl_hello_retry_random) == SSL3_RANDOM_LENGTH); /* This list of SSL3 cipher suites is sorted in descending order of * precedence (desirability). It only includes cipher suites we implement. @@ -183,9 +183,9 @@ static const SSLSignatureScheme defaultSignatureSchemes[] = { ssl_sig_ecdsa_secp384r1_sha384, ssl_sig_ecdsa_secp521r1_sha512, ssl_sig_ecdsa_sha1, - ssl_sig_rsa_pss_sha256, - ssl_sig_rsa_pss_sha384, - ssl_sig_rsa_pss_sha512, + ssl_sig_rsa_pss_rsae_sha256, + ssl_sig_rsa_pss_rsae_sha384, + ssl_sig_rsa_pss_rsae_sha512, ssl_sig_rsa_pkcs1_sha256, ssl_sig_rsa_pkcs1_sha384, ssl_sig_rsa_pkcs1_sha512, @@ -214,52 +214,6 @@ ssl3_CheckCipherSuiteOrderConsistency() } #endif -/* This list of SSL3 compression methods is sorted in descending order of - * precedence (desirability). It only includes compression methods we - * implement. - */ -static const SSLCompressionMethod ssl_compression_methods[] = { -#ifdef NSS_SSL_ENABLE_ZLIB - ssl_compression_deflate, -#endif - ssl_compression_null -}; - -static const unsigned int ssl_compression_method_count = - PR_ARRAY_SIZE(ssl_compression_methods); - -/* compressionEnabled returns true iff the compression algorithm is enabled - * for the given SSL socket. */ -static PRBool -ssl_CompressionEnabled(sslSocket *ss, SSLCompressionMethod compression) -{ - SSL3ProtocolVersion version; - - if (compression == ssl_compression_null) { - return PR_TRUE; /* Always enabled */ - } - if (ss->sec.isServer) { - /* We can't easily check that the client didn't attempt TLS 1.3, - * so this will have to do. */ - PORT_Assert(ss->version < SSL_LIBRARY_VERSION_TLS_1_3); - version = ss->version; - } else { - version = ss->vrange.max; - } - if (version >= SSL_LIBRARY_VERSION_TLS_1_3) { - return PR_FALSE; - } -#ifdef NSS_SSL_ENABLE_ZLIB - if (compression == ssl_compression_deflate) { - if (IS_DTLS(ss)) { - return PR_FALSE; - } - return ss->opt.enableDeflate; - } -#endif - return PR_FALSE; -} - static const /*SSL3ClientCertificateType */ PRUint8 certificate_types[] = { ct_RSA_sign, ct_ECDSA_sign, @@ -268,173 +222,125 @@ static const /*SSL3ClientCertificateType */ PRUint8 certificate_types[] = { static SSL3Statistics ssl3stats; -/* Record protection algorithms, indexed by SSL3BulkCipher. - * - * The |max_records| field (|mr| below) is set to a number that is higher than - * recommended in some literature (esp. TLS 1.3) because we currently abort the - * connection when this limit is reached and we want to ensure that we only - * rarely hit this limit. See bug 1268745 for details. - */ -#define MR_MAX RECORD_SEQ_MAX /* 2^48-1 */ -#define MR_128 (0x5aULL << 28) /* For AES and similar. */ -#define MR_LOW (1ULL << 20) /* For weak ciphers. */ -/* clang-format off */ -static const ssl3BulkCipherDef bulk_cipher_defs[] = { - /* |--------- Lengths ---------| */ - /* cipher calg : s : */ - /* : e b n */ - /* oid short_name mr : l o */ - /* k r o t n */ - /* e e i c a c */ - /* y t type v k g e */ - {cipher_null, calg_null, 0, 0, type_stream, 0, 0, 0, 0, - SEC_OID_NULL_CIPHER, "NULL", MR_MAX}, - {cipher_rc4, calg_rc4, 16,16, type_stream, 0, 0, 0, 0, - SEC_OID_RC4, "RC4", MR_LOW}, - {cipher_des, calg_des, 8, 8, type_block, 8, 8, 0, 0, - SEC_OID_DES_CBC, "DES-CBC", MR_LOW}, - {cipher_3des, calg_3des, 24,24, type_block, 8, 8, 0, 0, - SEC_OID_DES_EDE3_CBC, "3DES-EDE-CBC", MR_LOW}, - {cipher_aes_128, calg_aes, 16,16, type_block, 16,16, 0, 0, - SEC_OID_AES_128_CBC, "AES-128", MR_128}, - {cipher_aes_256, calg_aes, 32,32, type_block, 16,16, 0, 0, - SEC_OID_AES_256_CBC, "AES-256", MR_128}, - {cipher_camellia_128, calg_camellia, 16,16, type_block, 16,16, 0, 0, - SEC_OID_CAMELLIA_128_CBC, "Camellia-128", MR_128}, - {cipher_camellia_256, calg_camellia, 32,32, type_block, 16,16, 0, 0, - SEC_OID_CAMELLIA_256_CBC, "Camellia-256", MR_128}, - {cipher_seed, calg_seed, 16,16, type_block, 16,16, 0, 0, - SEC_OID_SEED_CBC, "SEED-CBC", MR_128}, - {cipher_aes_128_gcm, calg_aes_gcm, 16,16, type_aead, 4, 0,16, 8, - SEC_OID_AES_128_GCM, "AES-128-GCM", MR_128}, - {cipher_aes_256_gcm, calg_aes_gcm, 32,32, type_aead, 4, 0,16, 8, - SEC_OID_AES_256_GCM, "AES-256-GCM", MR_128}, - {cipher_chacha20, calg_chacha20, 32,32, type_aead, 12, 0,16, 0, - SEC_OID_CHACHA20_POLY1305, "ChaCha20-Poly1305", MR_MAX}, - {cipher_missing, calg_null, 0, 0, type_stream, 0, 0, 0, 0, - SEC_OID_UNKNOWN, "missing", 0U}, -}; - static const ssl3KEADef kea_defs[] = -{ /* indexed by SSL3KeyExchangeAlgorithm */ - /* kea exchKeyType signKeyType authKeyType ephemeral oid */ - {kea_null, ssl_kea_null, nullKey, ssl_auth_null, PR_FALSE, 0}, - {kea_rsa, ssl_kea_rsa, nullKey, ssl_auth_rsa_decrypt, PR_FALSE, SEC_OID_TLS_RSA}, - {kea_dh_dss, ssl_kea_dh, dsaKey, ssl_auth_dsa, PR_FALSE, SEC_OID_TLS_DH_DSS}, - {kea_dh_rsa, ssl_kea_dh, rsaKey, ssl_auth_rsa_sign, PR_FALSE, SEC_OID_TLS_DH_RSA}, - {kea_dhe_dss, ssl_kea_dh, dsaKey, ssl_auth_dsa, PR_TRUE, SEC_OID_TLS_DHE_DSS}, - {kea_dhe_rsa, ssl_kea_dh, rsaKey, ssl_auth_rsa_sign, PR_TRUE, SEC_OID_TLS_DHE_RSA}, - {kea_dh_anon, ssl_kea_dh, nullKey, ssl_auth_null, PR_TRUE, SEC_OID_TLS_DH_ANON}, - {kea_ecdh_ecdsa, ssl_kea_ecdh, nullKey, ssl_auth_ecdh_ecdsa, PR_FALSE, SEC_OID_TLS_ECDH_ECDSA}, - {kea_ecdhe_ecdsa, ssl_kea_ecdh, ecKey, ssl_auth_ecdsa, PR_TRUE, SEC_OID_TLS_ECDHE_ECDSA}, - {kea_ecdh_rsa, ssl_kea_ecdh, nullKey, ssl_auth_ecdh_rsa, PR_FALSE, SEC_OID_TLS_ECDH_RSA}, - {kea_ecdhe_rsa, ssl_kea_ecdh, rsaKey, ssl_auth_rsa_sign, PR_TRUE, SEC_OID_TLS_ECDHE_RSA}, - {kea_ecdh_anon, ssl_kea_ecdh, nullKey, ssl_auth_null, PR_TRUE, SEC_OID_TLS_ECDH_ANON}, - {kea_ecdhe_psk, ssl_kea_ecdh_psk, nullKey, ssl_auth_psk, PR_TRUE, SEC_OID_TLS_ECDHE_PSK}, - {kea_dhe_psk, ssl_kea_dh_psk, nullKey, ssl_auth_psk, PR_TRUE, SEC_OID_TLS_DHE_PSK}, - {kea_tls13_any, ssl_kea_tls13_any, nullKey, ssl_auth_tls13_any, PR_TRUE, SEC_OID_TLS13_KEA_ANY}, -}; + { + /* indexed by SSL3KeyExchangeAlgorithm */ + /* kea exchKeyType signKeyType authKeyType ephemeral oid */ + { kea_null, ssl_kea_null, nullKey, ssl_auth_null, PR_FALSE, 0 }, + { kea_rsa, ssl_kea_rsa, nullKey, ssl_auth_rsa_decrypt, PR_FALSE, SEC_OID_TLS_RSA }, + { kea_dh_dss, ssl_kea_dh, dsaKey, ssl_auth_dsa, PR_FALSE, SEC_OID_TLS_DH_DSS }, + { kea_dh_rsa, ssl_kea_dh, rsaKey, ssl_auth_rsa_sign, PR_FALSE, SEC_OID_TLS_DH_RSA }, + { kea_dhe_dss, ssl_kea_dh, dsaKey, ssl_auth_dsa, PR_TRUE, SEC_OID_TLS_DHE_DSS }, + { kea_dhe_rsa, ssl_kea_dh, rsaKey, ssl_auth_rsa_sign, PR_TRUE, SEC_OID_TLS_DHE_RSA }, + { kea_dh_anon, ssl_kea_dh, nullKey, ssl_auth_null, PR_TRUE, SEC_OID_TLS_DH_ANON }, + { kea_ecdh_ecdsa, ssl_kea_ecdh, nullKey, ssl_auth_ecdh_ecdsa, PR_FALSE, SEC_OID_TLS_ECDH_ECDSA }, + { kea_ecdhe_ecdsa, ssl_kea_ecdh, ecKey, ssl_auth_ecdsa, PR_TRUE, SEC_OID_TLS_ECDHE_ECDSA }, + { kea_ecdh_rsa, ssl_kea_ecdh, nullKey, ssl_auth_ecdh_rsa, PR_FALSE, SEC_OID_TLS_ECDH_RSA }, + { kea_ecdhe_rsa, ssl_kea_ecdh, rsaKey, ssl_auth_rsa_sign, PR_TRUE, SEC_OID_TLS_ECDHE_RSA }, + { kea_ecdh_anon, ssl_kea_ecdh, nullKey, ssl_auth_null, PR_TRUE, SEC_OID_TLS_ECDH_ANON }, + { kea_ecdhe_psk, ssl_kea_ecdh_psk, nullKey, ssl_auth_psk, PR_TRUE, SEC_OID_TLS_ECDHE_PSK }, + { kea_dhe_psk, ssl_kea_dh_psk, nullKey, ssl_auth_psk, PR_TRUE, SEC_OID_TLS_DHE_PSK }, + { kea_tls13_any, ssl_kea_tls13_any, nullKey, ssl_auth_tls13_any, PR_TRUE, SEC_OID_TLS13_KEA_ANY }, + }; /* must use ssl_LookupCipherSuiteDef to access */ static const ssl3CipherSuiteDef cipher_suite_defs[] = -{ -/* cipher_suite bulk_cipher_alg mac_alg key_exchange_alg prf_hash */ -/* Note that the prf_hash_alg is the hash function used by the PRF, see sslimpl.h. */ - - {TLS_NULL_WITH_NULL_NULL, cipher_null, mac_null, kea_null, ssl_hash_none}, - {TLS_RSA_WITH_NULL_MD5, cipher_null, mac_md5, kea_rsa, ssl_hash_none}, - {TLS_RSA_WITH_NULL_SHA, cipher_null, mac_sha, kea_rsa, ssl_hash_none}, - {TLS_RSA_WITH_NULL_SHA256, cipher_null, hmac_sha256, kea_rsa, ssl_hash_sha256}, - {TLS_RSA_WITH_RC4_128_MD5, cipher_rc4, mac_md5, kea_rsa, ssl_hash_none}, - {TLS_RSA_WITH_RC4_128_SHA, cipher_rc4, mac_sha, kea_rsa, ssl_hash_none}, - {TLS_RSA_WITH_DES_CBC_SHA, cipher_des, mac_sha, kea_rsa, ssl_hash_none}, - {TLS_RSA_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, kea_rsa, ssl_hash_none}, - {TLS_DHE_DSS_WITH_DES_CBC_SHA, cipher_des, mac_sha, kea_dhe_dss, ssl_hash_none}, - {TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA, - cipher_3des, mac_sha, kea_dhe_dss, ssl_hash_none}, - {TLS_DHE_DSS_WITH_RC4_128_SHA, cipher_rc4, mac_sha, kea_dhe_dss, ssl_hash_none}, - {TLS_DHE_RSA_WITH_DES_CBC_SHA, cipher_des, mac_sha, kea_dhe_rsa, ssl_hash_none}, - {TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, - cipher_3des, mac_sha, kea_dhe_rsa, ssl_hash_none}, - - -/* New TLS cipher suites */ - {TLS_RSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_rsa, ssl_hash_none}, - {TLS_RSA_WITH_AES_128_CBC_SHA256, cipher_aes_128, hmac_sha256, kea_rsa, ssl_hash_sha256}, - {TLS_DHE_DSS_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_dhe_dss, ssl_hash_none}, - {TLS_DHE_RSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_dhe_rsa, ssl_hash_none}, - {TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, cipher_aes_128, hmac_sha256, kea_dhe_rsa, ssl_hash_sha256}, - {TLS_RSA_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_rsa, ssl_hash_none}, - {TLS_RSA_WITH_AES_256_CBC_SHA256, cipher_aes_256, hmac_sha256, kea_rsa, ssl_hash_sha256}, - {TLS_DHE_DSS_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_dhe_dss, ssl_hash_none}, - {TLS_DHE_RSA_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_dhe_rsa, ssl_hash_none}, - {TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, cipher_aes_256, hmac_sha256, kea_dhe_rsa, ssl_hash_sha256}, - {TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, cipher_aes_256_gcm, mac_aead, kea_dhe_rsa, ssl_hash_sha384}, - - {TLS_RSA_WITH_SEED_CBC_SHA, cipher_seed, mac_sha, kea_rsa, ssl_hash_none}, - - {TLS_RSA_WITH_CAMELLIA_128_CBC_SHA, cipher_camellia_128, mac_sha, kea_rsa, ssl_hash_none}, - {TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA, - cipher_camellia_128, mac_sha, kea_dhe_dss, ssl_hash_none}, - {TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, - cipher_camellia_128, mac_sha, kea_dhe_rsa, ssl_hash_none}, - {TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, cipher_camellia_256, mac_sha, kea_rsa, ssl_hash_none}, - {TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA, - cipher_camellia_256, mac_sha, kea_dhe_dss, ssl_hash_none}, - {TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, - cipher_camellia_256, mac_sha, kea_dhe_rsa, ssl_hash_none}, - - {TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, mac_aead, kea_dhe_rsa, ssl_hash_sha256}, - {TLS_RSA_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, mac_aead, kea_rsa, ssl_hash_sha256}, - - {TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, mac_aead, kea_ecdhe_rsa, ssl_hash_sha256}, - {TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, mac_aead, kea_ecdhe_ecdsa, ssl_hash_sha256}, - {TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, cipher_aes_256_gcm, mac_aead, kea_ecdhe_ecdsa, ssl_hash_sha384}, - {TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, cipher_aes_256_gcm, mac_aead, kea_ecdhe_rsa, ssl_hash_sha384}, - {TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, cipher_aes_256, hmac_sha384, kea_ecdhe_ecdsa, ssl_hash_sha384}, - {TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, cipher_aes_256, hmac_sha384, kea_ecdhe_rsa, ssl_hash_sha384}, - {TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, mac_aead, kea_dhe_dss, ssl_hash_sha256}, - {TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, cipher_aes_128, hmac_sha256, kea_dhe_dss, ssl_hash_sha256}, - {TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, cipher_aes_256, hmac_sha256, kea_dhe_dss, ssl_hash_sha256}, - {TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, cipher_aes_256_gcm, mac_aead, kea_dhe_dss, ssl_hash_sha384}, - {TLS_RSA_WITH_AES_256_GCM_SHA384, cipher_aes_256_gcm, mac_aead, kea_rsa, ssl_hash_sha384}, - - {TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256, cipher_chacha20, mac_aead, kea_dhe_rsa, ssl_hash_sha256}, - - {TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, cipher_chacha20, mac_aead, kea_ecdhe_rsa, ssl_hash_sha256}, - {TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, cipher_chacha20, mac_aead, kea_ecdhe_ecdsa, ssl_hash_sha256}, - - {TLS_ECDH_ECDSA_WITH_NULL_SHA, cipher_null, mac_sha, kea_ecdh_ecdsa, ssl_hash_none}, - {TLS_ECDH_ECDSA_WITH_RC4_128_SHA, cipher_rc4, mac_sha, kea_ecdh_ecdsa, ssl_hash_none}, - {TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, kea_ecdh_ecdsa, ssl_hash_none}, - {TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_ecdh_ecdsa, ssl_hash_none}, - {TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_ecdh_ecdsa, ssl_hash_none}, - - {TLS_ECDHE_ECDSA_WITH_NULL_SHA, cipher_null, mac_sha, kea_ecdhe_ecdsa, ssl_hash_none}, - {TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, cipher_rc4, mac_sha, kea_ecdhe_ecdsa, ssl_hash_none}, - {TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, kea_ecdhe_ecdsa, ssl_hash_none}, - {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_ecdhe_ecdsa, ssl_hash_none}, - {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, cipher_aes_128, hmac_sha256, kea_ecdhe_ecdsa, ssl_hash_sha256}, - {TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_ecdhe_ecdsa, ssl_hash_none}, - - {TLS_ECDH_RSA_WITH_NULL_SHA, cipher_null, mac_sha, kea_ecdh_rsa, ssl_hash_none}, - {TLS_ECDH_RSA_WITH_RC4_128_SHA, cipher_rc4, mac_sha, kea_ecdh_rsa, ssl_hash_none}, - {TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, kea_ecdh_rsa, ssl_hash_none}, - {TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_ecdh_rsa, ssl_hash_none}, - {TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_ecdh_rsa, ssl_hash_none}, - - {TLS_ECDHE_RSA_WITH_NULL_SHA, cipher_null, mac_sha, kea_ecdhe_rsa, ssl_hash_none}, - {TLS_ECDHE_RSA_WITH_RC4_128_SHA, cipher_rc4, mac_sha, kea_ecdhe_rsa, ssl_hash_none}, - {TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, kea_ecdhe_rsa, ssl_hash_none}, - {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_ecdhe_rsa, ssl_hash_none}, - {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, cipher_aes_128, hmac_sha256, kea_ecdhe_rsa, ssl_hash_sha256}, - {TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_ecdhe_rsa, ssl_hash_none}, - - {TLS_AES_128_GCM_SHA256, cipher_aes_128_gcm, mac_aead, kea_tls13_any, ssl_hash_sha256}, - {TLS_CHACHA20_POLY1305_SHA256, cipher_chacha20, mac_aead, kea_tls13_any, ssl_hash_sha256}, - {TLS_AES_256_GCM_SHA384, cipher_aes_256_gcm, mac_aead, kea_tls13_any, ssl_hash_sha384}, -}; -/* clang-format on */ + { + /* cipher_suite bulk_cipher_alg mac_alg key_exchange_alg prf_hash */ + /* Note that the prf_hash_alg is the hash function used by the PRF, see sslimpl.h. */ + + { TLS_NULL_WITH_NULL_NULL, cipher_null, ssl_mac_null, kea_null, ssl_hash_none }, + { TLS_RSA_WITH_NULL_MD5, cipher_null, ssl_mac_md5, kea_rsa, ssl_hash_none }, + { TLS_RSA_WITH_NULL_SHA, cipher_null, ssl_mac_sha, kea_rsa, ssl_hash_none }, + { TLS_RSA_WITH_NULL_SHA256, cipher_null, ssl_hmac_sha256, kea_rsa, ssl_hash_sha256 }, + { TLS_RSA_WITH_RC4_128_MD5, cipher_rc4, ssl_mac_md5, kea_rsa, ssl_hash_none }, + { TLS_RSA_WITH_RC4_128_SHA, cipher_rc4, ssl_mac_sha, kea_rsa, ssl_hash_none }, + { TLS_RSA_WITH_DES_CBC_SHA, cipher_des, ssl_mac_sha, kea_rsa, ssl_hash_none }, + { TLS_RSA_WITH_3DES_EDE_CBC_SHA, cipher_3des, ssl_mac_sha, kea_rsa, ssl_hash_none }, + { TLS_DHE_DSS_WITH_DES_CBC_SHA, cipher_des, ssl_mac_sha, kea_dhe_dss, ssl_hash_none }, + { TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA, + cipher_3des, ssl_mac_sha, kea_dhe_dss, ssl_hash_none }, + { TLS_DHE_DSS_WITH_RC4_128_SHA, cipher_rc4, ssl_mac_sha, kea_dhe_dss, ssl_hash_none }, + { TLS_DHE_RSA_WITH_DES_CBC_SHA, cipher_des, ssl_mac_sha, kea_dhe_rsa, ssl_hash_none }, + { TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, + cipher_3des, ssl_mac_sha, kea_dhe_rsa, ssl_hash_none }, + + /* New TLS cipher suites */ + { TLS_RSA_WITH_AES_128_CBC_SHA, cipher_aes_128, ssl_mac_sha, kea_rsa, ssl_hash_none }, + { TLS_RSA_WITH_AES_128_CBC_SHA256, cipher_aes_128, ssl_hmac_sha256, kea_rsa, ssl_hash_sha256 }, + { TLS_DHE_DSS_WITH_AES_128_CBC_SHA, cipher_aes_128, ssl_mac_sha, kea_dhe_dss, ssl_hash_none }, + { TLS_DHE_RSA_WITH_AES_128_CBC_SHA, cipher_aes_128, ssl_mac_sha, kea_dhe_rsa, ssl_hash_none }, + { TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, cipher_aes_128, ssl_hmac_sha256, kea_dhe_rsa, ssl_hash_sha256 }, + { TLS_RSA_WITH_AES_256_CBC_SHA, cipher_aes_256, ssl_mac_sha, kea_rsa, ssl_hash_none }, + { TLS_RSA_WITH_AES_256_CBC_SHA256, cipher_aes_256, ssl_hmac_sha256, kea_rsa, ssl_hash_sha256 }, + { TLS_DHE_DSS_WITH_AES_256_CBC_SHA, cipher_aes_256, ssl_mac_sha, kea_dhe_dss, ssl_hash_none }, + { TLS_DHE_RSA_WITH_AES_256_CBC_SHA, cipher_aes_256, ssl_mac_sha, kea_dhe_rsa, ssl_hash_none }, + { TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, cipher_aes_256, ssl_hmac_sha256, kea_dhe_rsa, ssl_hash_sha256 }, + { TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, cipher_aes_256_gcm, ssl_mac_aead, kea_dhe_rsa, ssl_hash_sha384 }, + + { TLS_RSA_WITH_SEED_CBC_SHA, cipher_seed, ssl_mac_sha, kea_rsa, ssl_hash_none }, + + { TLS_RSA_WITH_CAMELLIA_128_CBC_SHA, cipher_camellia_128, ssl_mac_sha, kea_rsa, ssl_hash_none }, + { TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA, + cipher_camellia_128, ssl_mac_sha, kea_dhe_dss, ssl_hash_none }, + { TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, + cipher_camellia_128, ssl_mac_sha, kea_dhe_rsa, ssl_hash_none }, + { TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, cipher_camellia_256, ssl_mac_sha, kea_rsa, ssl_hash_none }, + { TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA, + cipher_camellia_256, ssl_mac_sha, kea_dhe_dss, ssl_hash_none }, + { TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, + cipher_camellia_256, ssl_mac_sha, kea_dhe_rsa, ssl_hash_none }, + + { TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, ssl_mac_aead, kea_dhe_rsa, ssl_hash_sha256 }, + { TLS_RSA_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, ssl_mac_aead, kea_rsa, ssl_hash_sha256 }, + + { TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, ssl_mac_aead, kea_ecdhe_rsa, ssl_hash_sha256 }, + { TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, ssl_mac_aead, kea_ecdhe_ecdsa, ssl_hash_sha256 }, + { TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, cipher_aes_256_gcm, ssl_mac_aead, kea_ecdhe_ecdsa, ssl_hash_sha384 }, + { TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, cipher_aes_256_gcm, ssl_mac_aead, kea_ecdhe_rsa, ssl_hash_sha384 }, + { TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, cipher_aes_256, ssl_hmac_sha384, kea_ecdhe_ecdsa, ssl_hash_sha384 }, + { TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, cipher_aes_256, ssl_hmac_sha384, kea_ecdhe_rsa, ssl_hash_sha384 }, + { TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, ssl_mac_aead, kea_dhe_dss, ssl_hash_sha256 }, + { TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, cipher_aes_128, ssl_hmac_sha256, kea_dhe_dss, ssl_hash_sha256 }, + { TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, cipher_aes_256, ssl_hmac_sha256, kea_dhe_dss, ssl_hash_sha256 }, + { TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, cipher_aes_256_gcm, ssl_mac_aead, kea_dhe_dss, ssl_hash_sha384 }, + { TLS_RSA_WITH_AES_256_GCM_SHA384, cipher_aes_256_gcm, ssl_mac_aead, kea_rsa, ssl_hash_sha384 }, + + { TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256, cipher_chacha20, ssl_mac_aead, kea_dhe_rsa, ssl_hash_sha256 }, + + { TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, cipher_chacha20, ssl_mac_aead, kea_ecdhe_rsa, ssl_hash_sha256 }, + { TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, cipher_chacha20, ssl_mac_aead, kea_ecdhe_ecdsa, ssl_hash_sha256 }, + + { TLS_ECDH_ECDSA_WITH_NULL_SHA, cipher_null, ssl_mac_sha, kea_ecdh_ecdsa, ssl_hash_none }, + { TLS_ECDH_ECDSA_WITH_RC4_128_SHA, cipher_rc4, ssl_mac_sha, kea_ecdh_ecdsa, ssl_hash_none }, + { TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, cipher_3des, ssl_mac_sha, kea_ecdh_ecdsa, ssl_hash_none }, + { TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, cipher_aes_128, ssl_mac_sha, kea_ecdh_ecdsa, ssl_hash_none }, + { TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, cipher_aes_256, ssl_mac_sha, kea_ecdh_ecdsa, ssl_hash_none }, + + { TLS_ECDHE_ECDSA_WITH_NULL_SHA, cipher_null, ssl_mac_sha, kea_ecdhe_ecdsa, ssl_hash_none }, + { TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, cipher_rc4, ssl_mac_sha, kea_ecdhe_ecdsa, ssl_hash_none }, + { TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, cipher_3des, ssl_mac_sha, kea_ecdhe_ecdsa, ssl_hash_none }, + { TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, cipher_aes_128, ssl_mac_sha, kea_ecdhe_ecdsa, ssl_hash_none }, + { TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, cipher_aes_128, ssl_hmac_sha256, kea_ecdhe_ecdsa, ssl_hash_sha256 }, + { TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, cipher_aes_256, ssl_mac_sha, kea_ecdhe_ecdsa, ssl_hash_none }, + + { TLS_ECDH_RSA_WITH_NULL_SHA, cipher_null, ssl_mac_sha, kea_ecdh_rsa, ssl_hash_none }, + { TLS_ECDH_RSA_WITH_RC4_128_SHA, cipher_rc4, ssl_mac_sha, kea_ecdh_rsa, ssl_hash_none }, + { TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, cipher_3des, ssl_mac_sha, kea_ecdh_rsa, ssl_hash_none }, + { TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, cipher_aes_128, ssl_mac_sha, kea_ecdh_rsa, ssl_hash_none }, + { TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, cipher_aes_256, ssl_mac_sha, kea_ecdh_rsa, ssl_hash_none }, + + { TLS_ECDHE_RSA_WITH_NULL_SHA, cipher_null, ssl_mac_sha, kea_ecdhe_rsa, ssl_hash_none }, + { TLS_ECDHE_RSA_WITH_RC4_128_SHA, cipher_rc4, ssl_mac_sha, kea_ecdhe_rsa, ssl_hash_none }, + { TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, cipher_3des, ssl_mac_sha, kea_ecdhe_rsa, ssl_hash_none }, + { TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, cipher_aes_128, ssl_mac_sha, kea_ecdhe_rsa, ssl_hash_none }, + { TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, cipher_aes_128, ssl_hmac_sha256, kea_ecdhe_rsa, ssl_hash_sha256 }, + { TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, cipher_aes_256, ssl_mac_sha, kea_ecdhe_rsa, ssl_hash_none }, + + { TLS_AES_128_GCM_SHA256, cipher_aes_128_gcm, ssl_mac_aead, kea_tls13_any, ssl_hash_sha256 }, + { TLS_CHACHA20_POLY1305_SHA256, cipher_chacha20, ssl_mac_aead, kea_tls13_any, ssl_hash_sha256 }, + { TLS_AES_256_GCM_SHA384, cipher_aes_256_gcm, ssl_mac_aead, kea_tls13_any, ssl_hash_sha384 }, + }; static const CK_MECHANISM_TYPE auth_alg_defs[] = { CKM_INVALID_MECHANISM, /* ssl_auth_null */ @@ -471,43 +377,19 @@ typedef struct SSLCipher2MechStr { /* indexed by type SSLCipherAlgorithm */ static const SSLCipher2Mech alg2Mech[] = { /* calg, cmech */ - { calg_null, (CK_MECHANISM_TYPE)0x80000000L }, - { calg_rc4, CKM_RC4 }, - { calg_rc2, CKM_RC2_CBC }, - { calg_des, CKM_DES_CBC }, - { calg_3des, CKM_DES3_CBC }, - { calg_idea, CKM_IDEA_CBC }, - { calg_fortezza, CKM_SKIPJACK_CBC64 }, - { calg_aes, CKM_AES_CBC }, - { calg_camellia, CKM_CAMELLIA_CBC }, - { calg_seed, CKM_SEED_CBC }, - { calg_aes_gcm, CKM_AES_GCM }, - { calg_chacha20, CKM_NSS_CHACHA20_POLY1305 }, - /* { calg_init , (CK_MECHANISM_TYPE)0x7fffffffL } */ -}; - -#define mmech_invalid (CK_MECHANISM_TYPE)0x80000000L -#define mmech_md5 CKM_SSL3_MD5_MAC -#define mmech_sha CKM_SSL3_SHA1_MAC -#define mmech_md5_hmac CKM_MD5_HMAC -#define mmech_sha_hmac CKM_SHA_1_HMAC -#define mmech_sha256_hmac CKM_SHA256_HMAC -#define mmech_sha384_hmac CKM_SHA384_HMAC - -/* clang-format off */ -static const ssl3MACDef mac_defs[] = { /* indexed by SSL3MACAlgorithm */ - /* pad_size is only used for SSL 3.0 MAC. See RFC 6101 Sec. 5.2.3.1. */ - /* mac mmech pad_size mac_size */ - { mac_null, mmech_invalid, 0, 0 , 0}, - { mac_md5, mmech_md5, 48, MD5_LENGTH, SEC_OID_HMAC_MD5 }, - { mac_sha, mmech_sha, 40, SHA1_LENGTH, SEC_OID_HMAC_SHA1}, - {hmac_md5, mmech_md5_hmac, 0, MD5_LENGTH, SEC_OID_HMAC_MD5}, - {hmac_sha, mmech_sha_hmac, 0, SHA1_LENGTH, SEC_OID_HMAC_SHA1}, - {hmac_sha256, mmech_sha256_hmac, 0, SHA256_LENGTH, SEC_OID_HMAC_SHA256}, - { mac_aead, mmech_invalid, 0, 0, 0 }, - {hmac_sha384, mmech_sha384_hmac, 0, SHA384_LENGTH, SEC_OID_HMAC_SHA384} + { ssl_calg_null, CKM_INVALID_MECHANISM }, + { ssl_calg_rc4, CKM_RC4 }, + { ssl_calg_rc2, CKM_RC2_CBC }, + { ssl_calg_des, CKM_DES_CBC }, + { ssl_calg_3des, CKM_DES3_CBC }, + { ssl_calg_idea, CKM_IDEA_CBC }, + { ssl_calg_fortezza, CKM_SKIPJACK_CBC64 }, + { ssl_calg_aes, CKM_AES_CBC }, + { ssl_calg_camellia, CKM_CAMELLIA_CBC }, + { ssl_calg_seed, CKM_SEED_CBC }, + { ssl_calg_aes_gcm, CKM_AES_GCM }, + { ssl_calg_chacha20, CKM_NSS_CHACHA20_POLY1305 }, }; -/* clang-format on */ const PRUint8 tls13_downgrade_random[] = { 0x44, 0x4F, 0x57, 0x4E, 0x47, 0x52, 0x44, 0x01 }; @@ -554,48 +436,57 @@ ssl3_DecodeHandshakeType(int msgType) static char line[40]; switch (msgType) { - case hello_request: + case ssl_hs_hello_request: rv = "hello_request (0)"; break; - case client_hello: + case ssl_hs_client_hello: rv = "client_hello (1)"; break; - case server_hello: + case ssl_hs_server_hello: rv = "server_hello (2)"; break; - case hello_verify_request: + case ssl_hs_hello_verify_request: rv = "hello_verify_request (3)"; break; - case new_session_ticket: - rv = "session_ticket (4)"; + case ssl_hs_new_session_ticket: + rv = "new_session_ticket (4)"; + break; + case ssl_hs_end_of_early_data: + rv = "end_of_early_data (5)"; break; - case hello_retry_request: + case ssl_hs_hello_retry_request: rv = "hello_retry_request (6)"; break; - case encrypted_extensions: + case ssl_hs_encrypted_extensions: rv = "encrypted_extensions (8)"; break; - case certificate: + case ssl_hs_certificate: rv = "certificate (11)"; break; - case server_key_exchange: + case ssl_hs_server_key_exchange: rv = "server_key_exchange (12)"; break; - case certificate_request: + case ssl_hs_certificate_request: rv = "certificate_request (13)"; break; - case server_hello_done: + case ssl_hs_server_hello_done: rv = "server_hello_done (14)"; break; - case certificate_verify: + case ssl_hs_certificate_verify: rv = "certificate_verify (15)"; break; - case client_key_exchange: + case ssl_hs_client_key_exchange: rv = "client_key_exchange (16)"; break; - case finished: + case ssl_hs_finished: rv = "finished (20)"; break; + case ssl_hs_certificate_status: + rv = "certificate_status (22)"; + break; + case ssl_hs_key_update: + rv = "key_update (24)"; + break; default: sprintf(line, "*UNKNOWN* handshake type! (%d)", msgType); rv = line; @@ -622,6 +513,9 @@ ssl3_DecodeContentType(int msgType) case content_application_data: rv = "application_data (23)"; break; + case content_ack: + rv = "ack (25)"; + break; default: sprintf(line, "*UNKNOWN* record type! (%d)", msgType); rv = line; @@ -874,20 +768,12 @@ ssl_HasCert(const sslSocket *ss, SSLAuthType authType) return PR_FALSE; } -const ssl3BulkCipherDef * -ssl_GetBulkCipherDef(const ssl3CipherSuiteDef *cipher_def) -{ - PORT_Assert(cipher_def->bulk_cipher_alg < PR_ARRAY_SIZE(bulk_cipher_defs)); - PORT_Assert(bulk_cipher_defs[cipher_def->bulk_cipher_alg].cipher == cipher_def->bulk_cipher_alg); - return &bulk_cipher_defs[cipher_def->bulk_cipher_alg]; -} - /* Initialize the suite->isPresent value for config_match * Returns count of enabled ciphers supported by extant tokens, * regardless of policy or user preference. * If this returns zero, the user cannot do SSL v3. */ -int +unsigned int ssl3_config_match_init(sslSocket *ss) { ssl3CipherSuiteCfg *suite; @@ -896,9 +782,9 @@ ssl3_config_match_init(sslSocket *ss) CK_MECHANISM_TYPE cipher_mech; SSLAuthType authType; SSLKEAType keaType; - int i; - int numPresent = 0; - int numEnabled = 0; + unsigned int i; + unsigned int numPresent = 0; + unsigned int numEnabled = 0; PORT_Assert(ss); if (!ss) { @@ -909,6 +795,7 @@ ssl3_config_match_init(sslSocket *ss) return 0; } + ssl_FilterSupportedGroups(ss); for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) { suite = &ss->cipherSuites[i]; if (suite->enabled) { @@ -944,7 +831,7 @@ ssl3_config_match_init(sslSocket *ss) suite->isPresent = PR_FALSE; } - if (cipher_alg != calg_null && + if (cipher_alg != ssl_calg_null && !PK11_TokenExists(cipher_mech)) { suite->isPresent = PR_FALSE; } @@ -955,7 +842,7 @@ ssl3_config_match_init(sslSocket *ss) } } PORT_Assert(numPresent > 0 || numEnabled == 0); - if (numPresent <= 0) { + if (numPresent == 0) { PORT_SetError(SSL_ERROR_NO_CIPHERS_SUPPORTED); } return numPresent; @@ -965,7 +852,7 @@ ssl3_config_match_init(sslSocket *ss) * enabled, has a certificate (as needed), has a viable key agreement method, is * usable with the negotiated TLS version, and is otherwise usable. */ static PRBool -config_match(const ssl3CipherSuiteCfg *suite, int policy, +config_match(const ssl3CipherSuiteCfg *suite, PRUint8 policy, const SSLVersionRange *vrange, const sslSocket *ss) { const ssl3CipherSuiteDef *cipher_def; @@ -1000,10 +887,10 @@ config_match(const ssl3CipherSuiteCfg *suite, int policy, /* Return the number of cipher suites that are usable. */ /* called from ssl3_SendClientHello */ -static int -count_cipher_suites(sslSocket *ss, int policy) +static unsigned int +count_cipher_suites(sslSocket *ss, PRUint8 policy) { - int i, count = 0; + unsigned int i, count = 0; if (SSL_ALL_VERSIONS_DISABLED(&ss->vrange)) { return 0; @@ -1012,7 +899,7 @@ count_cipher_suites(sslSocket *ss, int policy) if (config_match(&ss->cipherSuites[i], policy, &ss->vrange, ss)) count++; } - if (count <= 0) { + if (count == 0) { PORT_SetError(SSL_ERROR_SSL_DISABLED); } return count; @@ -1021,7 +908,7 @@ count_cipher_suites(sslSocket *ss, int policy) /* * Null compression, mac and encryption functions */ -static SECStatus +SECStatus Null_Cipher(void *ctx, unsigned char *output, int *outputLen, int maxOutputLen, const unsigned char *input, int inputLen) { @@ -1041,6 +928,19 @@ Null_Cipher(void *ctx, unsigned char *output, int *outputLen, int maxOutputLen, * SSL3 Utility functions */ +static void +ssl_SetSpecVersions(sslSocket *ss, ssl3CipherSpec *spec) +{ + spec->version = ss->version; + if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) { + tls13_SetSpecRecordVersion(ss, spec); + } else if (IS_DTLS(ss)) { + spec->recordVersion = dtls_TLSVersionToDTLSVersion(ss->version); + } else { + spec->recordVersion = ss->version; + } +} + /* allowLargerPeerVersion controls whether the function will select the * highest enabled SSL version or fail when peerVersion is greater than the * highest enabled version. @@ -1052,6 +952,8 @@ SECStatus ssl3_NegotiateVersion(sslSocket *ss, SSL3ProtocolVersion peerVersion, PRBool allowLargerPeerVersion) { + SSL3ProtocolVersion negotiated; + if (SSL_ALL_VERSIONS_DISABLED(&ss->vrange)) { PORT_SetError(SSL_ERROR_SSL_DISABLED); return SECFailure; @@ -1063,9 +965,14 @@ ssl3_NegotiateVersion(sslSocket *ss, SSL3ProtocolVersion peerVersion, return SECFailure; } - ss->version = PR_MIN(peerVersion, ss->vrange.max); - PORT_Assert(ssl3_VersionIsSupported(ss->protocolVariant, ss->version)); + negotiated = PR_MIN(peerVersion, ss->vrange.max); + PORT_Assert(ssl3_VersionIsSupported(ss->protocolVariant, negotiated)); + if (ss->firstHsDone && ss->version != negotiated) { + PORT_SetError(SSL_ERROR_UNSUPPORTED_VERSION); + return SECFailure; + } + ss->version = negotiated; return SECSuccess; } @@ -1104,24 +1011,16 @@ ssl_ClientReadVersion(sslSocket *ss, PRUint8 **b, unsigned int *len, v = dtls_DTLSVersionToTLSVersion(v); } - PORT_Assert(!SSL_ALL_VERSIONS_DISABLED(&ss->vrange)); - if (ss->vrange.min > v || ss->vrange.max < v) { - (void)SSL3_SendAlert(ss, alert_fatal, - (v > SSL_LIBRARY_VERSION_3_0) ? protocol_version - : handshake_failure); - PORT_SetError(SSL_ERROR_UNSUPPORTED_VERSION); - return SECFailure; - } *version = v; return SECSuccess; } static SECStatus -ssl3_GetNewRandom(SSL3Random *random) +ssl3_GetNewRandom(SSL3Random random) { SECStatus rv; - rv = PK11_GenerateRandom(random->rand, SSL3_RANDOM_LENGTH); + rv = PK11_GenerateRandom(random, SSL3_RANDOM_LENGTH); if (rv != SECSuccess) { ssl_MapLowLevelError(SSL_ERROR_GENERATE_RANDOM_FAILURE); } @@ -1135,7 +1034,7 @@ ssl3_SignHashes(sslSocket *ss, SSL3Hashes *hash, SECKEYPrivateKey *key, { SECStatus rv = SECFailure; PRBool doDerEncode = PR_FALSE; - PRBool isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0); + PRBool isTLS = (PRBool)(ss->version > SSL_LIBRARY_VERSION_3_0); PRBool useRsaPss = ssl_IsRsaPssSignatureScheme(ss->ssl3.hs.signatureScheme); SECItem hashItem; @@ -1421,124 +1320,110 @@ static SECStatus ssl3_ComputeDHKeyHash(sslSocket *ss, SSLHashType hashAlg, SSL3Hashes *hashes, SECItem dh_p, SECItem dh_g, SECItem dh_Ys, PRBool padY) { - PRUint8 *hashBuf; - PRUint8 *pBuf; - SECStatus rv = SECSuccess; - unsigned int bufLen, yLen; - PRUint8 buf[2 * SSL3_RANDOM_LENGTH + 2 + 4096 / 8 + 2 + 4096 / 8]; + sslBuffer buf = SSL_BUFFER_EMPTY; + SECStatus rv; + unsigned int yLen; + unsigned int i; PORT_Assert(dh_p.data); PORT_Assert(dh_g.data); PORT_Assert(dh_Ys.data); - yLen = padY ? dh_p.len : dh_Ys.len; - bufLen = 2 * SSL3_RANDOM_LENGTH + - 2 + dh_p.len + - 2 + dh_g.len + - 2 + yLen; - if (bufLen <= sizeof buf) { - hashBuf = buf; - } else { - hashBuf = PORT_Alloc(bufLen); - if (!hashBuf) { - return SECFailure; - } + rv = sslBuffer_Append(&buf, ss->ssl3.hs.client_random, SSL3_RANDOM_LENGTH); + if (rv != SECSuccess) { + goto loser; } - - memcpy(hashBuf, &ss->ssl3.hs.client_random, SSL3_RANDOM_LENGTH); - pBuf = hashBuf + SSL3_RANDOM_LENGTH; - memcpy(pBuf, &ss->ssl3.hs.server_random, SSL3_RANDOM_LENGTH); - pBuf += SSL3_RANDOM_LENGTH; - pBuf = ssl_EncodeUintX(dh_p.len, 2, pBuf); - memcpy(pBuf, dh_p.data, dh_p.len); - pBuf += dh_p.len; - pBuf = ssl_EncodeUintX(dh_g.len, 2, pBuf); - memcpy(pBuf, dh_g.data, dh_g.len); - pBuf += dh_g.len; - pBuf = ssl_EncodeUintX(yLen, 2, pBuf); - if (padY && dh_p.len > dh_Ys.len) { - memset(pBuf, 0, dh_p.len - dh_Ys.len); - pBuf += dh_p.len - dh_Ys.len; + rv = sslBuffer_Append(&buf, ss->ssl3.hs.server_random, SSL3_RANDOM_LENGTH); + if (rv != SECSuccess) { + goto loser; + } + /* p */ + rv = sslBuffer_AppendVariable(&buf, dh_p.data, dh_p.len, 2); + if (rv != SECSuccess) { + goto loser; + } + /* g */ + rv = sslBuffer_AppendVariable(&buf, dh_g.data, dh_g.len, 2); + if (rv != SECSuccess) { + goto loser; + } + /* y - complicated by padding */ + yLen = padY ? dh_p.len : dh_Ys.len; + rv = sslBuffer_AppendNumber(&buf, yLen, 2); + if (rv != SECSuccess) { + goto loser; } /* If we're padding Y, dh_Ys can't be longer than dh_p. */ PORT_Assert(!padY || dh_p.len >= dh_Ys.len); - memcpy(pBuf, dh_Ys.data, dh_Ys.len); - pBuf += dh_Ys.len; - PORT_Assert((unsigned int)(pBuf - hashBuf) == bufLen); - - rv = ssl3_ComputeCommonKeyHash(hashAlg, hashBuf, bufLen, hashes); - - PRINT_BUF(95, (NULL, "DHkey hash: ", hashBuf, bufLen)); - if (rv == SECSuccess) { - if (hashAlg == ssl_hash_none) { - PRINT_BUF(95, (NULL, "DHkey hash: MD5 result", - hashes->u.s.md5, MD5_LENGTH)); - PRINT_BUF(95, (NULL, "DHkey hash: SHA1 result", - hashes->u.s.sha, SHA1_LENGTH)); - } else { - PRINT_BUF(95, (NULL, "DHkey hash: result", - hashes->u.raw, hashes->len)); + for (i = dh_Ys.len; i < yLen; ++i) { + rv = sslBuffer_AppendNumber(&buf, 0, 1); + if (rv != SECSuccess) { + goto loser; } } - - if (hashBuf != buf && hashBuf != NULL) - PORT_Free(hashBuf); - return rv; -} - -/* Called twice, only from ssl3_DestroyCipherSpec (immediately below). */ -static void -ssl3_CleanupKeyMaterial(ssl3KeyMaterial *mat) -{ - if (mat->write_key != NULL) { - PK11_FreeSymKey(mat->write_key); - mat->write_key = NULL; + rv = sslBuffer_Append(&buf, dh_Ys.data, dh_Ys.len); + if (rv != SECSuccess) { + goto loser; } - if (mat->write_mac_key != NULL) { - PK11_FreeSymKey(mat->write_mac_key); - mat->write_mac_key = NULL; + + rv = ssl3_ComputeCommonKeyHash(hashAlg, SSL_BUFFER_BASE(&buf), + SSL_BUFFER_LEN(&buf), hashes); + if (rv != SECSuccess) { + goto loser; } - if (mat->write_mac_context != NULL) { - PK11_DestroyContext(mat->write_mac_context, PR_TRUE); - mat->write_mac_context = NULL; + + PRINT_BUF(95, (NULL, "DHkey hash: ", SSL_BUFFER_BASE(&buf), + SSL_BUFFER_LEN(&buf))); + if (hashAlg == ssl_hash_none) { + PRINT_BUF(95, (NULL, "DHkey hash: MD5 result", + hashes->u.s.md5, MD5_LENGTH)); + PRINT_BUF(95, (NULL, "DHkey hash: SHA1 result", + hashes->u.s.sha, SHA1_LENGTH)); + } else { + PRINT_BUF(95, (NULL, "DHkey hash: result", + hashes->u.raw, hashes->len)); } + + sslBuffer_Clear(&buf); + return SECSuccess; + +loser: + sslBuffer_Clear(&buf); + return SECFailure; } -/* Called from ssl3_SendChangeCipherSpecs() and -** ssl3_HandleChangeCipherSpecs() -** ssl3_DestroySSL3Info -** Caller must hold SpecWriteLock. -*/ -void -ssl3_DestroyCipherSpec(ssl3CipherSpec *spec, PRBool freeSrvName) +static SECStatus +ssl3_SetupPendingCipherSpec(sslSocket *ss, CipherSpecDirection direction, + const ssl3CipherSuiteDef *suiteDef, + ssl3CipherSpec **specp) { - /* PORT_Assert( ss->opt.noLocks || ssl_HaveSpecWriteLock(ss)); Don't have ss! */ - if (spec->encodeContext) { - PK11_DestroyContext(spec->encodeContext, PR_TRUE); - spec->encodeContext = NULL; - } - if (spec->decodeContext) { - PK11_DestroyContext(spec->decodeContext, PR_TRUE); - spec->decodeContext = NULL; - } - if (spec->destroyCompressContext && spec->compressContext) { - spec->destroyCompressContext(spec->compressContext, 1); - spec->compressContext = NULL; + ssl3CipherSpec *spec; + const ssl3CipherSpec *prev; + + prev = (direction == CipherSpecWrite) ? ss->ssl3.cwSpec : ss->ssl3.crSpec; + if (prev->epoch == PR_UINT16_MAX) { + PORT_SetError(SSL_ERROR_RENEGOTIATION_NOT_ALLOWED); + return SECFailure; } - if (spec->destroyDecompressContext && spec->decompressContext) { - spec->destroyDecompressContext(spec->decompressContext, 1); - spec->decompressContext = NULL; + + spec = ssl_CreateCipherSpec(ss, direction); + if (!spec) { + return SECFailure; } - if (spec->master_secret != NULL) { - PK11_FreeSymKey(spec->master_secret); - spec->master_secret = NULL; + + spec->cipherDef = ssl_GetBulkCipherDef(suiteDef); + spec->macDef = ssl_GetMacDef(ss, suiteDef); + + spec->epoch = prev->epoch + 1; + spec->seqNum = 0; + if (IS_DTLS(ss) && direction == CipherSpecRead) { + dtls_InitRecvdRecords(&spec->recvdRecords); } - spec->msItem.data = NULL; - spec->msItem.len = 0; - ssl3_CleanupKeyMaterial(&spec->client); - ssl3_CleanupKeyMaterial(&spec->server); - spec->destroyCompressContext = NULL; - spec->destroyDecompressContext = NULL; + ssl_SetSpecVersions(ss, spec); + + ssl_SaveCipherSpec(ss, spec); + *specp = spec; + return SECSuccess; } /* Fill in the pending cipher spec with info from the selected ciphersuite. @@ -1548,272 +1433,116 @@ ssl3_DestroyCipherSpec(ssl3CipherSpec *spec, PRBool freeSrvName) ** Acquires & releases SpecWriteLock. */ SECStatus -ssl3_SetupPendingCipherSpec(sslSocket *ss) +ssl3_SetupBothPendingCipherSpecs(sslSocket *ss) { - ssl3CipherSpec *pwSpec; - ssl3CipherSpec *cwSpec; ssl3CipherSuite suite = ss->ssl3.hs.cipher_suite; - SSL3MACAlgorithm mac; SSL3KeyExchangeAlgorithm kea; - const ssl3CipherSuiteDef *suite_def; - PRBool isTLS; + const ssl3CipherSuiteDef *suiteDef; + SECStatus rv; PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); PORT_Assert(ss->version < SSL_LIBRARY_VERSION_TLS_1_3); ssl_GetSpecWriteLock(ss); /*******************************/ - pwSpec = ss->ssl3.pwSpec; - PORT_Assert(pwSpec == ss->ssl3.prSpec); - /* This hack provides maximal interoperability with SSL 3 servers. */ - cwSpec = ss->ssl3.cwSpec; - if (cwSpec->mac_def->mac == mac_null) { + if (ss->ssl3.cwSpec->macDef->mac == ssl_mac_null) { /* SSL records are not being MACed. */ - cwSpec->version = ss->version; + ss->ssl3.cwSpec->version = ss->version; } - pwSpec->version = ss->version; - isTLS = (PRBool)(pwSpec->version > SSL_LIBRARY_VERSION_3_0); - SSL_TRC(3, ("%d: SSL3[%d]: Set XXX Pending Cipher Suite to 0x%04x", SSL_GETPID(), ss->fd, suite)); - suite_def = ssl_LookupCipherSuiteDef(suite); - if (suite_def == NULL) { - ssl_ReleaseSpecWriteLock(ss); - return SECFailure; /* error code set by ssl_LookupCipherSuiteDef */ + suiteDef = ssl_LookupCipherSuiteDef(suite); + if (suiteDef == NULL) { + goto loser; } if (IS_DTLS(ss)) { /* Double-check that we did not pick an RC4 suite */ - PORT_Assert(suite_def->bulk_cipher_alg != cipher_rc4); + PORT_Assert(suiteDef->bulk_cipher_alg != cipher_rc4); } - kea = suite_def->key_exchange_alg; - mac = suite_def->mac_alg; - if (mac <= ssl_mac_sha && mac != ssl_mac_null && isTLS) - mac += 2; + ss->ssl3.hs.suite_def = suiteDef; - ss->ssl3.hs.suite_def = suite_def; + kea = suiteDef->key_exchange_alg; ss->ssl3.hs.kea_def = &kea_defs[kea]; PORT_Assert(ss->ssl3.hs.kea_def->kea == kea); - pwSpec->cipher_def = ssl_GetBulkCipherDef(suite_def); - - pwSpec->mac_def = &mac_defs[mac]; - PORT_Assert(pwSpec->mac_def->mac == mac); - - pwSpec->encodeContext = NULL; - pwSpec->decodeContext = NULL; - - pwSpec->mac_size = pwSpec->mac_def->mac_size; - - pwSpec->compression_method = ss->ssl3.hs.compression; - pwSpec->compressContext = NULL; - pwSpec->decompressContext = NULL; - - ssl_ReleaseSpecWriteLock(ss); /*******************************/ - return SECSuccess; -} - -#ifdef NSS_SSL_ENABLE_ZLIB -#define SSL3_DEFLATE_CONTEXT_SIZE sizeof(z_stream) - -static SECStatus -ssl3_MapZlibError(int zlib_error) -{ - switch (zlib_error) { - case Z_OK: - return SECSuccess; - default: - return SECFailure; - } -} - -static SECStatus -ssl3_DeflateInit(void *void_context) -{ - z_stream *context = void_context; - context->zalloc = NULL; - context->zfree = NULL; - context->opaque = NULL; - - return ssl3_MapZlibError(deflateInit(context, Z_DEFAULT_COMPRESSION)); -} - -static SECStatus -ssl3_InflateInit(void *void_context) -{ - z_stream *context = void_context; - context->zalloc = NULL; - context->zfree = NULL; - context->opaque = NULL; - context->next_in = NULL; - context->avail_in = 0; - - return ssl3_MapZlibError(inflateInit(context)); -} - -static SECStatus -ssl3_DeflateCompress(void *void_context, unsigned char *out, int *out_len, - int maxout, const unsigned char *in, int inlen) -{ - z_stream *context = void_context; - - if (!inlen) { - *out_len = 0; - return SECSuccess; - } - - context->next_in = (unsigned char *)in; - context->avail_in = inlen; - context->next_out = out; - context->avail_out = maxout; - if (deflate(context, Z_SYNC_FLUSH) != Z_OK) { - return SECFailure; - } - if (context->avail_out == 0) { - /* We ran out of space! */ - SSL_TRC(3, ("%d: SSL3[%d] Ran out of buffer while compressing", - SSL_GETPID())); - return SECFailure; - } - - *out_len = maxout - context->avail_out; - return SECSuccess; -} - -static SECStatus -ssl3_DeflateDecompress(void *void_context, unsigned char *out, int *out_len, - int maxout, const unsigned char *in, int inlen) -{ - z_stream *context = void_context; - - if (!inlen) { - *out_len = 0; - return SECSuccess; + rv = ssl3_SetupPendingCipherSpec(ss, CipherSpecRead, suiteDef, + &ss->ssl3.prSpec); + if (rv != SECSuccess) { + goto loser; } - - context->next_in = (unsigned char *)in; - context->avail_in = inlen; - context->next_out = out; - context->avail_out = maxout; - if (inflate(context, Z_SYNC_FLUSH) != Z_OK) { - PORT_SetError(SSL_ERROR_DECOMPRESSION_FAILURE); - return SECFailure; + rv = ssl3_SetupPendingCipherSpec(ss, CipherSpecWrite, suiteDef, + &ss->ssl3.pwSpec); + if (rv != SECSuccess) { + goto loser; } - *out_len = maxout - context->avail_out; - return SECSuccess; -} - -static SECStatus -ssl3_DestroyCompressContext(void *void_context, PRBool unused) -{ - deflateEnd(void_context); - PORT_Free(void_context); - return SECSuccess; -} - -static SECStatus -ssl3_DestroyDecompressContext(void *void_context, PRBool unused) -{ - inflateEnd(void_context); - PORT_Free(void_context); + ssl_ReleaseSpecWriteLock(ss); /*******************************/ return SECSuccess; -} - -#endif /* NSS_SSL_ENABLE_ZLIB */ -/* Initialize the compression functions and contexts for the given - * CipherSpec. */ -static SECStatus -ssl3_InitCompressionContext(ssl3CipherSpec *pwSpec) -{ - /* Setup the compression functions */ - switch (pwSpec->compression_method) { - case ssl_compression_null: - pwSpec->compressor = NULL; - pwSpec->decompressor = NULL; - pwSpec->compressContext = NULL; - pwSpec->decompressContext = NULL; - pwSpec->destroyCompressContext = NULL; - pwSpec->destroyDecompressContext = NULL; - break; -#ifdef NSS_SSL_ENABLE_ZLIB - case ssl_compression_deflate: - pwSpec->compressor = ssl3_DeflateCompress; - pwSpec->decompressor = ssl3_DeflateDecompress; - pwSpec->compressContext = PORT_Alloc(SSL3_DEFLATE_CONTEXT_SIZE); - pwSpec->decompressContext = PORT_Alloc(SSL3_DEFLATE_CONTEXT_SIZE); - pwSpec->destroyCompressContext = ssl3_DestroyCompressContext; - pwSpec->destroyDecompressContext = ssl3_DestroyDecompressContext; - ssl3_DeflateInit(pwSpec->compressContext); - ssl3_InflateInit(pwSpec->decompressContext); - break; -#endif /* NSS_SSL_ENABLE_ZLIB */ - default: - PORT_Assert(0); - PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); - return SECFailure; - } - - return SECSuccess; +loser: + ssl_ReleaseSpecWriteLock(ss); + return SECFailure; } -/* ssl3_BuildRecordPseudoHeader writes the SSL/TLS pseudo-header (the data - * which is included in the MAC or AEAD additional data) to |out| and returns - * its length. See https://tools.ietf.org/html/rfc5246#section-6.2.3.3 for the - * definition of the AEAD additional data. +/* ssl3_BuildRecordPseudoHeader writes the SSL/TLS pseudo-header (the data which + * is included in the MAC or AEAD additional data) to |buf|. See + * https://tools.ietf.org/html/rfc5246#section-6.2.3.3 for the definition of the + * AEAD additional data. * * TLS pseudo-header includes the record's version field, SSL's doesn't. Which - * pseudo-header defintiion to use should be decided based on the version of + * pseudo-header definition to use should be decided based on the version of * the protocol that was negotiated when the cipher spec became current, NOT * based on the version value in the record itself, and the decision is passed * to this function as the |includesVersion| argument. But, the |version| * argument should be the record's version value. */ -static unsigned int -ssl3_BuildRecordPseudoHeader(unsigned char *out, - sslSequenceNumber seq_num, +static SECStatus +ssl3_BuildRecordPseudoHeader(DTLSEpoch epoch, + sslSequenceNumber seqNum, SSL3ContentType type, PRBool includesVersion, SSL3ProtocolVersion version, PRBool isDTLS, - int length) -{ - out[0] = (unsigned char)(seq_num >> 56); - out[1] = (unsigned char)(seq_num >> 48); - out[2] = (unsigned char)(seq_num >> 40); - out[3] = (unsigned char)(seq_num >> 32); - out[4] = (unsigned char)(seq_num >> 24); - out[5] = (unsigned char)(seq_num >> 16); - out[6] = (unsigned char)(seq_num >> 8); - out[7] = (unsigned char)(seq_num >> 0); - out[8] = type; + int length, + sslBuffer *buf) +{ + SECStatus rv; + if (isDTLS) { + rv = sslBuffer_AppendNumber(buf, epoch, 2); + if (rv != SECSuccess) { + return SECFailure; + } + rv = sslBuffer_AppendNumber(buf, seqNum, 6); + } else { + rv = sslBuffer_AppendNumber(buf, seqNum, 8); + } + if (rv != SECSuccess) { + return SECFailure; + } + rv = sslBuffer_AppendNumber(buf, type, 1); + if (rv != SECSuccess) { + return SECFailure; + } /* SSL3 MAC doesn't include the record's version field. */ - if (!includesVersion) { - out[9] = MSB(length); - out[10] = LSB(length); - return 11; + if (includesVersion) { + /* TLS MAC and AEAD additional data include version. */ + rv = sslBuffer_AppendNumber(buf, version, 2); + if (rv != SECSuccess) { + return SECFailure; + } } - - /* TLS MAC and AEAD additional data include version. */ - if (isDTLS) { - SSL3ProtocolVersion dtls_version; - - dtls_version = dtls_TLSVersionToDTLSVersion(version); - out[9] = MSB(dtls_version); - out[10] = LSB(dtls_version); - } else { - out[9] = MSB(version); - out[10] = LSB(version); + rv = sslBuffer_AppendNumber(buf, length, 2); + if (rv != SECSuccess) { + return SECFailure; } - out[11] = MSB(length); - out[12] = LSB(length); - return 13; + + return SECSuccess; } static SECStatus @@ -1833,13 +1562,12 @@ ssl3_AESGCM(ssl3KeyMaterial *keys, unsigned int uOutLen; CK_GCM_PARAMS gcmParams; - const int tagSize = bulk_cipher_defs[cipher_aes_128_gcm].tag_size; - const int explicitNonceLen = - bulk_cipher_defs[cipher_aes_128_gcm].explicit_nonce_size; + const int tagSize = 16; + const int explicitNonceLen = 8; /* See https://tools.ietf.org/html/rfc5288#section-3 for details of how the * nonce is formed. */ - memcpy(nonce, keys->write_iv, 4); + memcpy(nonce, keys->iv, 4); if (doDecrypt) { memcpy(nonce + 4, in, explicitNonceLen); in += explicitNonceLen; @@ -1868,10 +1596,10 @@ ssl3_AESGCM(ssl3KeyMaterial *keys, gcmParams.ulTagBits = tagSize * 8; if (doDecrypt) { - rv = PK11_Decrypt(keys->write_key, CKM_AES_GCM, ¶m, out, &uOutLen, + rv = PK11_Decrypt(keys->key, CKM_AES_GCM, ¶m, out, &uOutLen, maxout, in, inlen); } else { - rv = PK11_Encrypt(keys->write_key, CKM_AES_GCM, ¶m, out, &uOutLen, + rv = PK11_Encrypt(keys->key, CKM_AES_GCM, ¶m, out, &uOutLen, maxout, in, inlen); } *outlen += (int)uOutLen; @@ -1893,12 +1621,12 @@ ssl3_ChaCha20Poly1305(ssl3KeyMaterial *keys, PRBool doDecrypt, unsigned char nonce[12]; CK_NSS_AEAD_PARAMS aeadParams; - const int tagSize = bulk_cipher_defs[cipher_chacha20].tag_size; + const int tagSize = 16; /* See * https://tools.ietf.org/html/draft-ietf-tls-chacha20-poly1305-04#section-2 * for details of how the nonce is formed. */ - PORT_Memcpy(nonce, keys->write_iv, 12); + PORT_Memcpy(nonce, keys->iv, 12); /* XOR the last 8 bytes of the IV with the sequence number. */ PORT_Assert(additionalDataLen >= 8); @@ -1917,10 +1645,10 @@ ssl3_ChaCha20Poly1305(ssl3KeyMaterial *keys, PRBool doDecrypt, aeadParams.ulTagLen = tagSize; if (doDecrypt) { - rv = PK11_Decrypt(keys->write_key, CKM_NSS_CHACHA20_POLY1305, ¶m, + rv = PK11_Decrypt(keys->key, CKM_NSS_CHACHA20_POLY1305, ¶m, out, &uOutLen, maxout, in, inlen); } else { - rv = PK11_Encrypt(keys->write_key, CKM_NSS_CHACHA20_POLY1305, ¶m, + rv = PK11_Encrypt(keys->key, CKM_NSS_CHACHA20_POLY1305, ¶m, out, &uOutLen, maxout, in, inlen); } *outlen = (int)uOutLen; @@ -1933,44 +1661,31 @@ ssl3_ChaCha20Poly1305(ssl3KeyMaterial *keys, PRBool doDecrypt, * Caller holds Spec write lock. */ static SECStatus -ssl3_InitPendingContexts(sslSocket *ss) +ssl3_InitPendingContexts(sslSocket *ss, ssl3CipherSpec *spec) { - ssl3CipherSpec *pwSpec; - const ssl3BulkCipherDef *cipher_def; - PK11Context *serverContext = NULL; - PK11Context *clientContext = NULL; - SECItem *param; - CK_MECHANISM_TYPE mechanism; - CK_MECHANISM_TYPE mac_mech; + CK_MECHANISM_TYPE encMechanism; + CK_ATTRIBUTE_TYPE encMode; + SECItem macParam; CK_ULONG macLength; SECItem iv; - SECItem mac_param; SSLCipherAlgorithm calg; PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); PORT_Assert(ss->opt.noLocks || ssl_HaveSpecWriteLock(ss)); - PORT_Assert(ss->ssl3.prSpec == ss->ssl3.pwSpec); - pwSpec = ss->ssl3.pwSpec; - cipher_def = pwSpec->cipher_def; - macLength = pwSpec->mac_size; - calg = cipher_def->calg; + macLength = spec->macDef->mac_size; + calg = spec->cipherDef->calg; PORT_Assert(alg2Mech[calg].calg == calg); - pwSpec->client.write_mac_context = NULL; - pwSpec->server.write_mac_context = NULL; - - if (cipher_def->type == type_aead) { - pwSpec->encode = NULL; - pwSpec->decode = NULL; - pwSpec->encodeContext = NULL; - pwSpec->decodeContext = NULL; + if (spec->cipherDef->type == type_aead) { + spec->cipher = NULL; + spec->cipherContext = NULL; switch (calg) { - case calg_aes_gcm: - pwSpec->aead = ssl3_AESGCM; + case ssl_calg_aes_gcm: + spec->aead = ssl3_AESGCM; break; - case calg_chacha20: - pwSpec->aead = ssl3_ChaCha20Poly1305; + case ssl_calg_chacha20: + spec->aead = ssl3_ChaCha20Poly1305; break; default: PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); @@ -1983,128 +1698,43 @@ ssl3_InitPendingContexts(sslSocket *ss) ** Now setup the MAC contexts, ** crypto contexts are setup below. */ + macParam.data = (unsigned char *)&macLength; + macParam.len = sizeof(macLength); + macParam.type = siBuffer; - mac_mech = pwSpec->mac_def->mmech; - mac_param.data = (unsigned char *)&macLength; - mac_param.len = sizeof(macLength); - mac_param.type = 0; - - pwSpec->client.write_mac_context = PK11_CreateContextBySymKey( - mac_mech, CKA_SIGN, pwSpec->client.write_mac_key, &mac_param); - if (pwSpec->client.write_mac_context == NULL) { - ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE); - goto fail; - } - pwSpec->server.write_mac_context = PK11_CreateContextBySymKey( - mac_mech, CKA_SIGN, pwSpec->server.write_mac_key, &mac_param); - if (pwSpec->server.write_mac_context == NULL) { + spec->keyMaterial.macContext = PK11_CreateContextBySymKey( + spec->macDef->mmech, CKA_SIGN, spec->keyMaterial.macKey, &macParam); + if (!spec->keyMaterial.macContext) { ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE); - goto fail; + return SECFailure; } /* ** Now setup the crypto contexts. */ - - if (calg == calg_null) { - pwSpec->encode = Null_Cipher; - pwSpec->decode = Null_Cipher; + if (calg == ssl_calg_null) { + spec->cipher = Null_Cipher; return SECSuccess; } - mechanism = ssl3_Alg2Mech(calg); - /* - * build the server context - */ - iv.data = pwSpec->server.write_iv; - iv.len = cipher_def->iv_size; - param = PK11_ParamFromIV(mechanism, &iv); - if (param == NULL) { - ssl_MapLowLevelError(SSL_ERROR_IV_PARAM_FAILURE); - goto fail; - } - serverContext = PK11_CreateContextBySymKey(mechanism, - (ss->sec.isServer ? CKA_ENCRYPT - : CKA_DECRYPT), - pwSpec->server.write_key, param); - iv.data = PK11_IVFromParam(mechanism, param, (int *)&iv.len); - if (iv.data) - PORT_Memcpy(pwSpec->server.write_iv, iv.data, iv.len); - SECITEM_FreeItem(param, PR_TRUE); - if (serverContext == NULL) { - ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE); - goto fail; - } + spec->cipher = (SSLCipher)PK11_CipherOp; + encMechanism = ssl3_Alg2Mech(calg); + encMode = (spec->direction == CipherSpecWrite) ? CKA_ENCRYPT : CKA_DECRYPT; /* - * build the client context + * build the context */ - iv.data = pwSpec->client.write_iv; - iv.len = cipher_def->iv_size; - - param = PK11_ParamFromIV(mechanism, &iv); - if (param == NULL) { - ssl_MapLowLevelError(SSL_ERROR_IV_PARAM_FAILURE); - goto fail; - } - clientContext = PK11_CreateContextBySymKey(mechanism, - (ss->sec.isServer ? CKA_DECRYPT - : CKA_ENCRYPT), - pwSpec->client.write_key, param); - iv.data = PK11_IVFromParam(mechanism, param, (int *)&iv.len); - if (iv.data) - PORT_Memcpy(pwSpec->client.write_iv, iv.data, iv.len); - SECITEM_FreeItem(param, PR_TRUE); - if (clientContext == NULL) { + iv.data = spec->keyMaterial.iv; + iv.len = spec->cipherDef->iv_size; + spec->cipherContext = PK11_CreateContextBySymKey(encMechanism, encMode, + spec->keyMaterial.key, + &iv); + if (!spec->cipherContext) { ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE); - goto fail; + return SECFailure; } - pwSpec->encode = (SSLCipher)PK11_CipherOp; - pwSpec->decode = (SSLCipher)PK11_CipherOp; - - pwSpec->encodeContext = (ss->sec.isServer) ? serverContext : clientContext; - pwSpec->decodeContext = (ss->sec.isServer) ? clientContext : serverContext; - - serverContext = NULL; - clientContext = NULL; - - ssl3_InitCompressionContext(pwSpec); return SECSuccess; - -fail: - if (serverContext != NULL) - PK11_DestroyContext(serverContext, PR_TRUE); - if (pwSpec->client.write_mac_context != NULL) { - PK11_DestroyContext(pwSpec->client.write_mac_context, PR_TRUE); - pwSpec->client.write_mac_context = NULL; - } - if (pwSpec->server.write_mac_context != NULL) { - PK11_DestroyContext(pwSpec->server.write_mac_context, PR_TRUE); - pwSpec->server.write_mac_context = NULL; - } - - return SECFailure; -} - -HASH_HashType -ssl3_GetTls12HashType(sslSocket *ss) -{ - if (ss->ssl3.pwSpec->version < SSL_LIBRARY_VERSION_TLS_1_2) { - return HASH_AlgNULL; - } - - switch (ss->ssl3.hs.suite_def->prf_hash) { - case ssl_hash_sha384: - return HASH_AlgSHA384; - case ssl_hash_sha256: - case ssl_hash_none: - /* ssl_hash_none is for pre-1.2 suites, which use SHA-256. */ - return HASH_AlgSHA256; - default: - PORT_Assert(0); - } - return HASH_AlgSHA256; } /* Complete the initialization of all keys, ciphers, MACs and their contexts @@ -2114,73 +1744,78 @@ ssl3_GetTls12HashType(sslSocket *ss) * ssl3_HandleServerHello (for session restart) * ssl3_HandleClientHello (for session restart) * Sets error code, but caller probably should override to disambiguate. - * NULL pms means re-use old master_secret. * - * If the old master secret is reused, pms is NULL and the master secret is - * already in pwSpec->master_secret. + * If |secret| is a master secret from a previous connection is reused, |derive| + * is PR_FALSE. If the secret is a pre-master secret, then |derive| is PR_TRUE + * and the master secret is derived from |secret|. */ SECStatus -ssl3_InitPendingCipherSpec(sslSocket *ss, PK11SymKey *pms) +ssl3_InitPendingCipherSpecs(sslSocket *ss, PK11SymKey *secret, PRBool derive) { + PK11SymKey *masterSecret; ssl3CipherSpec *pwSpec; - ssl3CipherSpec *cwSpec; + ssl3CipherSpec *prSpec; SECStatus rv; PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); + PORT_Assert(secret); ssl_GetSpecWriteLock(ss); /**************************************/ - PORT_Assert(ss->ssl3.prSpec == ss->ssl3.pwSpec); - + PORT_Assert(ss->ssl3.pwSpec); + PORT_Assert(ss->ssl3.cwSpec->epoch == ss->ssl3.crSpec->epoch); + prSpec = ss->ssl3.prSpec; pwSpec = ss->ssl3.pwSpec; - cwSpec = ss->ssl3.cwSpec; - if (pms || (!pwSpec->msItem.len && !pwSpec->master_secret)) { - rv = ssl3_DeriveMasterSecret(ss, pms); - if (rv != SECSuccess) { - goto done; /* err code set by ssl3_DeriveMasterSecret */ - } + if (ss->ssl3.cwSpec->epoch == PR_UINT16_MAX) { + /* The problem here is that we have rehandshaked too many + * times (you are not allowed to wrap the epoch). The + * spec says you should be discarding the connection + * and start over, so not much we can do here. */ + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + goto loser; } - if (pwSpec->master_secret) { - rv = ssl3_DeriveConnectionKeys(ss); - if (rv == SECSuccess) { - rv = ssl3_InitPendingContexts(ss); + + if (derive) { + rv = ssl3_ComputeMasterSecret(ss, secret, &masterSecret); + if (rv != SECSuccess) { + goto loser; } } else { - PORT_Assert(pwSpec->master_secret); - PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); - rv = SECFailure; + masterSecret = secret; } + + PORT_Assert(masterSecret); + rv = ssl3_DeriveConnectionKeys(ss, masterSecret); if (rv != SECSuccess) { - goto done; + if (derive) { + /* masterSecret was created here. */ + PK11_FreeSymKey(masterSecret); + } + goto loser; } - /* Generic behaviors -- common to all crypto methods */ - if (!IS_DTLS(ss)) { - pwSpec->read_seq_num = pwSpec->write_seq_num = 0; - } else { - if (cwSpec->epoch == PR_UINT16_MAX) { - /* The problem here is that we have rehandshaked too many - * times (you are not allowed to wrap the epoch). The - * spec says you should be discarding the connection - * and start over, so not much we can do here. */ - PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); - rv = SECFailure; - goto done; - } - /* The sequence number has the high 16 bits as the epoch. */ - pwSpec->epoch = cwSpec->epoch + 1; - pwSpec->read_seq_num = pwSpec->write_seq_num = - (sslSequenceNumber)pwSpec->epoch << 48; + /* Both cipher specs maintain a reference to the master secret, since each + * is managed and freed independently. */ + prSpec->masterSecret = masterSecret; + pwSpec->masterSecret = PK11_ReferenceSymKey(masterSecret); + rv = ssl3_InitPendingContexts(ss, ss->ssl3.prSpec); + if (rv != SECSuccess) { + goto loser; + } - dtls_InitRecvdRecords(&pwSpec->recvdRecords); + rv = ssl3_InitPendingContexts(ss, ss->ssl3.pwSpec); + if (rv != SECSuccess) { + goto loser; } -done: ssl_ReleaseSpecWriteLock(ss); /******************************/ - if (rv != SECSuccess) - ssl_MapLowLevelError(SSL_ERROR_SESSION_KEY_GEN_FAILURE); - return rv; + return SECSuccess; + +loser: + ssl_ReleaseSpecWriteLock(ss); /******************************/ + ssl_MapLowLevelError(SSL_ERROR_SESSION_KEY_GEN_FAILURE); + return SECFailure; } /* @@ -2213,36 +1848,33 @@ static const unsigned char mac_pad_2[60] = { static SECStatus ssl3_ComputeRecordMAC( ssl3CipherSpec *spec, - PRBool useServerMacKey, const unsigned char *header, unsigned int headerLen, const PRUint8 *input, - int inputLength, + int inputLen, unsigned char *outbuf, - unsigned int *outLength) + unsigned int *outLen) { - const ssl3MACDef *mac_def; + PK11Context *context; + int macSize = spec->macDef->mac_size; SECStatus rv; PRINT_BUF(95, (NULL, "frag hash1: header", header, headerLen)); - PRINT_BUF(95, (NULL, "frag hash1: input", input, inputLength)); + PRINT_BUF(95, (NULL, "frag hash1: input", input, inputLen)); - mac_def = spec->mac_def; - if (mac_def->mac == mac_null) { - *outLength = 0; + if (spec->macDef->mac == ssl_mac_null) { + *outLen = 0; return SECSuccess; } - PK11Context *mac_context = - (useServerMacKey ? spec->server.write_mac_context - : spec->client.write_mac_context); - rv = PK11_DigestBegin(mac_context); - rv |= PK11_DigestOp(mac_context, header, headerLen); - rv |= PK11_DigestOp(mac_context, input, inputLength); - rv |= PK11_DigestFinal(mac_context, outbuf, outLength, spec->mac_size); - PORT_Assert(rv != SECSuccess || *outLength == (unsigned)spec->mac_size); + context = spec->keyMaterial.macContext; + rv = PK11_DigestBegin(context); + rv |= PK11_DigestOp(context, header, headerLen); + rv |= PK11_DigestOp(context, input, inputLen); + rv |= PK11_DigestFinal(context, outbuf, outLen, macSize); + PORT_Assert(rv != SECSuccess || *outLen == (unsigned)macSize); - PRINT_BUF(95, (NULL, "frag hash2: result", outbuf, *outLength)); + PRINT_BUF(95, (NULL, "frag hash2: result", outbuf, *outLen)); if (rv != SECSuccess) { rv = SECFailure; @@ -2260,7 +1892,6 @@ ssl3_ComputeRecordMAC( static SECStatus ssl3_ComputeRecordMACConstantTime( ssl3CipherSpec *spec, - PRBool useServerMacKey, const unsigned char *header, unsigned int headerLen, const PRUint8 *input, @@ -2272,13 +1903,13 @@ ssl3_ComputeRecordMACConstantTime( CK_MECHANISM_TYPE macType; CK_NSS_MAC_CONSTANT_TIME_PARAMS params; SECItem param, inputItem, outputItem; + int macSize = spec->macDef->mac_size; SECStatus rv; - PK11SymKey *key; - PORT_Assert(inputLen >= spec->mac_size); + PORT_Assert(inputLen >= spec->macDef->mac_size); PORT_Assert(originalLen >= inputLen); - if (spec->mac_def->mac == mac_null) { + if (spec->macDef->mac == ssl_mac_null) { *outLen = 0; return SECSuccess; } @@ -2288,7 +1919,7 @@ ssl3_ComputeRecordMACConstantTime( macType = CKM_NSS_SSL3_MAC_CONSTANT_TIME; } - params.macAlg = spec->mac_def->mmech; + params.macAlg = spec->macDef->mmech; params.ulBodyTotalLen = originalLen; params.pHeader = (unsigned char *)header; /* const cast */ params.ulHeaderLen = headerLen; @@ -2305,19 +1936,14 @@ ssl3_ComputeRecordMACConstantTime( outputItem.len = *outLen; outputItem.type = 0; - key = spec->server.write_mac_key; - if (!useServerMacKey) { - key = spec->client.write_mac_key; - } - - rv = PK11_SignWithSymKey(key, macType, ¶m, &outputItem, &inputItem); + rv = PK11_SignWithSymKey(spec->keyMaterial.macKey, macType, ¶m, + &outputItem, &inputItem); if (rv != SECSuccess) { if (PORT_GetError() == SEC_ERROR_INVALID_ALGORITHM) { /* ssl3_ComputeRecordMAC() expects the MAC to have been removed * from the input length already. */ - return ssl3_ComputeRecordMAC(spec, useServerMacKey, - header, headerLen, - input, inputLen - spec->mac_size, + return ssl3_ComputeRecordMAC(spec, header, headerLen, + input, inputLen - macSize, outbuf, outLen); } @@ -2327,7 +1953,7 @@ ssl3_ComputeRecordMACConstantTime( return rv; } - PORT_Assert(outputItem.len == (unsigned)spec->mac_size); + PORT_Assert(outputItem.len == (unsigned)macSize); *outLen = outputItem.len; return rv; @@ -2363,34 +1989,30 @@ ssl3_ClientAuthTokenPresent(sslSessionID *sid) /* Caller must hold the spec read lock. */ SECStatus -ssl3_CompressMACEncryptRecord(ssl3CipherSpec *cwSpec, - PRBool isServer, - PRBool isDTLS, - PRBool capRecordVersion, - SSL3ContentType type, - const PRUint8 *pIn, - PRUint32 contentLen, - sslBuffer *wrBuf) -{ - const ssl3BulkCipherDef *cipher_def; +ssl3_MACEncryptRecord(ssl3CipherSpec *cwSpec, + PRBool isServer, + PRBool isDTLS, + SSL3ContentType type, + const PRUint8 *pIn, + PRUint32 contentLen, + sslBuffer *wrBuf) +{ SECStatus rv; PRUint32 macLen = 0; PRUint32 fragLen; PRUint32 p1Len, p2Len, oddLen = 0; unsigned int ivLen = 0; - unsigned char pseudoHeader[13]; - unsigned int pseudoHeaderLen; - - cipher_def = cwSpec->cipher_def; + unsigned char pseudoHeaderBuf[13]; + sslBuffer pseudoHeader = SSL_BUFFER(pseudoHeaderBuf); - if (cipher_def->type == type_block && + if (cwSpec->cipherDef->type == type_block && cwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_1) { /* Prepend the per-record explicit IV using technique 2b from * RFC 4346 section 6.2.3.2: The IV is a cryptographically * strong random number XORed with the CBC residue from the previous * record. */ - ivLen = cipher_def->iv_size; + ivLen = cwSpec->cipherDef->iv_size; if (ivLen > wrBuf->space) { PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); return SECFailure; @@ -2400,7 +2022,7 @@ ssl3_CompressMACEncryptRecord(ssl3CipherSpec *cwSpec, ssl_MapLowLevelError(SSL_ERROR_GENERATE_RANDOM_FAILURE); return rv; } - rv = cwSpec->encode(cwSpec->encodeContext, + rv = cwSpec->cipher(cwSpec->cipherContext, wrBuf->buf, /* output */ (int *)&wrBuf->len, /* outlen */ ivLen, /* max outlen */ @@ -2412,24 +2034,14 @@ ssl3_CompressMACEncryptRecord(ssl3CipherSpec *cwSpec, } } - if (cwSpec->compressor) { - int outlen; - rv = cwSpec->compressor(cwSpec->compressContext, wrBuf->buf + ivLen, - &outlen, wrBuf->space - ivLen, pIn, contentLen); - if (rv != SECSuccess) - return rv; - pIn = wrBuf->buf + ivLen; - contentLen = outlen; - } - - pseudoHeaderLen = ssl3_BuildRecordPseudoHeader( - pseudoHeader, cwSpec->write_seq_num, type, - cwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_0, cwSpec->version, - isDTLS, contentLen); - PORT_Assert(pseudoHeaderLen <= sizeof(pseudoHeader)); - if (cipher_def->type == type_aead) { - const int nonceLen = cipher_def->explicit_nonce_size; - const int tagLen = cipher_def->tag_size; + rv = ssl3_BuildRecordPseudoHeader( + cwSpec->epoch, cwSpec->seqNum, type, + cwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_0, cwSpec->recordVersion, + isDTLS, contentLen, &pseudoHeader); + PORT_Assert(rv == SECSuccess); + if (cwSpec->cipherDef->type == type_aead) { + const int nonceLen = cwSpec->cipherDef->explicit_nonce_size; + const int tagLen = cwSpec->cipherDef->tag_size; if (nonceLen + contentLen + tagLen > wrBuf->space) { PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); @@ -2437,23 +2049,26 @@ ssl3_CompressMACEncryptRecord(ssl3CipherSpec *cwSpec, } rv = cwSpec->aead( - isServer ? &cwSpec->server : &cwSpec->client, + &cwSpec->keyMaterial, PR_FALSE, /* do encrypt */ wrBuf->buf, /* output */ (int *)&wrBuf->len, /* out len */ wrBuf->space, /* max out */ pIn, contentLen, /* input */ - pseudoHeader, pseudoHeaderLen); + SSL_BUFFER_BASE(&pseudoHeader), SSL_BUFFER_LEN(&pseudoHeader)); if (rv != SECSuccess) { PORT_SetError(SSL_ERROR_ENCRYPTION_FAILURE); return SECFailure; } } else { + int blockSize = cwSpec->cipherDef->block_size; + /* * Add the MAC */ - rv = ssl3_ComputeRecordMAC(cwSpec, isServer, pseudoHeader, - pseudoHeaderLen, pIn, contentLen, + rv = ssl3_ComputeRecordMAC(cwSpec, SSL_BUFFER_BASE(&pseudoHeader), + SSL_BUFFER_LEN(&pseudoHeader), + pIn, contentLen, wrBuf->buf + ivLen + contentLen, &macLen); if (rv != SECSuccess) { ssl_MapLowLevelError(SSL_ERROR_MAC_COMPUTATION_FAILURE); @@ -2468,16 +2083,16 @@ ssl3_CompressMACEncryptRecord(ssl3CipherSpec *cwSpec, * Pad the text (if we're doing a block cipher) * then Encrypt it */ - if (cipher_def->type == type_block) { + if (cwSpec->cipherDef->type == type_block) { unsigned char *pBuf; int padding_length; int i; - oddLen = contentLen % cipher_def->block_size; + oddLen = contentLen % blockSize; /* Assume blockSize is a power of two */ - padding_length = cipher_def->block_size - 1 - ((fragLen) & (cipher_def->block_size - 1)); + padding_length = blockSize - 1 - ((fragLen) & (blockSize - 1)); fragLen += padding_length + 1; - PORT_Assert((fragLen % cipher_def->block_size) == 0); + PORT_Assert((fragLen % blockSize) == 0); /* Pad according to TLS rules (also acceptable to SSL3). */ pBuf = &wrBuf->buf[ivLen + fragLen - 1]; @@ -2495,13 +2110,13 @@ ssl3_CompressMACEncryptRecord(ssl3CipherSpec *cwSpec, } if (oddLen) { p2Len += oddLen; - PORT_Assert((cipher_def->block_size < 2) || - (p2Len % cipher_def->block_size) == 0); + PORT_Assert((blockSize < 2) || + (p2Len % blockSize) == 0); memmove(wrBuf->buf + ivLen + p1Len, pIn + p1Len, oddLen); } if (p1Len > 0) { int cipherBytesPart1 = -1; - rv = cwSpec->encode(cwSpec->encodeContext, + rv = cwSpec->cipher(cwSpec->cipherContext, wrBuf->buf + ivLen, /* output */ &cipherBytesPart1, /* actual outlen */ p1Len, /* max outlen */ @@ -2516,7 +2131,7 @@ ssl3_CompressMACEncryptRecord(ssl3CipherSpec *cwSpec, } if (p2Len > 0) { int cipherBytesPart2 = -1; - rv = cwSpec->encode(cwSpec->encodeContext, + rv = cwSpec->cipher(cwSpec->cipherContext, wrBuf->buf + ivLen + p1Len, &cipherBytesPart2, /* output and actual outLen */ p2Len, /* max outlen */ @@ -2534,34 +2149,66 @@ ssl3_CompressMACEncryptRecord(ssl3CipherSpec *cwSpec, return SECSuccess; } +/* Note: though this can report failure, it shouldn't. */ +static SECStatus +ssl_InsertRecordHeader(const sslSocket *ss, ssl3CipherSpec *cwSpec, + SSL3ContentType contentType, unsigned int len, + sslBuffer *wrBuf) +{ + SECStatus rv; + +#ifndef UNSAFE_FUZZER_MODE + if (cwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_3 && + cwSpec->cipherDef->calg != ssl_calg_null) { + contentType = content_application_data; + } +#endif + rv = sslBuffer_AppendNumber(wrBuf, contentType, 1); + if (rv != SECSuccess) { + return SECFailure; + } + + rv = sslBuffer_AppendNumber(wrBuf, cwSpec->recordVersion, 2); + if (rv != SECSuccess) { + return SECFailure; + } + if (IS_DTLS(ss)) { + rv = sslBuffer_AppendNumber(wrBuf, cwSpec->epoch, 2); + if (rv != SECSuccess) { + return SECFailure; + } + rv = sslBuffer_AppendNumber(wrBuf, cwSpec->seqNum, 6); + if (rv != SECSuccess) { + return SECFailure; + } + } + rv = sslBuffer_AppendNumber(wrBuf, len, 2); + if (rv != SECSuccess) { + return SECFailure; + } + + return SECSuccess; +} + SECStatus -ssl_ProtectRecord(sslSocket *ss, ssl3CipherSpec *cwSpec, - PRBool capRecordVersion, SSL3ContentType type, +ssl_ProtectRecord(sslSocket *ss, ssl3CipherSpec *cwSpec, SSL3ContentType type, const PRUint8 *pIn, PRUint32 contentLen, sslBuffer *wrBuf) { - const ssl3BulkCipherDef *cipher_def = cwSpec->cipher_def; - PRUint16 headerLen; - sslBuffer protBuf; - SSL3ProtocolVersion version = cwSpec->version; + 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; - PRUint8 *ptr = wrBuf->buf; SECStatus rv; - if (ss->ssl3.hs.shortHeaders) { - PORT_Assert(!IS_DTLS(ss)); - PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_TLS_1_3); - headerLen = TLS13_RECORD_HEADER_LENGTH_SHORT; - } else { - headerLen = IS_DTLS(ss) ? DTLS_RECORD_HEADER_LENGTH : SSL3_RECORD_HEADER_LENGTH; - } - protBuf.buf = wrBuf->buf + headerLen; - protBuf.len = 0; - protBuf.space = wrBuf->space - headerLen; - - PORT_Assert(cipher_def->max_records <= RECORD_SEQ_MAX); - if ((cwSpec->write_seq_num & RECORD_SEQ_MAX) >= cipher_def->max_records) { + 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) { + /* 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->write_seq_num)); + SSL_GETPID(), cwSpec->seqNum)); PORT_SetError(SSL_ERROR_TOO_MANY_RECORDS); return SECFailure; } @@ -2569,15 +2216,22 @@ ssl_ProtectRecord(sslSocket *ss, ssl3CipherSpec *cwSpec, isTLS13 = (PRBool)(cwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_3); #ifdef UNSAFE_FUZZER_MODE - rv = Null_Cipher(NULL, protBuf.buf, (int *)&protBuf.len, protBuf.space, - pIn, contentLen); + { + int len; + rv = Null_Cipher(NULL, SSL_BUFFER_BASE(&protBuf), &len, + SSL_BUFFER_SPACE(&protBuf), pIn, contentLen); + if (rv != SECSuccess) { + return SECFailure; /* error was set */ + } + rv = sslBuffer_Skip(&protBuf, len, NULL); + PORT_Assert(rv == SECSuccess); /* Can't fail. */ + } #else if (isTLS13) { rv = tls13_ProtectRecord(ss, cwSpec, type, pIn, contentLen, &protBuf); } else { - rv = ssl3_CompressMACEncryptRecord(cwSpec, ss->sec.isServer, - IS_DTLS(ss), capRecordVersion, type, - pIn, contentLen, &protBuf); + rv = ssl3_MACEncryptRecord(cwSpec, ss->sec.isServer, IS_DTLS(ss), type, + pIn, contentLen, &protBuf); } #endif if (rv != SECSuccess) { @@ -2585,40 +2239,58 @@ ssl_ProtectRecord(sslSocket *ss, ssl3CipherSpec *cwSpec, } PORT_Assert(protBuf.len <= MAX_FRAGMENT_LENGTH + (isTLS13 ? 256 : 1024)); - wrBuf->len = protBuf.len + headerLen; - if (ss->ssl3.hs.shortHeaders) { - PORT_Assert(!IS_DTLS(ss)); /* Decoder not yet implemented. */ - (void)ssl_EncodeUintX(0x8000 | protBuf.len, 2, ptr); - } else { -#ifndef UNSAFE_FUZZER_MODE - if (isTLS13 && cipher_def->calg != ssl_calg_null) { - *ptr++ = content_application_data; - } else -#endif - { - *ptr++ = type; - } + rv = ssl_InsertRecordHeader(ss, cwSpec, type, SSL_BUFFER_LEN(&protBuf), + wrBuf); + if (rv != SECSuccess) { + return SECFailure; + } - if (IS_DTLS(ss)) { - version = isTLS13 ? SSL_LIBRARY_VERSION_TLS_1_1 : version; - version = dtls_TLSVersionToDTLSVersion(version); + 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; + } + ++cwSpec->seqNum; - ptr = ssl_EncodeUintX(version, 2, ptr); - ptr = ssl_EncodeUintX(cwSpec->write_seq_num, 8, ptr); - } else { - if (capRecordVersion || isTLS13) { - version = PR_MIN(SSL_LIBRARY_VERSION_TLS_1_0, version); - } - ptr = ssl_EncodeUintX(version, 2, ptr); + return SECSuccess; +} + +SECStatus +ssl_ProtectNextRecord(sslSocket *ss, ssl3CipherSpec *spec, SSL3ContentType type, + const PRUint8 *pIn, unsigned int nIn, + unsigned int *written) +{ + sslBuffer *wrBuf = &ss->sec.writeBuf; + unsigned int contentLen; + unsigned int spaceNeeded; + SECStatus rv; + + contentLen = PR_MIN(nIn, MAX_FRAGMENT_LENGTH); + spaceNeeded = contentLen + SSL3_BUFFER_FUDGE; + if (spec->version >= SSL_LIBRARY_VERSION_TLS_1_1 && + spec->cipherDef->type == type_block) { + spaceNeeded += spec->cipherDef->iv_size; + } + if (spaceNeeded > SSL_BUFFER_SPACE(wrBuf)) { + rv = sslBuffer_Grow(wrBuf, spaceNeeded); + if (rv != SECSuccess) { + SSL_DBG(("%d: SSL3[%d]: failed to expand write buffer to %d", + SSL_GETPID(), ss->fd, spaceNeeded)); + return SECFailure; } - (void)ssl_EncodeUintX(protBuf.len, 2, ptr); } - ++cwSpec->write_seq_num; + rv = ssl_ProtectRecord(ss, spec, type, pIn, contentLen, wrBuf); + if (rv != SECSuccess) { + return SECFailure; + } + PRINT_BUF(50, (ss, "send (encrypted) record data:", + SSL_BUFFER_BASE(wrBuf), SSL_BUFFER_LEN(wrBuf))); + *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 @@ -2639,16 +2311,6 @@ ssl_ProtectRecord(sslSocket *ss, ssl3CipherSpec *cwSpec, * all ciphertext into the pending ciphertext buffer. * ssl_SEND_FLAG_USE_EPOCH (for DTLS) * Forces the use of the provided epoch - * ssl_SEND_FLAG_CAP_RECORD_VERSION - * Caps the record layer version number of TLS ClientHello to { 3, 1 } - * (TLS 1.0). Some TLS 1.0 servers (which seem to use F5 BIG-IP) ignore - * ClientHello.client_version and use the record layer version number - * (TLSPlaintext.version) instead when negotiating protocol versions. In - * addition, if the record layer version number of ClientHello is { 3, 2 } - * (TLS 1.1) or higher, these servers reset the TCP connections. Lastly, - * some F5 BIG-IP servers hang if a record containing a ClientHello has a - * version greater than { 3, 1 } and a length greater than 255. Set this - * flag to work around such servers. */ PRInt32 ssl3_SendRecord(sslSocket *ss, @@ -2659,10 +2321,9 @@ ssl3_SendRecord(sslSocket *ss, PRInt32 flags) { sslBuffer *wrBuf = &ss->sec.writeBuf; + ssl3CipherSpec *spec; SECStatus rv; PRInt32 totalSent = 0; - PRBool capRecordVersion; - ssl3CipherSpec *spec; SSL_TRC(3, ("%d: SSL3[%d] SendRecord type: %s nIn=%d", SSL_GETPID(), ss->fd, ssl3_DecodeContentType(type), @@ -2670,121 +2331,54 @@ ssl3_SendRecord(sslSocket *ss, PRINT_BUF(50, (ss, "Send record (plain text)", pIn, nIn)); PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); + PORT_Assert(SSL_BUFFER_LEN(wrBuf) == 0); if (ss->ssl3.fatalAlertSent) { SSL_TRC(3, ("%d: SSL3[%d] Suppress write, fatal alert already sent", SSL_GETPID(), ss->fd)); + if (type != content_alert) { + /* If we are sending an alert, then we already have an + * error, so don't overwrite. */ + PORT_SetError(SSL_ERROR_HANDSHAKE_FAILED); + } return SECFailure; } - capRecordVersion = ((flags & ssl_SEND_FLAG_CAP_RECORD_VERSION) != 0); - - if (capRecordVersion) { - /* ssl_SEND_FLAG_CAP_RECORD_VERSION can only be used with the - * TLS initial ClientHello. */ - PORT_Assert(!IS_DTLS(ss)); - PORT_Assert(!ss->firstHsDone); - PORT_Assert(type == content_handshake); - PORT_Assert(ss->ssl3.hs.ws == wait_server_hello); - } - - if (ss->ssl3.initialized == PR_FALSE) { - /* This can happen on a server if the very first incoming record - ** looks like a defective ssl3 record (e.g. too long), and we're - ** trying to send an alert. - */ - PR_ASSERT(type == content_alert); - ssl3_InitState(ss); - } - /* check for Token Presence */ if (!ssl3_ClientAuthTokenPresent(ss->sec.ci.sid)) { PORT_SetError(SSL_ERROR_TOKEN_INSERTION_REMOVAL); return SECFailure; } - while (nIn > 0) { - PRUint32 contentLen = PR_MIN(nIn, MAX_FRAGMENT_LENGTH); - unsigned int spaceNeeded; - unsigned int numRecords; - - ssl_GetSpecReadLock(ss); /********************************/ + if (cwSpec) { + /* cwSpec can only be set for retransmissions of the DTLS handshake. */ + PORT_Assert(IS_DTLS(ss) && + (type == content_handshake || + type == content_change_cipher_spec)); + spec = cwSpec; + } else { + spec = ss->ssl3.cwSpec; + } - if (nIn > 1 && ss->opt.cbcRandomIV && - ss->ssl3.cwSpec->version < SSL_LIBRARY_VERSION_TLS_1_1 && - type == content_application_data && - ss->ssl3.cwSpec->cipher_def->type == type_block /* CBC mode */) { - /* We will split the first byte of the record into its own record, - * as explained in the documentation for SSL_CBC_RANDOM_IV in ssl.h - */ - numRecords = 2; - } else { - numRecords = 1; - } + while (nIn > 0) { + unsigned int written = 0; + PRInt32 sent; - spaceNeeded = contentLen + (numRecords * SSL3_BUFFER_FUDGE); - if (ss->ssl3.cwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_1 && - ss->ssl3.cwSpec->cipher_def->type == type_block) { - spaceNeeded += ss->ssl3.cwSpec->cipher_def->iv_size; - } - if (spaceNeeded > wrBuf->space) { - rv = sslBuffer_Grow(wrBuf, spaceNeeded); - if (rv != SECSuccess) { - SSL_DBG(("%d: SSL3[%d]: SendRecord, tried to get %d bytes", - SSL_GETPID(), ss->fd, spaceNeeded)); - goto spec_locked_loser; /* sslBuffer_Grow set error code. */ - } + ssl_GetSpecReadLock(ss); + rv = ssl_ProtectNextRecord(ss, spec, type, pIn, nIn, &written); + ssl_ReleaseSpecReadLock(ss); + if (rv != SECSuccess) { + return SECFailure; } - if (numRecords == 2) { - sslBuffer secondRecord; - rv = ssl_ProtectRecord(ss, ss->ssl3.cwSpec, capRecordVersion, type, - pIn, 1, wrBuf); - if (rv != SECSuccess) - goto spec_locked_loser; - - PRINT_BUF(50, (ss, "send (encrypted) record data [1/2]:", - wrBuf->buf, wrBuf->len)); - - secondRecord.buf = wrBuf->buf + wrBuf->len; - secondRecord.len = 0; - secondRecord.space = wrBuf->space - wrBuf->len; - - rv = ssl_ProtectRecord(ss, ss->ssl3.cwSpec, capRecordVersion, type, - pIn + 1, contentLen - 1, &secondRecord); - if (rv == SECSuccess) { - PRINT_BUF(50, (ss, "send (encrypted) record data [2/2]:", - secondRecord.buf, secondRecord.len)); - wrBuf->len += secondRecord.len; - } - } else { - if (cwSpec) { - /* cwSpec can only be set for retransmissions of DTLS handshake - * messages. */ - PORT_Assert(IS_DTLS(ss) && - (type == content_handshake || - type == content_change_cipher_spec)); - spec = cwSpec; - } else { - spec = ss->ssl3.cwSpec; - } - - rv = ssl_ProtectRecord(ss, spec, !IS_DTLS(ss) && capRecordVersion, - type, pIn, contentLen, wrBuf); - if (rv == SECSuccess) { - PRINT_BUF(50, (ss, "send (encrypted) record data:", - wrBuf->buf, wrBuf->len)); - } + PORT_Assert(written > 0); + /* DTLS should not fragment non-application data here. */ + if (IS_DTLS(ss) && type != content_application_data) { + PORT_Assert(written == nIn); } - spec_locked_loser: - ssl_ReleaseSpecReadLock(ss); /************************************/ - - if (rv != SECSuccess) - return SECFailure; - - pIn += contentLen; - nIn -= contentLen; + pIn += written; + nIn -= written; PORT_Assert(nIn >= 0); /* If there's still some previously saved ciphertext, @@ -2794,58 +2388,64 @@ ssl3_SendRecord(sslSocket *ss, if ((ss->pendingBuf.len > 0) || (flags & ssl_SEND_FLAG_FORCE_INTO_BUFFER)) { - rv = ssl_SaveWriteData(ss, wrBuf->buf, wrBuf->len); + rv = ssl_SaveWriteData(ss, SSL_BUFFER_BASE(wrBuf), + SSL_BUFFER_LEN(wrBuf)); if (rv != SECSuccess) { /* presumably a memory error, SEC_ERROR_NO_MEMORY */ - return SECFailure; + goto loser; } - wrBuf->len = 0; /* All cipher text is saved away. */ if (!(flags & ssl_SEND_FLAG_FORCE_INTO_BUFFER)) { - PRInt32 sent; ss->handshakeBegun = 1; sent = ssl_SendSavedWriteData(ss); if (sent < 0 && PR_GetError() != PR_WOULD_BLOCK_ERROR) { ssl_MapLowLevelError(SSL_ERROR_SOCKET_WRITE_FAILURE); - return SECFailure; + goto loser; } if (ss->pendingBuf.len) { flags |= ssl_SEND_FLAG_FORCE_INTO_BUFFER; } } - } else if (wrBuf->len > 0) { - PRInt32 sent; + } else { + PORT_Assert(SSL_BUFFER_LEN(wrBuf) > 0); ss->handshakeBegun = 1; - sent = ssl_DefSend(ss, wrBuf->buf, wrBuf->len, + sent = ssl_DefSend(ss, SSL_BUFFER_BASE(wrBuf), + SSL_BUFFER_LEN(wrBuf), flags & ~ssl_SEND_FLAG_MASK); if (sent < 0) { - if (PR_GetError() != PR_WOULD_BLOCK_ERROR) { + if (PORT_GetError() != PR_WOULD_BLOCK_ERROR) { ssl_MapLowLevelError(SSL_ERROR_SOCKET_WRITE_FAILURE); - return SECFailure; + goto loser; } /* we got PR_WOULD_BLOCK_ERROR, which means none was sent. */ sent = 0; } - wrBuf->len -= sent; - if (wrBuf->len) { + if (SSL_BUFFER_LEN(wrBuf) > (unsigned int)sent) { if (IS_DTLS(ss)) { /* DTLS just says no in this case. No buffering */ - PR_SetError(PR_WOULD_BLOCK_ERROR, 0); - return SECFailure; + PORT_SetError(PR_WOULD_BLOCK_ERROR); + goto loser; } /* now take all the remaining unsent new ciphertext and * append it to the buffer of previously unsent ciphertext. */ - rv = ssl_SaveWriteData(ss, wrBuf->buf + sent, wrBuf->len); + rv = ssl_SaveWriteData(ss, SSL_BUFFER_BASE(wrBuf) + sent, + SSL_BUFFER_LEN(wrBuf) - sent); if (rv != SECSuccess) { /* presumably a memory error, SEC_ERROR_NO_MEMORY */ - return SECFailure; + goto loser; } } } - totalSent += contentLen; + wrBuf->len = 0; + totalSent += written; } return totalSent; + +loser: + /* Don't leave bits of buffer lying around. */ + wrBuf->len = 0; + return -1; } #define SSL3_PENDING_HIGH_WATER 1024 @@ -2859,6 +2459,7 @@ ssl3_SendApplicationData(sslSocket *ss, const unsigned char *in, { PRInt32 totalSent = 0; PRInt32 discarded = 0; + PRBool splitNeeded = PR_FALSE; PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); /* These flags for internal use only */ @@ -2885,6 +2486,16 @@ ssl3_SendApplicationData(sslSocket *ss, const unsigned char *in, len--; discarded = 1; } + + /* We will split the first byte of the record into its own record, as + * explained in the documentation for SSL_CBC_RANDOM_IV in ssl.h. + */ + if (len > 1 && ss->opt.cbcRandomIV && + ss->version < SSL_LIBRARY_VERSION_TLS_1_1 && + ss->ssl3.cwSpec->cipherDef->type == type_block /* CBC */) { + splitNeeded = PR_TRUE; + } + while (len > totalSent) { PRInt32 sent, toSend; @@ -2899,7 +2510,13 @@ ssl3_SendApplicationData(sslSocket *ss, const unsigned char *in, PR_Sleep(PR_INTERVAL_NO_WAIT); /* PR_Yield(); */ ssl_GetXmitBufLock(ss); } - toSend = PR_MIN(len - totalSent, MAX_FRAGMENT_LENGTH); + + if (splitNeeded) { + toSend = 1; + splitNeeded = PR_FALSE; + } else { + toSend = PR_MIN(len - totalSent, MAX_FRAGMENT_LENGTH); + } /* * Note that the 0 epoch is OK because flags will never require @@ -2959,9 +2576,8 @@ ssl3_FlushHandshake(sslSocket *ss, PRInt32 flags) { if (IS_DTLS(ss)) { return dtls_FlushHandshakeMessages(ss, flags); - } else { - return ssl3_FlushHandshakeMessages(ss, flags); } + return ssl3_FlushHandshakeMessages(ss, flags); } /* Attempt to send the content of sendBuf buffer in an SSL handshake record. @@ -2973,8 +2589,7 @@ ssl3_FlushHandshake(sslSocket *ss, PRInt32 flags) static SECStatus ssl3_FlushHandshakeMessages(sslSocket *ss, PRInt32 flags) { - static const PRInt32 allowedFlags = ssl_SEND_FLAG_FORCE_INTO_BUFFER | - ssl_SEND_FLAG_CAP_RECORD_VERSION; + static const PRInt32 allowedFlags = ssl_SEND_FLAG_FORCE_INTO_BUFFER; PRInt32 count = -1; SECStatus rv; @@ -3037,9 +2652,7 @@ ssl3_HandleNoCertificate(sslSocket *ss) (ss->opt.requireCertificate == SSL_REQUIRE_FIRST_HANDSHAKE))) { PRFileDesc *lower; - if (!ss->opt.noCache) { - ss->sec.uncache(ss->sec.ci.sid); - } + ssl_UncacheSessionID(ss); SSL3_SendAlert(ss, alert_fatal, bad_certificate); lower = ss->fd->lower; @@ -3101,10 +2714,19 @@ SSL3_SendAlert(sslSocket *ss, SSL3AlertLevel level, SSL3AlertDescription desc) ssl_GetSSL3HandshakeLock(ss); } if (level == alert_fatal) { - if (!ss->opt.noCache && ss->sec.ci.sid) { - ss->sec.uncache(ss->sec.ci.sid); + if (ss->sec.ci.sid) { + ssl_UncacheSessionID(ss); } } + + rv = tls13_SetAlertCipherSpec(ss); + if (rv != SECSuccess) { + if (needHsLock) { + ssl_ReleaseSSL3HandshakeLock(ss); + } + return rv; + } + ssl_GetXmitBufLock(ss); rv = ssl3_FlushHandshake(ss, ssl_SEND_FLAG_FORCE_INTO_BUFFER); if (rv == SECSuccess) { @@ -3340,9 +2962,6 @@ ssl3_HandleAlert(sslSocket *ss, sslBuffer *buf) case bad_certificate_hash_value: error = SSL_ERROR_BAD_CERT_HASH_VALUE_ALERT; break; - case end_of_early_data: - error = SSL_ERROR_END_OF_EARLY_DATA_ALERT; - break; default: error = SSL_ERROR_RX_UNKNOWN_ALERT; break; @@ -3354,16 +2973,13 @@ ssl3_HandleAlert(sslSocket *ss, sslBuffer *buf) switch (desc) { case close_notify: case user_canceled: - case end_of_early_data: break; default: level = alert_fatal; } } if (level == alert_fatal) { - if (!ss->opt.noCache) { - ss->sec.uncache(ss->sec.ci.sid); - } + ssl_UncacheSessionID(ss); if ((ss->ssl3.hs.ws == wait_server_hello) && (desc == handshake_failure)) { /* XXX This is a hack. We're assuming that any handshake failure @@ -3374,9 +2990,6 @@ ssl3_HandleAlert(sslSocket *ss, sslBuffer *buf) PORT_SetError(error); return SECFailure; } - if (desc == end_of_early_data) { - return tls13_HandleEndOfEarlyData(ss); - } if ((desc == no_certificate) && (ss->ssl3.hs.ws == wait_client_cert)) { /* I'm a server. I've requested a client cert. He hasn't got one. */ SECStatus rv; @@ -3399,59 +3012,64 @@ ssl3_HandleAlert(sslSocket *ss, sslBuffer *buf) * and pending write spec pointers. */ -static SECStatus -ssl3_SendChangeCipherSpecs(sslSocket *ss) +SECStatus +ssl3_SendChangeCipherSpecsInt(sslSocket *ss) { PRUint8 change = change_cipher_spec_choice; - ssl3CipherSpec *pwSpec; SECStatus rv; - PRInt32 sent; SSL_TRC(3, ("%d: SSL3[%d]: send change_cipher_spec record", SSL_GETPID(), ss->fd)); - PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); - PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); - rv = ssl3_FlushHandshake(ss, ssl_SEND_FLAG_FORCE_INTO_BUFFER); if (rv != SECSuccess) { - return rv; /* error code set by ssl3_FlushHandshake */ + return SECFailure; /* error code set by ssl3_FlushHandshake */ } + if (!IS_DTLS(ss)) { - sent = ssl3_SendRecord(ss, NULL, content_change_cipher_spec, &change, 1, - ssl_SEND_FLAG_FORCE_INTO_BUFFER); + PRInt32 sent; + sent = ssl3_SendRecord(ss, NULL, content_change_cipher_spec, + &change, 1, ssl_SEND_FLAG_FORCE_INTO_BUFFER); if (sent < 0) { - return (SECStatus)sent; /* error code set by ssl3_SendRecord */ + 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 rv; + return SECFailure; } } + return SECSuccess; +} + +static SECStatus +ssl3_SendChangeCipherSpecs(sslSocket *ss) +{ + SECStatus rv; + + PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); + PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); + + rv = ssl3_SendChangeCipherSpecsInt(ss); + if (rv != SECSuccess) { + return rv; /* Error code set. */ + } /* swap the pending and current write specs. */ ssl_GetSpecWriteLock(ss); /**************************************/ - pwSpec = ss->ssl3.pwSpec; - ss->ssl3.pwSpec = ss->ssl3.cwSpec; - ss->ssl3.cwSpec = pwSpec; + ssl_CipherSpecRelease(ss->ssl3.cwSpec); + ss->ssl3.cwSpec = ss->ssl3.pwSpec; + ss->ssl3.pwSpec = NULL; SSL_TRC(3, ("%d: SSL3[%d] Set Current Write Cipher Suite to Pending", SSL_GETPID(), ss->fd)); - /* We need to free up the contexts, keys and certs ! */ - /* If we are really through with the old cipher spec - * (Both the read and write sides have changed) destroy it. - */ - if (ss->ssl3.prSpec == ss->ssl3.pwSpec) { - if (!IS_DTLS(ss)) { - ssl3_DestroyCipherSpec(ss->ssl3.pwSpec, PR_FALSE /*freeSrvName*/); - } else { - /* With DTLS, we need to set a holddown timer in case the final - * message got lost */ - rv = dtls_StartHolddownTimer(ss); - } + /* With DTLS, we need to set a holddown timer in case the final + * message got lost */ + if (IS_DTLS(ss) && ss->ssl3.crSpec->epoch == ss->ssl3.cwSpec->epoch) { + rv = dtls_StartHolddownTimer(ss); } ssl_ReleaseSpecWriteLock(ss); /**************************************/ @@ -3467,7 +3085,6 @@ ssl3_SendChangeCipherSpecs(sslSocket *ss) static SECStatus ssl3_HandleChangeCipherSpecs(sslSocket *ss, sslBuffer *buf) { - ssl3CipherSpec *prSpec; SSL3WaitState ws = ss->ssl3.hs.ws; SSL3ChangeCipherSpecChoice change; @@ -3477,19 +3094,18 @@ ssl3_HandleChangeCipherSpecs(sslSocket *ss, sslBuffer *buf) SSL_TRC(3, ("%d: SSL3[%d]: handle change_cipher_spec record", SSL_GETPID(), ss->fd)); - if (ws != wait_change_cipher) { - if (IS_DTLS(ss)) { - /* Ignore this because it's out of order. */ - SSL_TRC(3, ("%d: SSL3[%d]: discard out of order " - "DTLS change_cipher_spec", - SSL_GETPID(), ss->fd)); - buf->len = 0; - return SECSuccess; - } - (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message); - PORT_SetError(SSL_ERROR_RX_UNEXPECTED_CHANGE_CIPHER); - return SECFailure; + /* For DTLS: Ignore this if we aren't expecting it. Don't kill a connection + * as a result of receiving trash. + * For TLS: Maybe ignore, but only after checking format. */ + if (ws != wait_change_cipher && IS_DTLS(ss)) { + /* Ignore this because it's out of order. */ + SSL_TRC(3, ("%d: SSL3[%d]: discard out of order " + "DTLS change_cipher_spec", + SSL_GETPID(), ss->fd)); + buf->len = 0; + return SECSuccess; } + /* Handshake messages should not span ChangeCipherSpec. */ if (ss->ssl3.hs.header_bytes) { (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message); @@ -3508,26 +3124,44 @@ ssl3_HandleChangeCipherSpecs(sslSocket *ss, sslBuffer *buf) PORT_SetError(SSL_ERROR_RX_MALFORMED_CHANGE_CIPHER); return SECFailure; } - buf->len = 0; - - /* Swap the pending and current read specs. */ - ssl_GetSpecWriteLock(ss); /*************************************/ - prSpec = ss->ssl3.prSpec; - ss->ssl3.prSpec = ss->ssl3.crSpec; - ss->ssl3.crSpec = prSpec; - ss->ssl3.hs.ws = wait_finished; + buf->len = 0; + if (ws != wait_change_cipher) { + /* Ignore a CCS for TLS 1.3. This only happens if the server sends a + * HelloRetryRequest. In other cases, the CCS will fail decryption and + * will be discarded by ssl3_HandleRecord(). */ + if (ws == wait_server_hello && + ss->version >= SSL_LIBRARY_VERSION_TLS_1_3 && + ss->ssl3.hs.helloRetry) { + PORT_Assert(!ss->sec.isServer); + return SECSuccess; + } + /* Note: For a server, we can't test ss->ssl3.hs.helloRetry or + * ss->version because the server might be stateless (and so it won't + * have set either value yet). Set a flag so that at least we will + * guarantee that the server will treat any ClientHello properly. */ + if (ws == wait_client_hello && + ss->vrange.max >= SSL_LIBRARY_VERSION_TLS_1_3 && + !ss->ssl3.hs.receivedCcs) { + PORT_Assert(ss->sec.isServer); + ss->ssl3.hs.receivedCcs = PR_TRUE; + return SECSuccess; + } + (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message); + PORT_SetError(SSL_ERROR_RX_UNEXPECTED_CHANGE_CIPHER); + return SECFailure; + } SSL_TRC(3, ("%d: SSL3[%d] Set Current Read Cipher Suite to Pending", SSL_GETPID(), ss->fd)); - - /* If we are really through with the old cipher prSpec - * (Both the read and write sides have changed) destroy it. - */ - if (ss->ssl3.prSpec == ss->ssl3.pwSpec) { - ssl3_DestroyCipherSpec(ss->ssl3.prSpec, PR_FALSE /*freeSrvName*/); - } + ssl_GetSpecWriteLock(ss); /*************************************/ + PORT_Assert(ss->ssl3.prSpec); + ssl_CipherSpecRelease(ss->ssl3.crSpec); + ss->ssl3.crSpec = ss->ssl3.prSpec; + ss->ssl3.prSpec = NULL; ssl_ReleaseSpecWriteLock(ss); /*************************************/ + + ss->ssl3.hs.ws = wait_finished; return SECSuccess; } @@ -3650,12 +3284,8 @@ static SECStatus ssl3_ComputeMasterSecretInt(sslSocket *ss, PK11SymKey *pms, PK11SymKey **msp) { - ssl3CipherSpec *pwSpec = ss->ssl3.pwSpec; - unsigned char *cr = (unsigned char *)&ss->ssl3.hs.client_random; - unsigned char *sr = (unsigned char *)&ss->ssl3.hs.server_random; - PRBool isTLS = (PRBool)(pwSpec->version > SSL_LIBRARY_VERSION_3_0); - PRBool isTLS12 = - (PRBool)(isTLS && pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2); + PRBool isTLS = (PRBool)(ss->version > SSL_LIBRARY_VERSION_3_0); + PRBool isTLS12 = (PRBool)(ss->version >= SSL_LIBRARY_VERSION_TLS_1_2); /* * Whenever isDH is true, we need to use CKM_TLS_MASTER_KEY_DERIVE_DH * which, unlike CKM_TLS_MASTER_KEY_DERIVE, converts arbitrary size @@ -3701,9 +3331,9 @@ ssl3_ComputeMasterSecretInt(sslSocket *ss, PK11SymKey *pms, } master_params.pVersion = pms_version_ptr; - master_params.RandomInfo.pClientRandom = cr; + master_params.RandomInfo.pClientRandom = ss->ssl3.hs.client_random; master_params.RandomInfo.ulClientRandomLen = SSL3_RANDOM_LENGTH; - master_params.RandomInfo.pServerRandom = sr; + master_params.RandomInfo.pServerRandom = ss->ssl3.hs.server_random; master_params.RandomInfo.ulServerRandomLen = SSL3_RANDOM_LENGTH; if (isTLS12) { master_params.prfHashMechanism = ssl3_GetPrfHashMechanism(ss); @@ -3763,7 +3393,7 @@ tls_ComputeExtendedMasterSecretInt(sslSocket *ss, PK11SymKey *pms, pms_version_ptr = &pms_version; } - if (pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2) { + if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_2) { /* TLS 1.2+ */ extended_master_params.prfHashMechanism = ssl3_GetPrfHashMechanism(ss); key_derive = CKM_TLS12_KEY_AND_MAC_DERIVE; @@ -3795,7 +3425,6 @@ ssl3_ComputeMasterSecret(sslSocket *ss, PK11SymKey *pms, { PORT_Assert(pms != NULL); PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); - PORT_Assert(ss->ssl3.prSpec == ss->ssl3.pwSpec); if (ssl3_ExtensionNegotiated(ss, ssl_extended_master_secret_xtn)) { return tls_ComputeExtendedMasterSecretInt(ss, pms, msp); @@ -3804,36 +3433,6 @@ ssl3_ComputeMasterSecret(sslSocket *ss, PK11SymKey *pms, } } -/* This method uses PKCS11 to derive the MS from the PMS, where PMS -** is a PKCS11 symkey. We call ssl3_ComputeMasterSecret to do the -** computations and then modify the pwSpec->state as a side effect. -** -** This is used in all cases except the "triple bypass" with RSA key -** exchange. -** -** Called from ssl3_InitPendingCipherSpec. prSpec is pwSpec. -*/ -static SECStatus -ssl3_DeriveMasterSecret(sslSocket *ss, PK11SymKey *pms) -{ - SECStatus rv; - PK11SymKey *ms = NULL; - ssl3CipherSpec *pwSpec = ss->ssl3.pwSpec; - - PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); - PORT_Assert(ss->opt.noLocks || ssl_HaveSpecWriteLock(ss)); - PORT_Assert(ss->ssl3.prSpec == ss->ssl3.pwSpec); - - if (pms) { - rv = ssl3_ComputeMasterSecret(ss, pms, &ms); - pwSpec->master_secret = ms; - if (rv != SECSuccess) - return rv; - } - - return SECSuccess; -} - /* * Derive encryption and MAC Keys (and IVs) from master secret * Sets a useful error code when returning SECFailure. @@ -3850,17 +3449,18 @@ ssl3_DeriveMasterSecret(sslSocket *ss, PK11SymKey *pms) * */ static SECStatus -ssl3_DeriveConnectionKeys(sslSocket *ss) +ssl3_DeriveConnectionKeys(sslSocket *ss, PK11SymKey *masterSecret) { ssl3CipherSpec *pwSpec = ss->ssl3.pwSpec; - unsigned char *cr = (unsigned char *)&ss->ssl3.hs.client_random; - unsigned char *sr = (unsigned char *)&ss->ssl3.hs.server_random; - PRBool isTLS = (PRBool)(pwSpec->version > SSL_LIBRARY_VERSION_3_0); + ssl3CipherSpec *prSpec = ss->ssl3.prSpec; + ssl3CipherSpec *clientSpec; + ssl3CipherSpec *serverSpec; + PRBool isTLS = (PRBool)(ss->version > SSL_LIBRARY_VERSION_3_0); PRBool isTLS12 = - (PRBool)(isTLS && pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2); - const ssl3BulkCipherDef *cipher_def = pwSpec->cipher_def; + (PRBool)(isTLS && ss->version >= SSL_LIBRARY_VERSION_TLS_1_2); + const ssl3BulkCipherDef *cipher_def = pwSpec->cipherDef; PK11SlotInfo *slot = NULL; - PK11SymKey *symKey = NULL; + PK11SymKey *derivedKeyHandle = NULL; void *pwArg = ss->pkcs11PinArg; int keySize; CK_TLS12_KEY_MAT_PARAMS key_material_params; /* may be used as a @@ -3871,48 +3471,53 @@ ssl3_DeriveConnectionKeys(sslSocket *ss) CK_MECHANISM_TYPE bulk_mechanism; SSLCipherAlgorithm calg; SECItem params; - PRBool skipKeysAndIVs = (PRBool)(cipher_def->calg == calg_null); + PRBool skipKeysAndIVs = (PRBool)(cipher_def->calg == ssl_calg_null); PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); PORT_Assert(ss->opt.noLocks || ssl_HaveSpecWriteLock(ss)); - PORT_Assert(ss->ssl3.prSpec == ss->ssl3.pwSpec); + PORT_Assert(masterSecret); - if (!pwSpec->master_secret) { - PORT_SetError(SSL_ERROR_SESSION_KEY_GEN_FAILURE); - return SECFailure; + /* These functions operate in terms of who is writing specs. */ + if (ss->sec.isServer) { + clientSpec = prSpec; + serverSpec = pwSpec; + } else { + clientSpec = pwSpec; + serverSpec = prSpec; } + /* * generate the key material */ - key_material_params.ulMacSizeInBits = pwSpec->mac_size * BPB; - key_material_params.ulKeySizeInBits = cipher_def->secret_key_size * BPB; - key_material_params.ulIVSizeInBits = cipher_def->iv_size * BPB; if (cipher_def->type == type_block && - pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_1) { + ss->version >= SSL_LIBRARY_VERSION_TLS_1_1) { /* Block ciphers in >= TLS 1.1 use a per-record, explicit IV. */ key_material_params.ulIVSizeInBits = 0; - memset(pwSpec->client.write_iv, 0, cipher_def->iv_size); - memset(pwSpec->server.write_iv, 0, cipher_def->iv_size); + PORT_Memset(clientSpec->keyMaterial.iv, 0, cipher_def->iv_size); + PORT_Memset(serverSpec->keyMaterial.iv, 0, cipher_def->iv_size); } key_material_params.bIsExport = PR_FALSE; - key_material_params.RandomInfo.pClientRandom = cr; + key_material_params.RandomInfo.pClientRandom = ss->ssl3.hs.client_random; key_material_params.RandomInfo.ulClientRandomLen = SSL3_RANDOM_LENGTH; - key_material_params.RandomInfo.pServerRandom = sr; + key_material_params.RandomInfo.pServerRandom = ss->ssl3.hs.server_random; key_material_params.RandomInfo.ulServerRandomLen = SSL3_RANDOM_LENGTH; key_material_params.pReturnedKeyMaterial = &returnedKeys; - returnedKeys.pIVClient = pwSpec->client.write_iv; - returnedKeys.pIVServer = pwSpec->server.write_iv; - keySize = cipher_def->key_size; - if (skipKeysAndIVs) { keySize = 0; - key_material_params.ulKeySizeInBits = 0; - key_material_params.ulIVSizeInBits = 0; returnedKeys.pIVClient = NULL; returnedKeys.pIVServer = NULL; + key_material_params.ulKeySizeInBits = 0; + key_material_params.ulIVSizeInBits = 0; + } else { + keySize = cipher_def->key_size; + returnedKeys.pIVClient = clientSpec->keyMaterial.iv; + returnedKeys.pIVServer = serverSpec->keyMaterial.iv; + key_material_params.ulKeySizeInBits = cipher_def->secret_key_size * BPB; + key_material_params.ulIVSizeInBits = cipher_def->iv_size * BPB; } + key_material_params.ulMacSizeInBits = pwSpec->macDef->mac_size * BPB; calg = cipher_def->calg; bulk_mechanism = ssl3_Alg2Mech(calg); @@ -3934,9 +3539,9 @@ ssl3_DeriveConnectionKeys(sslSocket *ss) /* CKM_SSL3_KEY_AND_MAC_DERIVE is defined to set ENCRYPT, DECRYPT, and * DERIVE by DEFAULT */ - symKey = PK11_Derive(pwSpec->master_secret, key_derive, ¶ms, - bulk_mechanism, CKA_ENCRYPT, keySize); - if (!symKey) { + derivedKeyHandle = PK11_Derive(masterSecret, key_derive, ¶ms, + bulk_mechanism, CKA_ENCRYPT, keySize); + if (!derivedKeyHandle) { ssl_MapLowLevelError(SSL_ERROR_SESSION_KEY_GEN_FAILURE); return SECFailure; } @@ -3944,41 +3549,44 @@ ssl3_DeriveConnectionKeys(sslSocket *ss) * don't because these types are used to map keytype anyway and both * mac's map to the same keytype. */ - slot = PK11_GetSlotFromKey(symKey); + slot = PK11_GetSlotFromKey(derivedKeyHandle); PK11_FreeSlot(slot); /* slot is held until the key is freed */ - pwSpec->client.write_mac_key = - PK11_SymKeyFromHandle(slot, symKey, PK11_OriginDerive, - CKM_SSL3_SHA1_MAC, returnedKeys.hClientMacSecret, PR_TRUE, pwArg); - if (pwSpec->client.write_mac_key == NULL) { + clientSpec->keyMaterial.macKey = + PK11_SymKeyFromHandle(slot, derivedKeyHandle, PK11_OriginDerive, + CKM_SSL3_SHA1_MAC, returnedKeys.hClientMacSecret, + PR_TRUE, pwArg); + if (clientSpec->keyMaterial.macKey == NULL) { goto loser; /* loser sets err */ } - pwSpec->server.write_mac_key = - PK11_SymKeyFromHandle(slot, symKey, PK11_OriginDerive, - CKM_SSL3_SHA1_MAC, returnedKeys.hServerMacSecret, PR_TRUE, pwArg); - if (pwSpec->server.write_mac_key == NULL) { + serverSpec->keyMaterial.macKey = + PK11_SymKeyFromHandle(slot, derivedKeyHandle, PK11_OriginDerive, + CKM_SSL3_SHA1_MAC, returnedKeys.hServerMacSecret, + PR_TRUE, pwArg); + if (serverSpec->keyMaterial.macKey == NULL) { goto loser; /* loser sets err */ } if (!skipKeysAndIVs) { - pwSpec->client.write_key = - PK11_SymKeyFromHandle(slot, symKey, PK11_OriginDerive, - bulk_mechanism, returnedKeys.hClientKey, PR_TRUE, pwArg); - if (pwSpec->client.write_key == NULL) { + clientSpec->keyMaterial.key = + PK11_SymKeyFromHandle(slot, derivedKeyHandle, PK11_OriginDerive, + bulk_mechanism, returnedKeys.hClientKey, + PR_TRUE, pwArg); + if (clientSpec->keyMaterial.key == NULL) { goto loser; /* loser sets err */ } - pwSpec->server.write_key = - PK11_SymKeyFromHandle(slot, symKey, PK11_OriginDerive, - bulk_mechanism, returnedKeys.hServerKey, PR_TRUE, pwArg); - if (pwSpec->server.write_key == NULL) { + serverSpec->keyMaterial.key = + PK11_SymKeyFromHandle(slot, derivedKeyHandle, PK11_OriginDerive, + bulk_mechanism, returnedKeys.hServerKey, + PR_TRUE, pwArg); + if (serverSpec->keyMaterial.key == NULL) { goto loser; /* loser sets err */ } } - PK11_FreeSymKey(symKey); + PK11_FreeSymKey(derivedKeyHandle); return SECSuccess; loser: - if (symKey) - PK11_FreeSymKey(symKey); + PK11_FreeSymKey(derivedKeyHandle); ssl_MapLowLevelError(SSL_ERROR_SESSION_KEY_GEN_FAILURE); return SECFailure; } @@ -4022,11 +3630,11 @@ ssl3_InitHandshakeHashes(sslSocket *ss) return SECFailure; } ss->ssl3.hs.hashType = handshake_hash_single; - if (PK11_DigestBegin(ss->ssl3.hs.sha) != SECSuccess) { ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE); return SECFailure; } + } else { /* Both ss->ssl3.hs.md5 and ss->ssl3.hs.sha should be NULL or * created successfully. */ @@ -4117,7 +3725,7 @@ ssl3_UpdateHandshakeHashes(sslSocket *ss, const unsigned char *b, unsigned int l return sslBuffer_Append(&ss->ssl3.hs.messages, b, l); } - PRINT_BUF(90, (NULL, "handshake hash input:", b, l)); + PRINT_BUF(90, (ss, "handshake hash input:", b, l)); if (ss->ssl3.hs.hashType == handshake_hash_single) { PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_TLS_1_3); @@ -4141,104 +3749,8 @@ ssl3_UpdateHandshakeHashes(sslSocket *ss, const unsigned char *b, unsigned int l return rv; } -/************************************************************************** - * Append Handshake functions. - * All these functions set appropriate error codes. - * Most rely on ssl3_AppendHandshake to set the error code. - **************************************************************************/ -SECStatus -ssl3_AppendHandshake(sslSocket *ss, const void *void_src, PRInt32 bytes) -{ - unsigned char *src = (unsigned char *)void_src; - int room = ss->sec.ci.sendBuf.space - ss->sec.ci.sendBuf.len; - SECStatus rv; - - PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); /* protects sendBuf. */ - - if (!bytes) - return SECSuccess; - if (ss->sec.ci.sendBuf.space < MAX_SEND_BUF_LENGTH && room < bytes) { - rv = sslBuffer_Grow(&ss->sec.ci.sendBuf, PR_MAX(MIN_SEND_BUF_LENGTH, - PR_MIN(MAX_SEND_BUF_LENGTH, ss->sec.ci.sendBuf.len + bytes))); - if (rv != SECSuccess) - return rv; /* sslBuffer_Grow has set a memory error code. */ - room = ss->sec.ci.sendBuf.space - ss->sec.ci.sendBuf.len; - } - - PRINT_BUF(60, (ss, "Append to Handshake", (unsigned char *)void_src, bytes)); - rv = ssl3_UpdateHandshakeHashes(ss, src, bytes); - if (rv != SECSuccess) - return rv; /* error code set by ssl3_UpdateHandshakeHashes */ - - while (bytes > room) { - if (room > 0) - PORT_Memcpy(ss->sec.ci.sendBuf.buf + ss->sec.ci.sendBuf.len, src, - room); - ss->sec.ci.sendBuf.len += room; - rv = ssl3_FlushHandshake(ss, ssl_SEND_FLAG_FORCE_INTO_BUFFER); - if (rv != SECSuccess) { - return rv; /* error code set by ssl3_FlushHandshake */ - } - bytes -= room; - src += room; - room = ss->sec.ci.sendBuf.space; - PORT_Assert(ss->sec.ci.sendBuf.len == 0); - } - PORT_Memcpy(ss->sec.ci.sendBuf.buf + ss->sec.ci.sendBuf.len, src, bytes); - ss->sec.ci.sendBuf.len += bytes; - return SECSuccess; -} - -SECStatus -ssl3_AppendHandshakeNumber(sslSocket *ss, PRInt32 num, PRInt32 lenSize) -{ - SECStatus rv; - PRUint8 b[4]; - PRUint8 *p = b; - - PORT_Assert(lenSize <= 4 && lenSize > 0); - if (lenSize < 4 && num >= (1L << (lenSize * 8))) { - PORT_SetError(SSL_ERROR_TX_RECORD_TOO_LONG); - return SECFailure; - } - - switch (lenSize) { - case 4: - *p++ = (num >> 24) & 0xff; - case 3: - *p++ = (num >> 16) & 0xff; - case 2: - *p++ = (num >> 8) & 0xff; - case 1: - *p = num & 0xff; - } - SSL_TRC(60, ("%d: number:", SSL_GETPID())); - rv = ssl3_AppendHandshake(ss, &b[0], lenSize); - return rv; /* error code set by AppendHandshake, if applicable. */ -} - -SECStatus -ssl3_AppendHandshakeVariable( - sslSocket *ss, const PRUint8 *src, PRInt32 bytes, PRInt32 lenSize) -{ - SECStatus rv; - - PORT_Assert((bytes < (1 << 8) && lenSize == 1) || - (bytes < (1L << 16) && lenSize == 2) || - (bytes < (1L << 24) && lenSize == 3)); - - SSL_TRC(60, ("%d: append variable:", SSL_GETPID())); - rv = ssl3_AppendHandshakeNumber(ss, bytes, lenSize); - if (rv != SECSuccess) { - return rv; /* error code set by AppendHandshake, if applicable. */ - } - SSL_TRC(60, ("data:")); - rv = ssl3_AppendHandshake(ss, src, bytes); - return rv; /* error code set by AppendHandshake, if applicable. */ -} - SECStatus -ssl3_AppendHandshakeHeader(sslSocket *ss, SSL3HandshakeType t, PRUint32 length) +ssl3_AppendHandshakeHeader(sslSocket *ss, SSLHandshakeType t, PRUint32 length) { SECStatus rv; @@ -4330,17 +3842,22 @@ ssl3_ConsumeHandshake(sslSocket *ss, void *v, PRUint32 bytes, PRUint8 **b, * On error, an alert has been sent, and a generic error code has been set. */ SECStatus -ssl3_ConsumeHandshakeNumber(sslSocket *ss, PRUint32 *num, PRUint32 bytes, - PRUint8 **b, PRUint32 *length) +ssl3_ConsumeHandshakeNumber64(sslSocket *ss, PRUint64 *num, PRUint32 bytes, + PRUint8 **b, PRUint32 *length) { PRUint8 *buf = *b; - int i; + PRUint32 i; PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss)); PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); *num = 0; - if (bytes > *length || bytes > sizeof(*num)) { + if (bytes > sizeof(*num)) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + + if (bytes > *length) { return ssl3_DecodeError(ss); } PRINT_BUF(60, (ss, "consume bytes:", *b, bytes)); @@ -4353,6 +3870,26 @@ ssl3_ConsumeHandshakeNumber(sslSocket *ss, PRUint32 *num, PRUint32 bytes, return SECSuccess; } +SECStatus +ssl3_ConsumeHandshakeNumber(sslSocket *ss, PRUint32 *num, PRUint32 bytes, + PRUint8 **b, PRUint32 *length) +{ + PRUint64 num64; + SECStatus rv; + + PORT_Assert(bytes <= sizeof(*num)); + if (bytes > sizeof(*num)) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + rv = ssl3_ConsumeHandshakeNumber64(ss, &num64, bytes, b, length); + if (rv != SECSuccess) { + return SECFailure; + } + *num = num64 & 0xffffffff; + return SECSuccess; +} + /* Read in two values from the incoming decrypted byte stream "b", which is * *length bytes long. The first value is a number whose size is "bytes" * bytes long. The second value is a byte-string whose size is the value @@ -4426,17 +3963,20 @@ ssl_SignatureSchemeToHashType(SSLSignatureScheme scheme) return ssl_hash_sha1; case ssl_sig_rsa_pkcs1_sha256: case ssl_sig_ecdsa_secp256r1_sha256: - case ssl_sig_rsa_pss_sha256: + case ssl_sig_rsa_pss_rsae_sha256: + case ssl_sig_rsa_pss_pss_sha256: case ssl_sig_dsa_sha256: return ssl_hash_sha256; case ssl_sig_rsa_pkcs1_sha384: case ssl_sig_ecdsa_secp384r1_sha384: - case ssl_sig_rsa_pss_sha384: + case ssl_sig_rsa_pss_rsae_sha384: + case ssl_sig_rsa_pss_pss_sha384: case ssl_sig_dsa_sha384: return ssl_hash_sha384; case ssl_sig_rsa_pkcs1_sha512: case ssl_sig_ecdsa_secp521r1_sha512: - case ssl_sig_rsa_pss_sha512: + case ssl_sig_rsa_pss_rsae_sha512: + case ssl_sig_rsa_pss_pss_sha512: case ssl_sig_dsa_sha512: return ssl_hash_sha512; case ssl_sig_rsa_pkcs1_sha1md5: @@ -4458,9 +3998,12 @@ ssl_SignatureSchemeToKeyType(SSLSignatureScheme scheme) case ssl_sig_rsa_pkcs1_sha384: case ssl_sig_rsa_pkcs1_sha512: case ssl_sig_rsa_pkcs1_sha1: - case ssl_sig_rsa_pss_sha256: - case ssl_sig_rsa_pss_sha384: - case ssl_sig_rsa_pss_sha512: + case ssl_sig_rsa_pss_rsae_sha256: + case ssl_sig_rsa_pss_rsae_sha384: + case ssl_sig_rsa_pss_rsae_sha512: + case ssl_sig_rsa_pss_pss_sha256: + case ssl_sig_rsa_pss_pss_sha384: + case ssl_sig_rsa_pss_pss_sha512: case ssl_sig_rsa_pkcs1_sha1md5: return rsaKey; case ssl_sig_ecdsa_secp256r1_sha256: @@ -4595,9 +4138,9 @@ ssl_IsSupportedSignatureScheme(SSLSignatureScheme scheme) case ssl_sig_rsa_pkcs1_sha256: case ssl_sig_rsa_pkcs1_sha384: case ssl_sig_rsa_pkcs1_sha512: - case ssl_sig_rsa_pss_sha256: - case ssl_sig_rsa_pss_sha384: - case ssl_sig_rsa_pss_sha512: + case ssl_sig_rsa_pss_rsae_sha256: + case ssl_sig_rsa_pss_rsae_sha384: + case ssl_sig_rsa_pss_rsae_sha512: case ssl_sig_ecdsa_secp256r1_sha256: case ssl_sig_ecdsa_secp384r1_sha384: case ssl_sig_ecdsa_secp521r1_sha512: @@ -4609,6 +4152,9 @@ ssl_IsSupportedSignatureScheme(SSLSignatureScheme scheme) return PR_TRUE; case ssl_sig_rsa_pkcs1_sha1md5: + case ssl_sig_rsa_pss_pss_sha256: + case ssl_sig_rsa_pss_pss_sha384: + case ssl_sig_rsa_pss_pss_sha512: case ssl_sig_none: case ssl_sig_ed25519: case ssl_sig_ed448: @@ -4621,9 +4167,9 @@ PRBool ssl_IsRsaPssSignatureScheme(SSLSignatureScheme scheme) { switch (scheme) { - case ssl_sig_rsa_pss_sha256: - case ssl_sig_rsa_pss_sha384: - case ssl_sig_rsa_pss_sha512: + case ssl_sig_rsa_pss_rsae_sha256: + case ssl_sig_rsa_pss_rsae_sha384: + case ssl_sig_rsa_pss_rsae_sha512: return PR_TRUE; default: @@ -4726,6 +4272,7 @@ ssl3_ComputeHandshakeHashes(sslSocket *ss, sizeof(stackBuf), &stateLen); if (stateBuf == NULL) { ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE); + rv = SECFailure; goto tls12_loser; } rv |= PK11_DigestFinal(h, hashes->u.raw, &hashes->len, @@ -4737,7 +4284,6 @@ ssl3_ComputeHandshakeHashes(sslSocket *ss, } hashes->hashAlg = ssl3_GetSuitePrfHash(ss); - rv = SECSuccess; tls12_loser: if (stateBuf) { @@ -4762,11 +4308,14 @@ ssl3_ComputeHandshakeHashes(sslSocket *ss, unsigned int md5StateLen, shaStateLen; unsigned char md5StackBuf[256]; unsigned char shaStackBuf[512]; + const int md5Pad = ssl_GetMacDefByAlg(ssl_mac_md5)->pad_size; + const int shaPad = ssl_GetMacDefByAlg(ssl_mac_sha)->pad_size; md5StateBuf = PK11_SaveContextAlloc(ss->ssl3.hs.md5, md5StackBuf, sizeof md5StackBuf, &md5StateLen); if (md5StateBuf == NULL) { ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE); + rv = SECFailure; goto loser; } md5 = ss->ssl3.hs.md5; @@ -4775,6 +4324,7 @@ ssl3_ComputeHandshakeHashes(sslSocket *ss, sizeof shaStackBuf, &shaStateLen); if (shaStateBuf == NULL) { ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE); + rv = SECFailure; goto loser; } sha = ss->ssl3.hs.sha; @@ -4783,7 +4333,7 @@ ssl3_ComputeHandshakeHashes(sslSocket *ss, /* compute hashes for SSL3. */ unsigned char s[4]; - if (!spec->master_secret) { + if (!spec->masterSecret) { PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HANDSHAKE); rv = SECFailure; goto loser; @@ -4799,11 +4349,10 @@ ssl3_ComputeHandshakeHashes(sslSocket *ss, PRINT_BUF(95, (NULL, "MD5 inner: sender", s, 4)); } - PRINT_BUF(95, (NULL, "MD5 inner: MAC Pad 1", mac_pad_1, - mac_defs[mac_md5].pad_size)); + PRINT_BUF(95, (NULL, "MD5 inner: MAC Pad 1", mac_pad_1, md5Pad)); - rv |= PK11_DigestKey(md5, spec->master_secret); - rv |= PK11_DigestOp(md5, mac_pad_1, mac_defs[mac_md5].pad_size); + rv |= PK11_DigestKey(md5, spec->masterSecret); + rv |= PK11_DigestOp(md5, mac_pad_1, md5Pad); rv |= PK11_DigestFinal(md5, md5_inner, &outLength, MD5_LENGTH); PORT_Assert(rv != SECSuccess || outLength == MD5_LENGTH); if (rv != SECSuccess) { @@ -4819,11 +4368,10 @@ ssl3_ComputeHandshakeHashes(sslSocket *ss, PRINT_BUF(95, (NULL, "SHA inner: sender", s, 4)); } - PRINT_BUF(95, (NULL, "SHA inner: MAC Pad 1", mac_pad_1, - mac_defs[mac_sha].pad_size)); + PRINT_BUF(95, (NULL, "SHA inner: MAC Pad 1", mac_pad_1, shaPad)); - rv |= PK11_DigestKey(sha, spec->master_secret); - rv |= PK11_DigestOp(sha, mac_pad_1, mac_defs[mac_sha].pad_size); + rv |= PK11_DigestKey(sha, spec->masterSecret); + rv |= PK11_DigestOp(sha, mac_pad_1, shaPad); rv |= PK11_DigestFinal(sha, sha_inner, &outLength, SHA1_LENGTH); PORT_Assert(rv != SECSuccess || outLength == SHA1_LENGTH); if (rv != SECSuccess) { @@ -4834,13 +4382,12 @@ ssl3_ComputeHandshakeHashes(sslSocket *ss, PRINT_BUF(95, (NULL, "SHA inner: result", sha_inner, outLength)); - PRINT_BUF(95, (NULL, "MD5 outer: MAC Pad 2", mac_pad_2, - mac_defs[mac_md5].pad_size)); + PRINT_BUF(95, (NULL, "MD5 outer: MAC Pad 2", mac_pad_2, md5Pad)); PRINT_BUF(95, (NULL, "MD5 outer: MD5 inner", md5_inner, MD5_LENGTH)); rv |= PK11_DigestBegin(md5); - rv |= PK11_DigestKey(md5, spec->master_secret); - rv |= PK11_DigestOp(md5, mac_pad_2, mac_defs[mac_md5].pad_size); + rv |= PK11_DigestKey(md5, spec->masterSecret); + rv |= PK11_DigestOp(md5, mac_pad_2, md5Pad); rv |= PK11_DigestOp(md5, md5_inner, MD5_LENGTH); } rv |= PK11_DigestFinal(md5, hashes->u.s.md5, &outLength, MD5_LENGTH); @@ -4854,13 +4401,12 @@ ssl3_ComputeHandshakeHashes(sslSocket *ss, PRINT_BUF(60, (NULL, "MD5 outer: result", hashes->u.s.md5, MD5_LENGTH)); if (!isTLS) { - PRINT_BUF(95, (NULL, "SHA outer: MAC Pad 2", mac_pad_2, - mac_defs[mac_sha].pad_size)); + PRINT_BUF(95, (NULL, "SHA outer: MAC Pad 2", mac_pad_2, shaPad)); PRINT_BUF(95, (NULL, "SHA outer: SHA inner", sha_inner, SHA1_LENGTH)); rv |= PK11_DigestBegin(sha); - rv |= PK11_DigestKey(sha, spec->master_secret); - rv |= PK11_DigestOp(sha, mac_pad_2, mac_defs[mac_sha].pad_size); + rv |= PK11_DigestKey(sha, spec->masterSecret); + rv |= PK11_DigestOp(sha, mac_pad_2, shaPad); rv |= PK11_DigestOp(sha, sha_inner, SHA1_LENGTH); } rv |= PK11_DigestFinal(sha, hashes->u.s.sha, &outLength, SHA1_LENGTH); @@ -4874,7 +4420,6 @@ ssl3_ComputeHandshakeHashes(sslSocket *ss, PRINT_BUF(60, (NULL, "SHA outer: result", hashes->u.s.sha, SHA1_LENGTH)); hashes->len = MD5_LENGTH + SHA1_LENGTH; - rv = SECSuccess; loser: if (md5StateBuf) { @@ -4926,6 +4471,48 @@ ssl_ClientHelloTypeName(sslClientHelloType type) #undef CHTYPE #endif +PR_STATIC_ASSERT(SSL3_SESSIONID_BYTES == SSL3_RANDOM_LENGTH); +static void +ssl_MakeFakeSid(sslSocket *ss, PRUint8 *buf) +{ + PRUint8 x = 0x5a; + int i; + for (i = 0; i < SSL3_SESSIONID_BYTES; ++i) { + x += ss->ssl3.hs.client_random[i]; + buf[i] = x; + } +} + +/* Set the version fields of the cipher spec for a ClientHello. */ +static void +ssl_SetClientHelloSpecVersion(sslSocket *ss, ssl3CipherSpec *spec) +{ + ssl_GetSpecWriteLock(ss); + PORT_Assert(spec->cipherDef->cipher == cipher_null); + /* This is - a best guess - but it doesn't matter here. */ + spec->version = ss->vrange.max; + if (IS_DTLS(ss)) { + spec->recordVersion = SSL_LIBRARY_VERSION_DTLS_1_0_WIRE; + } else { + /* For new connections, cap the record layer version number of TLS + * ClientHello to { 3, 1 } (TLS 1.0). Some TLS 1.0 servers (which seem + * to use F5 BIG-IP) ignore ClientHello.client_version and use the + * record layer version number (TLSPlaintext.version) instead when + * negotiating protocol versions. In addition, if the record layer + * version number of ClientHello is { 3, 2 } (TLS 1.1) or higher, these + * servers reset the TCP connections. Lastly, some F5 BIG-IP servers + * hang if a record containing a ClientHello has a version greater than + * { 3, 1 } and a length greater than 255. Set this flag to work around + * such servers. + * + * The final version is set when a version is negotiated. + */ + spec->recordVersion = PR_MIN(SSL_LIBRARY_VERSION_TLS_1_0, + ss->vrange.max); + } + ssl_ReleaseSpecWriteLock(ss); +} + /* Called from ssl3_HandleHelloRequest(), * ssl3_RedoHandshake() * ssl_BeginClientHandshake (when resuming ssl3 session) @@ -4942,18 +4529,18 @@ SECStatus ssl3_SendClientHello(sslSocket *ss, sslClientHelloType type) { sslSessionID *sid; - ssl3CipherSpec *cwSpec; SECStatus rv; - int i; - int length; - int num_suites; - int actual_count = 0; + unsigned int i; + unsigned int length; + unsigned int num_suites; + unsigned int actual_count = 0; PRBool isTLS = PR_FALSE; PRBool requestingResume = PR_FALSE, fallbackSCSV = PR_FALSE; - PRInt32 total_exten_len = 0; - unsigned numCompressionMethods; - PRUint16 version; + PRBool unlockNeeded = PR_FALSE; + sslBuffer extensionBuf = SSL_BUFFER_EMPTY; + PRUint16 version = ss->vrange.max; PRInt32 flags; + unsigned int cookieLen = ss->ssl3.hs.cookie.len; SSL_TRC(3, ("%d: SSL3[%d]: send %s ClientHello handshake", SSL_GETPID(), ss->fd, ssl_ClientHelloTypeName(type))); @@ -4972,22 +4559,26 @@ ssl3_SendClientHello(sslSocket *ss, sslClientHelloType type) * to maintain the handshake hashes. */ if (ss->ssl3.hs.helloRetry) { PORT_Assert(type == client_hello_retry); + /* This cookieLen applies to the cookie that appears in the DTLS + ClientHello, which isn't used in DTLS 1.3. */ + cookieLen = 0; } else { - ssl3_InitState(ss); ssl3_RestartHandshakeHashes(ss); } + if (type == client_hello_initial) { + ssl_SetClientHelloSpecVersion(ss, ss->ssl3.cwSpec); + } /* These must be reset every handshake. */ + ssl3_ResetExtensionData(&ss->xtnData, ss); ss->ssl3.hs.sendingSCSV = PR_FALSE; ss->ssl3.hs.preliminaryInfo = 0; PORT_Assert(IS_DTLS(ss) || type != client_hello_retransmit); SECITEM_FreeItem(&ss->ssl3.hs.newSessionTicket.ticket, PR_FALSE); ss->ssl3.hs.receivedNewSessionTicket = PR_FALSE; - ssl3_ResetExtensionData(&ss->xtnData); /* How many suites does our PKCS11 support (regardless of policy)? */ - num_suites = ssl3_config_match_init(ss); - if (!num_suites) { + if (ssl3_config_match_init(ss) == 0) { return SECFailure; /* ssl3_config_match_init has set error code. */ } @@ -5009,13 +4600,24 @@ ssl3_SendClientHello(sslSocket *ss, sslClientHelloType type) } } - /* We ignore ss->sec.ci.sid here, and use ssl_Lookup because Lookup - * handles expired entries and other details. - * XXX If we've been called from ssl_BeginClientHandshake, then - * this lookup is duplicative and wasteful. - */ - sid = (ss->opt.noCache) ? NULL - : ssl_LookupSID(&ss->sec.ci.peer, ss->sec.ci.port, ss->peerID, ss->url); + /* Check if we have a ss->sec.ci.sid. + * Check that it's not expired. + * If we have an sid and it comes from an external cache, we use it. */ + if (ss->sec.ci.sid && ss->sec.ci.sid->cached == in_external_cache) { + PORT_Assert(!ss->sec.isServer); + sid = ss->sec.ci.sid; + SSL_TRC(3, ("%d: SSL3[%d]: using external resumption token in ClientHello", + SSL_GETPID(), ss->fd)); + } else if (!ss->opt.noCache) { + /* We ignore ss->sec.ci.sid here, and use ssl_Lookup because Lookup + * handles expired entries and other details. + * XXX If we've been called from ssl_BeginClientHandshake, then + * this lookup is duplicative and wasteful. + */ + sid = ssl_LookupSID(&ss->sec.ci.peer, ss->sec.ci.port, ss->peerID, ss->url); + } else { + sid = NULL; + } /* We can't resume based on a different token. If the sid exists, * make sure the token that holds the master secret still exists ... @@ -5035,7 +4637,7 @@ ssl3_SendClientHello(sslSocket *ss, sslClientHelloType type) } /* Check that we can recover the master secret. */ - if (sidOK && sid->u.ssl3.keys.msIsWrapped) { + if (sidOK) { PK11SlotInfo *slot = NULL; if (sid->u.ssl3.masterValid) { slot = SECMOD_LookupSlot(sid->u.ssl3.masterModuleID, @@ -5100,15 +4702,13 @@ ssl3_SendClientHello(sslSocket *ss, sslClientHelloType type) if (sid->version < ss->vrange.min || sid->version > ss->vrange.max) { sidOK = PR_FALSE; - } else { - version = ss->vrange.max; } } } if (!sidOK) { SSL_AtomicIncrementLong(&ssl3stats.sch_sid_cache_not_ok); - ss->sec.uncache(sid); + ssl_UncacheSessionID(ss); ssl_FreeSID(sid); sid = NULL; } @@ -5135,8 +4735,6 @@ ssl3_SendClientHello(sslSocket *ss, sslClientHelloType type) */ if (ss->firstHsDone) { version = ss->clientHelloVersion; - } else { - version = ss->vrange.max; } sid = ssl3_NewSessionID(ss, PR_FALSE); @@ -5149,10 +4747,9 @@ ssl3_SendClientHello(sslSocket *ss, sslClientHelloType type) isTLS = (version > SSL_LIBRARY_VERSION_3_0); ssl_GetSpecWriteLock(ss); - cwSpec = ss->ssl3.cwSpec; - if (cwSpec->mac_def->mac == mac_null) { + if (ss->ssl3.cwSpec->macDef->mac == ssl_mac_null) { /* SSL records are not being MACed. */ - cwSpec->version = version; + ss->ssl3.cwSpec->version = version; } ssl_ReleaseSpecWriteLock(ss); @@ -5176,9 +4773,10 @@ ssl3_SendClientHello(sslSocket *ss, sslClientHelloType type) * NewSessionTicket that will cause the ticket in the sid to be replaced. * Once we've copied the session ticket into our ClientHello message, it * is OK for the ticket to change, so we just need to make sure we hold - * the lock across the calls to ssl3_CallHelloExtensionSenders. + * the lock across the calls to ssl_ConstructExtensions. */ if (sid->u.ssl3.lock) { + unlockNeeded = PR_TRUE; PR_RWLock_Rlock(sid->u.ssl3.lock); } @@ -5186,24 +4784,14 @@ ssl3_SendClientHello(sslSocket *ss, sslClientHelloType type) type == client_hello_initial) { rv = tls13_SetupClientHello(ss); if (rv != SECSuccess) { - return SECFailure; + goto loser; } } if (isTLS || (ss->firstHsDone && ss->peerRequestedProtection)) { - PRUint32 maxBytes = 65535; /* 2^16 - 1 */ - PRInt32 extLen; - - extLen = ssl3_CallHelloExtensionSenders(ss, PR_FALSE, maxBytes, NULL); - if (extLen < 0) { - if (sid->u.ssl3.lock) { - PR_RWLock_Unlock(sid->u.ssl3.lock); - } - return SECFailure; + rv = ssl_ConstructExtensions(ss, &extensionBuf, ssl_hs_client_hello); + if (rv != SECSuccess) { + goto loser; } - total_exten_len += extLen; - - if (total_exten_len > 0) - total_exten_len += 2; } if (IS_DTLS(ss)) { @@ -5213,10 +4801,7 @@ ssl3_SendClientHello(sslSocket *ss, sslClientHelloType type) /* how many suites are permitted by policy and user preference? */ num_suites = count_cipher_suites(ss, ss->ssl3.policy); if (!num_suites) { - if (sid->u.ssl3.lock) { - PR_RWLock_Unlock(sid->u.ssl3.lock); - } - return SECFailure; /* count_cipher_suites has set error code. */ + goto loser; /* count_cipher_suites has set error code. */ } fallbackSCSV = ss->opt.enableFallbackSCSV && (!requestingResume || @@ -5229,37 +4814,30 @@ ssl3_SendClientHello(sslSocket *ss, sslClientHelloType type) ++num_suites; } - /* count compression methods */ - numCompressionMethods = 0; - for (i = 0; i < ssl_compression_method_count; i++) { - if (ssl_CompressionEnabled(ss, ssl_compression_methods[i])) - numCompressionMethods++; - } - length = sizeof(SSL3ProtocolVersion) + SSL3_RANDOM_LENGTH + - 1 + (sid->version >= SSL_LIBRARY_VERSION_TLS_1_3 - ? 0 - : sid->u.ssl3.sessionIDLength) + + 1 + /* session id */ 2 + num_suites * sizeof(ssl3CipherSuite) + - 1 + numCompressionMethods + total_exten_len; + 1 + 1 /* compression methods */; + if (sid->version < SSL_LIBRARY_VERSION_TLS_1_3) { + length += sid->u.ssl3.sessionIDLength; + } else if (ss->opt.enableTls13CompatMode && !IS_DTLS(ss)) { + length += SSL3_SESSIONID_BYTES; + } if (IS_DTLS(ss)) { - length += 1 + ss->ssl3.hs.cookie.len; + length += 1 + cookieLen; } - if (total_exten_len > 0) { - ssl3_CalculatePaddingExtLen(ss, length); - if (ss->xtnData.paddingLen) { - total_exten_len += 4 + ss->xtnData.paddingLen; - length += 4 + ss->xtnData.paddingLen; + if (extensionBuf.len) { + rv = ssl_InsertPaddingExtension(ss, length, &extensionBuf); + if (rv != SECSuccess) { + goto loser; /* err set by ssl_InsertPaddingExtension */ } + length += 2 + extensionBuf.len; } - rv = ssl3_AppendHandshakeHeader(ss, client_hello, length); + rv = ssl3_AppendHandshakeHeader(ss, ssl_hs_client_hello, length); if (rv != SECSuccess) { - if (sid->u.ssl3.lock) { - PR_RWLock_Unlock(sid->u.ssl3.lock); - } - return rv; /* err set by ssl3_AppendHandshake* */ + goto loser; /* err set by ssl3_AppendHandshake* */ } if (ss->firstHsDone) { @@ -5277,60 +4855,49 @@ ssl3_SendClientHello(sslSocket *ss, sslClientHelloType type) rv = ssl3_AppendHandshakeNumber(ss, ss->clientHelloVersion, 2); } if (rv != SECSuccess) { - if (sid->u.ssl3.lock) { - PR_RWLock_Unlock(sid->u.ssl3.lock); - } - return rv; /* err set by ssl3_AppendHandshake* */ + goto loser; /* err set by ssl3_AppendHandshake* */ } /* Generate a new random if this is the first attempt. */ if (type == client_hello_initial) { - rv = ssl3_GetNewRandom(&ss->ssl3.hs.client_random); + rv = ssl3_GetNewRandom(ss->ssl3.hs.client_random); if (rv != SECSuccess) { - if (sid->u.ssl3.lock) { - PR_RWLock_Unlock(sid->u.ssl3.lock); - } - return rv; /* err set by GetNewRandom. */ + goto loser; /* err set by GetNewRandom. */ } } - rv = ssl3_AppendHandshake(ss, &ss->ssl3.hs.client_random, + rv = ssl3_AppendHandshake(ss, ss->ssl3.hs.client_random, SSL3_RANDOM_LENGTH); if (rv != SECSuccess) { - if (sid->u.ssl3.lock) { - PR_RWLock_Unlock(sid->u.ssl3.lock); - } - return rv; /* err set by ssl3_AppendHandshake* */ + goto loser; /* err set by ssl3_AppendHandshake* */ } - if (sid->version < SSL_LIBRARY_VERSION_TLS_1_3) + if (sid->version < SSL_LIBRARY_VERSION_TLS_1_3) { rv = ssl3_AppendHandshakeVariable( ss, sid->u.ssl3.sessionID, sid->u.ssl3.sessionIDLength, 1); - else + } else if (ss->opt.enableTls13CompatMode && !IS_DTLS(ss)) { + /* We're faking session resumption, so rather than create new + * randomness, just mix up the client random a little. */ + PRUint8 buf[SSL3_SESSIONID_BYTES]; + ssl_MakeFakeSid(ss, buf); + rv = ssl3_AppendHandshakeVariable(ss, buf, SSL3_SESSIONID_BYTES, 1); + } else { rv = ssl3_AppendHandshakeNumber(ss, 0, 1); + } if (rv != SECSuccess) { - if (sid->u.ssl3.lock) { - PR_RWLock_Unlock(sid->u.ssl3.lock); - } - return rv; /* err set by ssl3_AppendHandshake* */ + goto loser; /* err set by ssl3_AppendHandshake* */ } if (IS_DTLS(ss)) { rv = ssl3_AppendHandshakeVariable( - ss, ss->ssl3.hs.cookie.data, ss->ssl3.hs.cookie.len, 1); + ss, ss->ssl3.hs.cookie.data, cookieLen, 1); if (rv != SECSuccess) { - if (sid->u.ssl3.lock) { - PR_RWLock_Unlock(sid->u.ssl3.lock); - } - return rv; /* err set by ssl3_AppendHandshake* */ + goto loser; /* err set by ssl3_AppendHandshake* */ } } rv = ssl3_AppendHandshakeNumber(ss, num_suites * sizeof(ssl3CipherSuite), 2); if (rv != SECSuccess) { - if (sid->u.ssl3.lock) { - PR_RWLock_Unlock(sid->u.ssl3.lock); - } - return rv; /* err set by ssl3_AppendHandshake* */ + goto loser; /* err set by ssl3_AppendHandshake* */ } if (ss->ssl3.hs.sendingSCSV) { @@ -5338,10 +4905,7 @@ ssl3_SendClientHello(sslSocket *ss, sslClientHelloType type) rv = ssl3_AppendHandshakeNumber(ss, TLS_EMPTY_RENEGOTIATION_INFO_SCSV, sizeof(ssl3CipherSuite)); if (rv != SECSuccess) { - if (sid->u.ssl3.lock) { - PR_RWLock_Unlock(sid->u.ssl3.lock); - } - return rv; /* err set by ssl3_AppendHandshake* */ + goto loser; /* err set by ssl3_AppendHandshake* */ } actual_count++; } @@ -5349,10 +4913,7 @@ ssl3_SendClientHello(sslSocket *ss, sslClientHelloType type) rv = ssl3_AppendHandshakeNumber(ss, TLS_FALLBACK_SCSV, sizeof(ssl3CipherSuite)); if (rv != SECSuccess) { - if (sid->u.ssl3.lock) { - PR_RWLock_Unlock(sid->u.ssl3.lock); - } - return rv; /* err set by ssl3_AppendHandshake* */ + goto loser; /* err set by ssl3_AppendHandshake* */ } actual_count++; } @@ -5361,20 +4922,14 @@ ssl3_SendClientHello(sslSocket *ss, sslClientHelloType type) if (config_match(suite, ss->ssl3.policy, &ss->vrange, ss)) { actual_count++; if (actual_count > num_suites) { - if (sid->u.ssl3.lock) { - PR_RWLock_Unlock(sid->u.ssl3.lock); - } /* set error card removal/insertion error */ PORT_SetError(SSL_ERROR_TOKEN_INSERTION_REMOVAL); - return SECFailure; + goto loser; } rv = ssl3_AppendHandshakeNumber(ss, suite->cipher_suite, sizeof(ssl3CipherSuite)); if (rv != SECSuccess) { - if (sid->u.ssl3.lock) { - PR_RWLock_Unlock(sid->u.ssl3.lock); - } - return rv; /* err set by ssl3_AppendHandshake* */ + goto loser; /* err set by ssl3_AppendHandshake* */ } } } @@ -5384,57 +4939,37 @@ ssl3_SendClientHello(sslSocket *ss, sslClientHelloType type) * the server.. */ if (actual_count != num_suites) { /* Card removal/insertion error */ - if (sid->u.ssl3.lock) { - PR_RWLock_Unlock(sid->u.ssl3.lock); - } PORT_SetError(SSL_ERROR_TOKEN_INSERTION_REMOVAL); - return SECFailure; + goto loser; } - rv = ssl3_AppendHandshakeNumber(ss, numCompressionMethods, 1); + /* Compression methods: count is always 1, null compression. */ + rv = ssl3_AppendHandshakeNumber(ss, 1, 1); if (rv != SECSuccess) { - if (sid->u.ssl3.lock) { - PR_RWLock_Unlock(sid->u.ssl3.lock); - } - return rv; /* err set by ssl3_AppendHandshake* */ + goto loser; /* err set by ssl3_AppendHandshake* */ } - for (i = 0; i < ssl_compression_method_count; i++) { - if (!ssl_CompressionEnabled(ss, ssl_compression_methods[i])) - continue; - rv = ssl3_AppendHandshakeNumber(ss, ssl_compression_methods[i], 1); - if (rv != SECSuccess) { - if (sid->u.ssl3.lock) { - PR_RWLock_Unlock(sid->u.ssl3.lock); - } - return rv; /* err set by ssl3_AppendHandshake* */ - } + rv = ssl3_AppendHandshakeNumber(ss, ssl_compression_null, 1); + if (rv != SECSuccess) { + goto loser; /* err set by ssl3_AppendHandshake* */ } - if (total_exten_len) { - PRUint32 maxBytes = total_exten_len - 2; - PRInt32 extLen; - - rv = ssl3_AppendHandshakeNumber(ss, maxBytes, 2); - if (rv != SECSuccess) { - if (sid->u.ssl3.lock) { - PR_RWLock_Unlock(sid->u.ssl3.lock); - } - return rv; /* err set by AppendHandshake. */ + if (extensionBuf.len) { + /* If we are sending a PSK binder, replace the dummy value. Note that + * we only set statelessResume on the client in TLS 1.3. */ + if (ss->statelessResume && + ss->xtnData.sentSessionTicketInClientHello) { + rv = tls13_WriteExtensionsWithBinder(ss, &extensionBuf); + } else { + rv = ssl3_AppendBufferToHandshakeVariable(ss, &extensionBuf, 2); } - - extLen = ssl3_CallHelloExtensionSenders(ss, PR_TRUE, maxBytes, NULL); - if (extLen < 0) { - if (sid->u.ssl3.lock) { - PR_RWLock_Unlock(sid->u.ssl3.lock); - } - return SECFailure; + if (rv != SECSuccess) { + goto loser; /* err set by AppendHandshake. */ } - maxBytes -= extLen; - - PORT_Assert(!maxBytes); } - if (sid->u.ssl3.lock) { + sslBuffer_Clear(&extensionBuf); + if (unlockNeeded) { + /* Note: goto loser can't be used past this point. */ PR_RWLock_Unlock(sid->u.ssl3.lock); } @@ -5450,9 +4985,6 @@ ssl3_SendClientHello(sslSocket *ss, sslClientHelloType type) } flags = 0; - if (!ss->firstHsDone && !IS_DTLS(ss)) { - flags |= ssl_SEND_FLAG_CAP_RECORD_VERSION; - } rv = ssl3_FlushHandshake(ss, flags); if (rv != SECSuccess) { return rv; /* error code set by ssl3_FlushHandshake */ @@ -5467,6 +4999,13 @@ ssl3_SendClientHello(sslSocket *ss, sslClientHelloType type) ss->ssl3.hs.ws = wait_server_hello; return SECSuccess; + +loser: + if (unlockNeeded) { + PR_RWLock_Unlock(sid->u.ssl3.lock); + } + sslBuffer_Clear(&extensionBuf); + return SECFailure; } /* Called from ssl3_HandlePostHelloHandshakeMessage() when it has deciphered a @@ -5500,7 +5039,7 @@ ssl3_HandleHelloRequest(sslSocket *ss) } if (sid) { - ss->sec.uncache(sid); + ssl_UncacheSessionID(ss); ssl_FreeSID(sid); ss->sec.ci.sid = NULL; } @@ -6018,7 +5557,7 @@ ssl3_SendRSAClientKeyExchange(sslSocket *ss, SECKEYPublicKey *svrPubKey) /* Generate the pre-master secret ... */ ssl_GetSpecWriteLock(ss); - isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0); + isTLS = (PRBool)(ss->version > SSL_LIBRARY_VERSION_3_0); pms = ssl3_GenerateRSAPMS(ss, ss->ssl3.pwSpec, NULL); ssl_ReleaseSpecWriteLock(ss); @@ -6041,41 +5580,20 @@ ssl3_SendRSAClientKeyExchange(sslSocket *ss, SECKEYPublicKey *svrPubKey) goto loser; } -#ifdef NSS_ALLOW_SSLKEYLOGFILE - if (ssl_keylog_iob) { +#ifdef TRACE + if (ssl_trace >= 100) { SECStatus extractRV = PK11_ExtractKeyValue(pms); if (extractRV == SECSuccess) { SECItem *keyData = PK11_GetKeyData(pms); if (keyData && keyData->data && keyData->len) { -#ifdef TRACE - if (ssl_trace >= 100) { - ssl_PrintBuf(ss, "Pre-Master Secret", - keyData->data, keyData->len); - } -#endif - if (ssl_keylog_iob && enc_pms.len >= 8 && keyData->len == 48) { - /* https://developer.mozilla.org/en/NSS_Key_Log_Format */ - - /* There could be multiple, concurrent writers to the - * keylog, so we have to do everything in a single call to - * fwrite. */ - char buf[4 + 8 * 2 + 1 + 48 * 2 + 1]; - - strcpy(buf, "RSA "); - hexEncode(buf + 4, enc_pms.data, 8); - buf[20] = ' '; - hexEncode(buf + 21, keyData->data, 48); - buf[sizeof(buf) - 1] = '\n'; - - fwrite(buf, sizeof(buf), 1, ssl_keylog_iob); - fflush(ssl_keylog_iob); - } + ssl_PrintBuf(ss, "Pre-Master Secret", + keyData->data, keyData->len); } } } #endif - rv = ssl3_AppendHandshakeHeader(ss, client_key_exchange, + rv = ssl3_AppendHandshakeHeader(ss, ssl_hs_client_key_exchange, isTLS ? enc_pms.len + 2 : enc_pms.len); if (rv != SECSuccess) { @@ -6090,7 +5608,7 @@ ssl3_SendRSAClientKeyExchange(sslSocket *ss, SECKEYPublicKey *svrPubKey) goto loser; /* err set by ssl3_AppendHandshake* */ } - rv = ssl3_InitPendingCipherSpec(ss, pms); + rv = ssl3_InitPendingCipherSpecs(ss, pms, PR_TRUE); PK11_FreeSymKey(pms); pms = NULL; @@ -6114,27 +5632,27 @@ loser: /* DH shares need to be padded to the size of their prime. Some implementations * require this. TLS 1.3 also requires this. */ SECStatus -ssl_AppendPaddedDHKeyShare(const sslSocket *ss, const SECKEYPublicKey *pubKey, +ssl_AppendPaddedDHKeyShare(sslBuffer *buf, const SECKEYPublicKey *pubKey, PRBool appendLength) { SECStatus rv; unsigned int pad = pubKey->u.dh.prime.len - pubKey->u.dh.publicValue.len; if (appendLength) { - rv = ssl3_ExtAppendHandshakeNumber(ss, pubKey->u.dh.prime.len, 2); + rv = sslBuffer_AppendNumber(buf, pubKey->u.dh.prime.len, 2); if (rv != SECSuccess) { return rv; } } while (pad) { - rv = ssl3_ExtAppendHandshakeNumber(ss, 0, 1); + rv = sslBuffer_AppendNumber(buf, 0, 1); if (rv != SECSuccess) { return rv; } --pad; } - rv = ssl3_ExtAppendHandshake(ss, pubKey->u.dh.publicValue.data, - pubKey->u.dh.publicValue.len); + rv = sslBuffer_Append(buf, pubKey->u.dh.publicValue.data, + pubKey->u.dh.publicValue.len); if (rv != SECSuccess) { return rv; } @@ -6158,11 +5676,13 @@ ssl3_SendDHClientKeyExchange(sslSocket *ss, SECKEYPublicKey *svrPubKey) }; sslEphemeralKeyPair *keyPair = NULL; SECKEYPublicKey *pubKey; + PRUint8 dhData[1026]; /* Enough for the 8192-bit group. */ + sslBuffer dhBuf = SSL_BUFFER(dhData); PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); - isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0); + isTLS = (PRBool)(ss->version > SSL_LIBRARY_VERSION_3_0); /* Copy DH parameters from server key */ @@ -6217,22 +5737,27 @@ ssl3_SendDHClientKeyExchange(sslSocket *ss, SECKEYPublicKey *svrPubKey) } /* Note: send the DH share padded to avoid triggering bugs. */ - rv = ssl3_AppendHandshakeHeader(ss, client_key_exchange, + rv = ssl3_AppendHandshakeHeader(ss, ssl_hs_client_key_exchange, params->prime.len + 2); if (rv != SECSuccess) { goto loser; /* err set by ssl3_AppendHandshake* */ } - rv = ssl_AppendPaddedDHKeyShare(ss, pubKey, PR_TRUE); + rv = ssl_AppendPaddedDHKeyShare(&dhBuf, pubKey, PR_TRUE); if (rv != SECSuccess) { goto loser; /* err set by ssl_AppendPaddedDHKeyShare */ } + rv = ssl3_AppendBufferToHandshake(ss, &dhBuf); + if (rv != SECSuccess) { + goto loser; /* err set by ssl3_AppendBufferToHandshake */ + } - rv = ssl3_InitPendingCipherSpec(ss, pms); + rv = ssl3_InitPendingCipherSpecs(ss, pms, PR_TRUE); if (rv != SECSuccess) { ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE); goto loser; } + sslBuffer_Clear(&dhBuf); PK11_FreeSymKey(pms); ssl_FreeEphemeralKeyPair(keyPair); return SECSuccess; @@ -6242,6 +5767,7 @@ loser: PK11_FreeSymKey(pms); if (keyPair) ssl_FreeEphemeralKeyPair(keyPair); + sslBuffer_Clear(&dhBuf); return SECFailure; } @@ -6422,8 +5948,8 @@ ssl3_PickServerSignatureScheme(sslSocket *ss) /* Sets error code, if needed. */ return ssl_PickSignatureScheme(ss, keyPair->pubKey, keyPair->privKey, - ss->xtnData.clientSigSchemes, - ss->xtnData.numClientSigScheme, + ss->xtnData.sigSchemes, + ss->xtnData.numSigSchemes, PR_FALSE /* requireSha1 */); } @@ -6540,7 +6066,7 @@ ssl3_SendCertificateVerify(sslSocket *ss, SECKEYPrivateKey *privKey) len = buf.len + 2 + (isTLS12 ? 2 : 0); - rv = ssl3_AppendHandshakeHeader(ss, certificate_verify, len); + rv = ssl3_AppendHandshakeHeader(ss, ssl_hs_certificate_verify, len); if (rv != SECSuccess) { goto done; /* error code set by AppendHandshake */ } @@ -6564,11 +6090,9 @@ done: /* Once a cipher suite has been selected, make sure that the necessary secondary * information is properly set. */ SECStatus -ssl3_SetCipherSuite(sslSocket *ss, ssl3CipherSuite chosenSuite, - PRBool initHashes) +ssl3_SetupCipherSuite(sslSocket *ss, PRBool initHashes) { - ss->ssl3.hs.cipher_suite = chosenSuite; - ss->ssl3.hs.suite_def = ssl_LookupCipherSuiteDef(chosenSuite); + ss->ssl3.hs.suite_def = ssl_LookupCipherSuiteDef(ss->ssl3.hs.cipher_suite); if (!ss->ssl3.hs.suite_def) { PORT_Assert(0); PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); @@ -6581,10 +6105,95 @@ ssl3_SetCipherSuite(sslSocket *ss, ssl3CipherSuite chosenSuite, if (!initHashes) { return SECSuccess; } - /* Now we've have a cipher suite, initialize the handshake hashes. */ + /* Now we have a cipher suite, initialize the handshake hashes. */ return ssl3_InitHandshakeHashes(ss); } +SECStatus +ssl_ClientSetCipherSuite(sslSocket *ss, SSL3ProtocolVersion version, + ssl3CipherSuite suite, PRBool initHashes) +{ + unsigned int i; + if (ssl3_config_match_init(ss) == 0) { + PORT_Assert(PR_FALSE); + return SECFailure; + } + for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) { + ssl3CipherSuiteCfg *suiteCfg = &ss->cipherSuites[i]; + if (suite == suiteCfg->cipher_suite) { + SSLVersionRange vrange = { version, version }; + if (!config_match(suiteCfg, ss->ssl3.policy, &vrange, ss)) { + /* config_match already checks whether the cipher suite is + * acceptable for the version, but the check is repeated here + * in order to give a more precise error code. */ + if (!ssl3_CipherSuiteAllowedForVersionRange(suite, &vrange)) { + PORT_SetError(SSL_ERROR_CIPHER_DISALLOWED_FOR_VERSION); + } else { + PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP); + } + return SECFailure; + } + break; + } + } + if (i >= ssl_V3_SUITES_IMPLEMENTED) { + PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP); + return SECFailure; + } + + /* Don't let the server change its mind. */ + if (ss->ssl3.hs.helloRetry && suite != ss->ssl3.hs.cipher_suite) { + (void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter); + PORT_SetError(SSL_ERROR_RX_MALFORMED_SERVER_HELLO); + return SECFailure; + } + + ss->ssl3.hs.cipher_suite = (ssl3CipherSuite)suite; + return ssl3_SetupCipherSuite(ss, initHashes); +} + +/* Check that session ID we received from the server, if any, matches our + * expectations, depending on whether we're in compat mode and whether we + * negotiated TLS 1.3+ or TLS 1.2-. + */ +static PRBool +ssl_CheckServerSessionIdCorrectness(sslSocket *ss, SECItem *sidBytes) +{ + sslSessionID *sid = ss->sec.ci.sid; + PRBool sidMatch = PR_FALSE; + PRBool sentFakeSid = PR_FALSE; + PRBool sentRealSid = sid && sid->version < SSL_LIBRARY_VERSION_TLS_1_3; + + /* If attempting to resume a TLS 1.2 connection, the session ID won't be a + * fake. Check for the real value. */ + if (sentRealSid) { + sidMatch = (sidBytes->len == sid->u.ssl3.sessionIDLength) && + PORT_Memcmp(sid->u.ssl3.sessionID, sidBytes->data, sidBytes->len) == 0; + } else { + /* Otherwise, the session ID was a fake if TLS 1.3 compat mode is + * enabled. If so, check for the fake value. */ + sentFakeSid = ss->opt.enableTls13CompatMode && !IS_DTLS(ss); + if (sentFakeSid && sidBytes->len == SSL3_SESSIONID_BYTES) { + PRUint8 buf[SSL3_SESSIONID_BYTES]; + ssl_MakeFakeSid(ss, buf); + sidMatch = PORT_Memcmp(buf, sidBytes->data, sidBytes->len) == 0; + } + } + + /* TLS 1.2: Session ID shouldn't match if we sent a fake. */ + if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) { + return !sentFakeSid || !sidMatch; + } + + /* TLS 1.3: We sent a session ID. The server's should match. */ + if (sentRealSid || sentFakeSid) { + return sidMatch; + } + + /* TLS 1.3: The server shouldn't send a session ID. */ + return sidBytes->len == 0; +} + /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete * ssl3 ServerHello message. * Caller must hold Handshake and RecvBuf locks. @@ -6592,14 +6201,16 @@ ssl3_SetCipherSuite(sslSocket *ss, ssl3CipherSuite chosenSuite, static SECStatus ssl3_HandleServerHello(sslSocket *ss, PRUint8 *b, PRUint32 length) { - PRUint32 temp; - PRBool suite_found = PR_FALSE; - int i; + PRUint32 cipher; int errCode = SSL_ERROR_RX_MALFORMED_SERVER_HELLO; + PRUint32 compression; SECStatus rv; SECItem sidBytes = { siBuffer, NULL, 0 }; - PRBool isTLS = PR_FALSE; + PRBool isHelloRetry; SSL3AlertDescription desc = illegal_parameter; + TLSExtension *versionExtension; + const PRUint8 *savedMsg = b; + const PRUint32 savedLength = length; #ifndef TLS_1_3_DRAFT_VERSION SSL3ProtocolVersion downgradeCheckVersion; #endif @@ -6608,7 +6219,6 @@ ssl3_HandleServerHello(sslSocket *ss, PRUint8 *b, PRUint32 length) SSL_GETPID(), ss->fd)); PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss)); PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); - PORT_Assert(ss->ssl3.initialized); if (ss->ssl3.hs.ws != wait_server_hello) { errCode = SSL_ERROR_RX_UNEXPECTED_SERVER_HELLO; @@ -6630,11 +6240,95 @@ ssl3_HandleServerHello(sslSocket *ss, PRUint8 *b, PRUint32 length) ss->ssl3.clientPrivateKey = NULL; } + /* Note that if the server selects TLS 1.3, this will set the version to TLS + * 1.2. We will amend that once all other fields have been read. */ rv = ssl_ClientReadVersion(ss, &b, &length, &ss->version); if (rv != SECSuccess) { goto loser; /* alert has been sent */ } + rv = ssl3_ConsumeHandshake( + ss, ss->ssl3.hs.server_random, SSL3_RANDOM_LENGTH, &b, &length); + if (rv != SECSuccess) { + goto loser; /* alert has been sent */ + } + isHelloRetry = !PORT_Memcmp(ss->ssl3.hs.server_random, + ssl_hello_retry_random, SSL3_RANDOM_LENGTH); + + rv = ssl3_ConsumeHandshakeVariable(ss, &sidBytes, 1, &b, &length); + if (rv != SECSuccess) { + goto loser; /* alert has been sent */ + } + if (sidBytes.len > SSL3_SESSIONID_BYTES) { + if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_0) + desc = decode_error; + goto alert_loser; /* malformed. */ + } + + /* Read the cipher suite. */ + rv = ssl3_ConsumeHandshakeNumber(ss, &cipher, 2, &b, &length); + if (rv != SECSuccess) { + goto loser; /* alert has been sent */ + } + + /* Compression method. */ + rv = ssl3_ConsumeHandshakeNumber(ss, &compression, 1, &b, &length); + if (rv != SECSuccess) { + goto loser; /* alert has been sent */ + } + if (compression != ssl_compression_null) { + desc = illegal_parameter; + errCode = SSL_ERROR_RX_MALFORMED_SERVER_HELLO; + goto alert_loser; + } + + /* Parse extensions. */ + if (length != 0) { + PRUint32 extensionLength; + rv = ssl3_ConsumeHandshakeNumber(ss, &extensionLength, 2, &b, &length); + if (rv != SECSuccess) { + goto loser; /* alert already sent */ + } + if (extensionLength != length) { + desc = decode_error; + goto alert_loser; + } + rv = ssl3_ParseExtensions(ss, &b, &length); + if (rv != SECSuccess) { + goto alert_loser; /* malformed */ + } + } + + /* 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 */ + } + } + + PORT_Assert(!SSL_ALL_VERSIONS_DISABLED(&ss->vrange)); + /* Check that the version is within the configured range. */ + if (ss->vrange.min > ss->version || ss->vrange.max < ss->version) { + desc = (ss->version > SSL_LIBRARY_VERSION_3_0) + ? protocol_version + : handshake_failure; + errCode = SSL_ERROR_UNSUPPORTED_VERSION; + goto alert_loser; + } + + if (isHelloRetry && ss->ssl3.hs.helloRetry) { + SSL_TRC(3, ("%d: SSL3[%d]: received a second hello_retry_request", + SSL_GETPID(), ss->fd)); + desc = unexpected_message; + errCode = SSL_ERROR_RX_UNEXPECTED_HELLO_RETRY_REQUEST; + goto alert_loser; + } + /* 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) { @@ -6657,18 +6351,10 @@ ssl3_HandleServerHello(sslSocket *ss, PRUint8 *b, PRUint32 length) * us to be getting this version number, but it's what we have. * (1294697). */ if (ss->firstHsDone && (ss->version != ss->ssl3.crSpec->version)) { - desc = illegal_parameter; + desc = protocol_version; errCode = SSL_ERROR_UNSUPPORTED_VERSION; goto alert_loser; } - ss->ssl3.hs.preliminaryInfo |= ssl_preinfo_version; - isTLS = (ss->version > SSL_LIBRARY_VERSION_3_0); - - rv = ssl3_ConsumeHandshake( - ss, &ss->ssl3.hs.server_random, SSL3_RANDOM_LENGTH, &b, &length); - if (rv != SECSuccess) { - goto loser; /* alert has been sent */ - } #ifndef TLS_1_3_DRAFT_VERSION /* Check the ServerHello.random per @@ -6688,8 +6374,8 @@ ssl3_HandleServerHello(sslSocket *ss, PRUint8 *b, PRUint32 length) if (downgradeCheckVersion >= SSL_LIBRARY_VERSION_TLS_1_2 && downgradeCheckVersion > ss->version) { /* Both sections use the same sentinel region. */ - unsigned char *downgrade_sentinel = - ss->ssl3.hs.server_random.rand + + PRUint8 *downgrade_sentinel = + ss->ssl3.hs.server_random + SSL3_RANDOM_LENGTH - sizeof(tls13_downgrade_random); if (!PORT_Memcmp(downgrade_sentinel, tls13_downgrade_random, @@ -6704,110 +6390,52 @@ ssl3_HandleServerHello(sslSocket *ss, PRUint8 *b, PRUint32 length) } #endif - if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) { - rv = ssl3_ConsumeHandshakeVariable(ss, &sidBytes, 1, &b, &length); - if (rv != SECSuccess) { - goto loser; /* alert has been sent */ - } - if (sidBytes.len > SSL3_SESSIONID_BYTES) { - if (isTLS) - desc = decode_error; - goto alert_loser; /* malformed. */ - } + /* 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) { + ssl_GetSpecWriteLock(ss); + ssl_SetSpecVersions(ss, ss->ssl3.cwSpec); + ssl_ReleaseSpecWriteLock(ss); } - /* find selected cipher suite in our list. */ - rv = ssl3_ConsumeHandshakeNumber(ss, &temp, 2, &b, &length); - if (rv != SECSuccess) { - goto loser; /* alert has been sent */ - } - i = ssl3_config_match_init(ss); - PORT_Assert(i > 0); - if (i <= 0) { - errCode = PORT_GetError(); - goto loser; - } - for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) { - ssl3CipherSuiteCfg *suite = &ss->cipherSuites[i]; - if (temp == suite->cipher_suite) { - SSLVersionRange vrange = { ss->version, ss->version }; - if (!config_match(suite, ss->ssl3.policy, &vrange, ss)) { - /* config_match already checks whether the cipher suite is - * acceptable for the version, but the check is repeated here - * in order to give a more precise error code. */ - if (!ssl3_CipherSuiteAllowedForVersionRange(temp, &vrange)) { - desc = handshake_failure; - errCode = SSL_ERROR_CIPHER_DISALLOWED_FOR_VERSION; - goto alert_loser; - } - - break; /* failure */ - } - - suite_found = PR_TRUE; - break; /* success */ - } - } - if (!suite_found) { - desc = handshake_failure; - errCode = SSL_ERROR_NO_CYPHER_OVERLAP; + /* Check that the session ID is as expected. */ + if (!ssl_CheckServerSessionIdCorrectness(ss, &sidBytes)) { + desc = illegal_parameter; + errCode = SSL_ERROR_RX_MALFORMED_SERVER_HELLO; goto alert_loser; } - rv = ssl3_SetCipherSuite(ss, (ssl3CipherSuite)temp, PR_TRUE); + /* Only initialize hashes if this isn't a Hello Retry. */ + rv = ssl_ClientSetCipherSuite(ss, ss->version, cipher, + !isHelloRetry); if (rv != SECSuccess) { - desc = internal_error; + desc = illegal_parameter; errCode = PORT_GetError(); goto alert_loser; } - if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) { - /* find selected compression method in our list. */ - rv = ssl3_ConsumeHandshakeNumber(ss, &temp, 1, &b, &length); + dtls_ReceivedFirstMessageInFlight(ss); + + if (isHelloRetry) { + rv = tls13_HandleHelloRetryRequest(ss, savedMsg, savedLength); if (rv != SECSuccess) { - goto loser; /* alert has been sent */ - } - suite_found = PR_FALSE; - for (i = 0; i < ssl_compression_method_count; i++) { - if (temp == ssl_compression_methods[i]) { - if (!ssl_CompressionEnabled(ss, ssl_compression_methods[i])) { - break; /* failure */ - } - suite_found = PR_TRUE; - break; /* success */ - } - } - if (!suite_found) { - desc = handshake_failure; - errCode = SSL_ERROR_NO_COMPRESSION_OVERLAP; - goto alert_loser; + goto loser; } - ss->ssl3.hs.compression = (SSLCompressionMethod)temp; - } else { - ss->ssl3.hs.compression = ssl_compression_null; + return SECSuccess; } - /* Note that if !isTLS and the extra stuff is not extensions, we - * do NOT goto alert_loser. - * There are some old SSL 3.0 implementations that do send stuff - * after the end of the server hello, and we deliberately ignore - * such stuff in the interest of maximal interoperability (being - * "generous in what you accept"). - * Update: Starting in NSS 3.12.6, we handle the renegotiation_info - * extension in SSL 3.0. - */ - if (length != 0) { - SECItem extensions; - rv = ssl3_ConsumeHandshakeVariable(ss, &extensions, 2, &b, &length); - if (rv != SECSuccess || length != 0) { - if (isTLS) - goto alert_loser; - } else { - rv = ssl3_HandleExtensions(ss, &extensions.data, - &extensions.len, server_hello); - if (rv != SECSuccess) - goto alert_loser; - } + rv = ssl3_HandleParsedExtensions(ss, ssl_hs_server_hello); + ssl3_DestroyRemoteExtensions(&ss->ssl3.hs.remoteExtensions); + if (rv != SECSuccess) { + goto alert_loser; + } + + rv = ssl_HashHandshakeMessage(ss, ssl_hs_server_hello, + savedMsg, savedLength); + if (rv != SECSuccess) { + goto loser; } if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) { @@ -6835,6 +6463,51 @@ loser: } static SECStatus +ssl3_UnwrapMasterSecretClient(sslSocket *ss, sslSessionID *sid, PK11SymKey **ms) +{ + PK11SlotInfo *slot; + PK11SymKey *wrapKey; + CK_FLAGS keyFlags = 0; + SECItem wrappedMS = { + siBuffer, + sid->u.ssl3.keys.wrapped_master_secret, + sid->u.ssl3.keys.wrapped_master_secret_len + }; + + /* unwrap master secret */ + slot = SECMOD_LookupSlot(sid->u.ssl3.masterModuleID, + sid->u.ssl3.masterSlotID); + if (slot == NULL) { + return SECFailure; + } + if (!PK11_IsPresent(slot)) { + PK11_FreeSlot(slot); + return SECFailure; + } + wrapKey = PK11_GetWrapKey(slot, sid->u.ssl3.masterWrapIndex, + sid->u.ssl3.masterWrapMech, + sid->u.ssl3.masterWrapSeries, + ss->pkcs11PinArg); + PK11_FreeSlot(slot); + if (wrapKey == NULL) { + return SECFailure; + } + + if (ss->version > SSL_LIBRARY_VERSION_3_0) { /* isTLS */ + keyFlags = CKF_SIGN | CKF_VERIFY; + } + + *ms = PK11_UnwrapSymKeyWithFlags(wrapKey, sid->u.ssl3.masterWrapMech, + NULL, &wrappedMS, CKM_SSL3_MASTER_KEY_DERIVE, + CKA_DERIVE, SSL3_MASTER_SECRET_LENGTH, keyFlags); + PK11_FreeSymKey(wrapKey); + if (!*ms) { + return SECFailure; + } + return SECSuccess; +} + +static SECStatus ssl3_HandleServerHelloPart2(sslSocket *ss, const SECItem *sidBytes, int *retErrCode) { @@ -6860,7 +6533,7 @@ ssl3_HandleServerHelloPart2(sslSocket *ss, const SECItem *sidBytes, /* we need to call ssl3_SetupPendingCipherSpec here so we can check the * key exchange algorithm. */ - rv = ssl3_SetupPendingCipherSpec(ss); + rv = ssl3_SetupBothPendingCipherSpecs(ss); if (rv != SECSuccess) { goto alert_loser; /* error code is set. */ } @@ -6883,9 +6556,7 @@ ssl3_HandleServerHelloPart2(sslSocket *ss, const SECItem *sidBytes, goto alert_loser; } do { - ssl3CipherSpec *pwSpec = ss->ssl3.pwSpec; - - SECItem wrappedMS; /* wrapped master secret. */ + PK11SymKey *masterSecret; /* [draft-ietf-tls-session-hash-06; Section 5.3] * @@ -6917,60 +6588,12 @@ ssl3_HandleServerHelloPart2(sslSocket *ss, const SECItem *sidBytes, ss->sec.authKeyBits = sid->authKeyBits; ss->sec.keaType = sid->keaType; ss->sec.keaKeyBits = sid->keaKeyBits; + ss->sec.originalKeaGroup = ssl_LookupNamedGroup(sid->keaGroup); + ss->sec.signatureScheme = sid->sigScheme; - if (sid->u.ssl3.keys.msIsWrapped) { - PK11SlotInfo *slot; - PK11SymKey *wrapKey; /* wrapping key */ - CK_FLAGS keyFlags = 0; - - /* unwrap master secret */ - slot = SECMOD_LookupSlot(sid->u.ssl3.masterModuleID, - sid->u.ssl3.masterSlotID); - if (slot == NULL) { - break; /* not considered an error. */ - } - if (!PK11_IsPresent(slot)) { - PK11_FreeSlot(slot); - break; /* not considered an error. */ - } - wrapKey = PK11_GetWrapKey(slot, sid->u.ssl3.masterWrapIndex, - sid->u.ssl3.masterWrapMech, - sid->u.ssl3.masterWrapSeries, - ss->pkcs11PinArg); - PK11_FreeSlot(slot); - if (wrapKey == NULL) { - break; /* not considered an error. */ - } - - if (ss->version > SSL_LIBRARY_VERSION_3_0) { /* isTLS */ - keyFlags = - CKF_SIGN | CKF_VERIFY; - } - - wrappedMS.data = sid->u.ssl3.keys.wrapped_master_secret; - wrappedMS.len = sid->u.ssl3.keys.wrapped_master_secret_len; - pwSpec->master_secret = - PK11_UnwrapSymKeyWithFlags(wrapKey, sid->u.ssl3.masterWrapMech, - NULL, &wrappedMS, CKM_SSL3_MASTER_KEY_DERIVE, - CKA_DERIVE, sizeof(SSL3MasterSecret), keyFlags); - errCode = PORT_GetError(); - PK11_FreeSymKey(wrapKey); - if (pwSpec->master_secret == NULL) { - break; /* errorCode set just after call to UnwrapSymKey. */ - } - } else { - /* need to import the raw master secret to session object */ - PK11SlotInfo *slot = PK11_GetInternalSlot(); - wrappedMS.data = sid->u.ssl3.keys.wrapped_master_secret; - wrappedMS.len = sid->u.ssl3.keys.wrapped_master_secret_len; - pwSpec->master_secret = - PK11_ImportSymKey(slot, CKM_SSL3_MASTER_KEY_DERIVE, - PK11_OriginUnwrap, CKA_ENCRYPT, - &wrappedMS, NULL); - PK11_FreeSlot(slot); - if (pwSpec->master_secret == NULL) { - break; - } + rv = ssl3_UnwrapMasterSecretClient(ss, sid, &masterSecret); + if (rv != SECSuccess) { + break; /* not considered an error */ } /* Got a Match */ @@ -6992,8 +6615,8 @@ ssl3_HandleServerHelloPart2(sslSocket *ss, const SECItem *sidBytes, ss->sec.peerCert = CERT_DupCertificate(sid->peerCert); } - /* NULL value for PMS because we are reusing the old MS */ - rv = ssl3_InitPendingCipherSpec(ss, NULL); + /* We are re-using the old MS, so no need to derive again. */ + rv = ssl3_InitPendingCipherSpecs(ss, masterSecret, PR_FALSE); if (rv != SECSuccess) { goto alert_loser; /* err code was set */ } @@ -7021,7 +6644,7 @@ ssl3_HandleServerHelloPart2(sslSocket *ss, const SECItem *sidBytes, /* throw the old one away */ sid->u.ssl3.keys.resumable = PR_FALSE; - ss->sec.uncache(sid); + ssl_UncacheSessionID(ss); ssl_FreeSID(sid); /* get a new sid */ @@ -7098,11 +6721,11 @@ ssl_HandleDHServerKeyExchange(sslSocket *ss, PRUint8 *b, PRUint32 length) } rv = NSS_OptionGet(NSS_DH_MIN_KEY_SIZE, &minDH); - if (rv != SECSuccess) { + if (rv != SECSuccess || minDH <= 0) { minDH = SSL_DH_MIN_P_BITS; } dh_p_bits = SECKEY_BigIntegerBitLength(&dh_p); - if (dh_p_bits < minDH) { + if (dh_p_bits < (unsigned)minDH) { errCode = SSL_ERROR_WEAK_SERVER_EPHEMERAL_DH_KEY; goto alert_loser; } @@ -7283,7 +6906,7 @@ typedef struct dnameNode { */ SECStatus ssl3_ParseCertificateRequestCAs(sslSocket *ss, PRUint8 **b, PRUint32 *length, - PLArenaPool *arena, CERTDistNames *ca_list) + CERTDistNames *ca_list) { PRUint32 remaining; int nnames = 0; @@ -7298,7 +6921,7 @@ ssl3_ParseCertificateRequestCAs(sslSocket *ss, PRUint8 **b, PRUint32 *length, if (remaining > *length) goto alert_loser; - ca_list->head = node = PORT_ArenaZNew(arena, dnameNode); + ca_list->head = node = PORT_ArenaZNew(ca_list->arena, dnameNode); if (node == NULL) goto no_mem; @@ -7324,14 +6947,14 @@ ssl3_ParseCertificateRequestCAs(sslSocket *ss, PRUint8 **b, PRUint32 *length, if (remaining <= 0) break; /* success */ - node->next = PORT_ArenaZNew(arena, dnameNode); + node->next = PORT_ArenaZNew(ca_list->arena, dnameNode); node = node->next; if (node == NULL) goto no_mem; } ca_list->nnames = nnames; - ca_list->names = PORT_ArenaNewArray(arena, SECItem, nnames); + ca_list->names = PORT_ArenaNewArray(ca_list->arena, SECItem, nnames); if (nnames > 0 && ca_list->names == NULL) goto no_mem; @@ -7475,7 +7098,7 @@ ssl3_HandleCertificateRequest(sslSocket *ss, PRUint8 *b, PRUint32 length) } } - rv = ssl3_ParseCertificateRequestCAs(ss, &b, &length, arena, &ca_list); + rv = ssl3_ParseCertificateRequestCAs(ss, &b, &length, &ca_list); if (rv != SECSuccess) goto done; /* alert sent in ssl3_ParseCertificateRequestCAs */ @@ -7575,7 +7198,7 @@ ssl3_CompleteHandleCertificateRequest(sslSocket *ss, case SECFailure: default: send_no_certificate: - if (ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0) { + if (ss->version > SSL_LIBRARY_VERSION_3_0) { ss->ssl3.sendEmptyCert = PR_TRUE; } else { (void)SSL3_SendAlert(ss, alert_warning, no_certificate); @@ -7606,7 +7229,7 @@ ssl3_CheckFalseStart(sslSocket *ss) * sufficiently strong that the attack can gain no advantage. * Therefore we always require an 80-bit cipher. */ ssl_GetSpecReadLock(ss); - maybeFalseStart = ss->ssl3.cwSpec->cipher_def->secret_key_size >= 10; + maybeFalseStart = ss->ssl3.cwSpec->cipherDef->secret_key_size >= 10; ssl_ReleaseSpecReadLock(ss); if (!maybeFalseStart) { @@ -7858,7 +7481,7 @@ ssl3_SendHelloRequest(sslSocket *ss) PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); - rv = ssl3_AppendHandshakeHeader(ss, hello_request, 0); + rv = ssl3_AppendHandshakeHeader(ss, ssl_hs_hello_request, 0); if (rv != SECSuccess) { return rv; /* err set by AppendHandshake */ } @@ -7927,11 +7550,10 @@ ssl3_NewSessionID(sslSocket *ss, PRBool is_server) sid->references = 1; sid->cached = never_cached; sid->version = ss->version; + sid->sigScheme = ssl_sig_none; sid->u.ssl3.keys.resumable = PR_TRUE; sid->u.ssl3.policy = SSL_ALLOWED; - sid->u.ssl3.clientWriteKey = NULL; - sid->u.ssl3.serverWriteKey = NULL; sid->u.ssl3.keys.extendedMasterSecretUsed = PR_FALSE; if (is_server) { @@ -8037,8 +7659,8 @@ SECStatus ssl3_NegotiateCipherSuite(sslSocket *ss, const SECItem *suites, PRBool initHashes) { - int j; - int i; + unsigned int j; + unsigned int i; for (j = 0; j < ssl_V3_SUITES_IMPLEMENTED; j++) { ssl3CipherSuiteCfg *suite = &ss->cipherSuites[j]; @@ -8049,7 +7671,8 @@ ssl3_NegotiateCipherSuite(sslSocket *ss, const SECItem *suites, for (i = 0; i + 1 < suites->len; i += 2) { PRUint16 suite_i = (suites->data[i] << 8) | suites->data[i + 1]; if (suite_i == suite->cipher_suite) { - return ssl3_SetCipherSuite(ss, suite_i, initHashes); + ss->ssl3.hs.cipher_suite = suite_i; + return ssl3_SetupCipherSuite(ss, initHashes); } } } @@ -8148,7 +7771,6 @@ ssl3_ServerCallSNICallback(sslSocket *ss) * and save the name. */ SECStatus rv; SECItem *name = &ss->xtnData.sniNameArr[ret]; - int configedCiphers; SECItem *pwsName; /* get rid of the old name and save the newly picked. */ @@ -8177,8 +7799,7 @@ ssl3_ServerCallSNICallback(sslSocket *ss) ret = SSL_SNI_SEND_ALERT; break; } - configedCiphers = ssl3_config_match_init(ss); - if (configedCiphers <= 0) { + if (ssl3_config_match_init(ss) == 0) { /* no ciphers are working/supported */ errCode = PORT_GetError(); desc = handshake_failure; @@ -8189,7 +7810,7 @@ ssl3_ServerCallSNICallback(sslSocket *ss) * the name from the offered list and reconfigured the socket. */ ssl3_RegisterExtensionSender(ss, &ss->xtnData, ssl_server_name_xtn, - ssl3_SendServerNameXtn); + ssl_SendEmptyExtension); } else { /* Callback returned index outside of the boundary. */ PORT_Assert((unsigned int)ret < ss->xtnData.sniNameArrSize); @@ -8288,13 +7909,14 @@ ssl3_HandleClientHello(sslSocket *ss, PRUint8 *b, PRUint32 length) SECItem suites = { siBuffer, NULL, 0 }; SECItem comps = { siBuffer, NULL, 0 }; PRBool isTLS13; + const PRUint8 *savedMsg = b; + const PRUint32 savedLen = length; SSL_TRC(3, ("%d: SSL3[%d]: handle client_hello handshake", SSL_GETPID(), ss->fd)); PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss)); PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); - PORT_Assert(ss->ssl3.initialized); ss->ssl3.hs.preliminaryInfo = 0; if (!ss->sec.isServer || @@ -8319,6 +7941,9 @@ ssl3_HandleClientHello(sslSocket *ss, PRUint8 *b, PRUint32 length) } } + /* We should always be in a fresh state. */ + SSL_ASSERT_HASHES_EMPTY(ss); + /* Get peer name of client */ rv = ssl_GetPeerInfo(ss); if (rv != SECSuccess) { @@ -8328,7 +7953,7 @@ ssl3_HandleClientHello(sslSocket *ss, PRUint8 *b, PRUint32 length) /* We might be starting session renegotiation in which case we should * clear previous state. */ - ssl3_ResetExtensionData(&ss->xtnData); + ssl3_ResetExtensionData(&ss->xtnData, ss); ss->statelessResume = PR_FALSE; if (IS_DTLS(ss)) { @@ -8349,7 +7974,7 @@ ssl3_HandleClientHello(sslSocket *ss, PRUint8 *b, PRUint32 length) /* Grab the client random data. */ rv = ssl3_ConsumeHandshake( - ss, &ss->ssl3.hs.client_random, SSL3_RANDOM_LENGTH, &b, &length); + ss, ss->ssl3.hs.client_random, SSL3_RANDOM_LENGTH, &b, &length); if (rv != SECSuccess) { goto loser; /* malformed */ } @@ -8366,6 +7991,9 @@ ssl3_HandleClientHello(sslSocket *ss, PRUint8 *b, PRUint32 length) if (rv != SECSuccess) { goto loser; /* malformed */ } + if (cookieBytes.len != 0) { + goto loser; /* We never send cookies in DTLS 1.2. */ + } } /* Grab the list of cipher suites. */ @@ -8389,14 +8017,15 @@ ssl3_HandleClientHello(sslSocket *ss, PRUint8 *b, PRUint32 length) if (length) { /* Get length of hello extensions */ - PRUint32 extension_length; - rv = ssl3_ConsumeHandshakeNumber(ss, &extension_length, 2, &b, &length); + PRUint32 extensionLength; + rv = ssl3_ConsumeHandshakeNumber(ss, &extensionLength, 2, &b, &length); if (rv != SECSuccess) { goto loser; /* alert already sent */ } - if (extension_length != length) { - ssl3_DecodeError(ss); /* send alert */ - goto loser; + if (extensionLength != length) { + errCode = SSL_ERROR_RX_MALFORMED_CLIENT_HELLO; + desc = decode_error; + goto alert_loser; } rv = ssl3_ParseExtensions(ss, &b, &length); @@ -8427,17 +8056,35 @@ ssl3_HandleClientHello(sslSocket *ss, PRUint8 *b, PRUint32 length) goto alert_loser; } } + + if (ss->firstHsDone && ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) { + desc = unexpected_message; + errCode = SSL_ERROR_RENEGOTIATION_NOT_ALLOWED; + goto alert_loser; + } + isTLS13 = ss->version >= SSL_LIBRARY_VERSION_TLS_1_3; ss->ssl3.hs.preliminaryInfo |= ssl_preinfo_version; + /* Update the write spec to match the selected version. */ + if (!ss->firstHsDone) { + ssl_GetSpecWriteLock(ss); + ssl_SetSpecVersions(ss, ss->ssl3.cwSpec); + ssl_ReleaseSpecWriteLock(ss); + } - /* You can't resume TLS 1.3 like this. */ - if (isTLS13 && sidBytes.len) { - goto alert_loser; + if (isTLS13 && sidBytes.len > 0 && !IS_DTLS(ss)) { + SECITEM_FreeItem(&ss->ssl3.hs.fakeSid, PR_FALSE); + rv = SECITEM_CopyItem(NULL, &ss->ssl3.hs.fakeSid, &sidBytes); + if (rv != SECSuccess) { + desc = internal_error; + errCode = PORT_GetError(); + goto alert_loser; + } } /* Generate the Server Random now so it is available * when we process the ClientKeyShare in TLS 1.3 */ - rv = ssl3_GetNewRandom(&ss->ssl3.hs.server_random); + rv = ssl3_GetNewRandom(ss->ssl3.hs.server_random); if (rv != SECSuccess) { errCode = SSL_ERROR_GENERATE_RANDOM_FAILURE; goto loser; @@ -8463,8 +8110,8 @@ ssl3_HandleClientHello(sslSocket *ss, PRUint8 *b, PRUint32 length) * we ship the final version of TLS 1.3. Bug 1306672. */ if (ss->vrange.max > ss->version) { - unsigned char *downgrade_sentinel = - ss->ssl3.hs.server_random.rand + + PRUint8 *downgrade_sentinel = + ss->ssl3.hs.server_random + SSL3_RANDOM_LENGTH - sizeof(tls13_downgrade_random); switch (ss->vrange.max) { @@ -8485,9 +8132,29 @@ ssl3_HandleClientHello(sslSocket *ss, PRUint8 *b, PRUint32 length) } #endif + /* If there is a cookie, then this is a second ClientHello (TLS 1.3). */ + if (ssl3_FindExtension(ss, ssl_tls13_cookie_xtn)) { + ss->ssl3.hs.helloRetry = PR_TRUE; + } + + if (ss->ssl3.hs.receivedCcs) { + /* This is only valid if we sent HelloRetryRequest, so we should have + * negotiated TLS 1.3 and there should be a cookie extension. */ + if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3 || + !ss->ssl3.hs.helloRetry) { + desc = unexpected_message; + errCode = SSL_ERROR_RX_UNEXPECTED_CHANGE_CIPHER; + goto alert_loser; + } + } + /* Now parse the rest of the extensions. */ - rv = ssl3_HandleParsedExtensions(ss, client_hello); + rv = ssl3_HandleParsedExtensions(ss, ssl_hs_client_hello); + ssl3_DestroyRemoteExtensions(&ss->ssl3.hs.remoteExtensions); if (rv != SECSuccess) { + if (PORT_GetError() == SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM) { + errCode = SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM; + } goto loser; /* malformed */ } @@ -8509,6 +8176,12 @@ ssl3_HandleClientHello(sslSocket *ss, PRUint8 *b, PRUint32 length) if (comps.len != 1 || comps.data[0] != ssl_compression_null) { goto alert_loser; } + } else { + /* Other versions need to include null somewhere. */ + if (comps.len < 1 || + !memchr(comps.data, ssl_compression_null, comps.len)) { + goto alert_loser; + } } if (!ssl3_ExtensionNegotiated(ss, ssl_renegotiation_info_xtn)) { @@ -8521,34 +8194,30 @@ ssl3_HandleClientHello(sslSocket *ss, PRUint8 *b, PRUint32 length) if (suite_i == TLS_EMPTY_RENEGOTIATION_INFO_SCSV) { PRUint8 *b2 = (PRUint8 *)emptyRIext; PRUint32 L2 = sizeof emptyRIext; - (void)ssl3_HandleExtensions(ss, &b2, &L2, client_hello); + (void)ssl3_HandleExtensions(ss, &b2, &L2, ssl_hs_client_hello); break; } } } - /* This is a second check for TLS 1.3 and re-handshake to stop us - * from re-handshake up to TLS 1.3, so it happens after version - * negotiation. */ - if (ss->firstHsDone && ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) { - desc = unexpected_message; - errCode = SSL_ERROR_RENEGOTIATION_NOT_ALLOWED; - goto alert_loser; - } - if (ss->firstHsDone && - (ss->opt.enableRenegotiation == SSL_RENEGOTIATE_REQUIRES_XTN || - ss->opt.enableRenegotiation == SSL_RENEGOTIATE_TRANSITIONAL) && - !ssl3_ExtensionNegotiated(ss, ssl_renegotiation_info_xtn)) { - desc = no_renegotiation; - level = alert_warning; - errCode = SSL_ERROR_RENEGOTIATION_NOT_ALLOWED; - goto alert_loser; - } - if ((ss->opt.requireSafeNegotiation || - (ss->firstHsDone && ss->peerRequestedProtection)) && - !ssl3_ExtensionNegotiated(ss, ssl_renegotiation_info_xtn)) { - desc = handshake_failure; - errCode = SSL_ERROR_UNSAFE_NEGOTIATION; - goto alert_loser; + + /* The check for renegotiation in TLS 1.3 is earlier. */ + if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) { + if (ss->firstHsDone && + (ss->opt.enableRenegotiation == SSL_RENEGOTIATE_REQUIRES_XTN || + ss->opt.enableRenegotiation == SSL_RENEGOTIATE_TRANSITIONAL) && + !ssl3_ExtensionNegotiated(ss, ssl_renegotiation_info_xtn)) { + desc = no_renegotiation; + level = alert_warning; + errCode = SSL_ERROR_RENEGOTIATION_NOT_ALLOWED; + goto alert_loser; + } + if ((ss->opt.requireSafeNegotiation || + (ss->firstHsDone && ss->peerRequestedProtection)) && + !ssl3_ExtensionNegotiated(ss, ssl_renegotiation_info_xtn)) { + desc = handshake_failure; + errCode = SSL_ERROR_UNSAFE_NEGOTIATION; + goto alert_loser; + } } /* We do stateful resumes only if we are in TLS < 1.3 and @@ -8613,7 +8282,7 @@ ssl3_HandleClientHello(sslSocket *ss, PRUint8 *b, PRUint32 length) !ss->firstHsDone))) { SSL_AtomicIncrementLong(&ssl3stats.hch_sid_cache_not_ok); - ss->sec.uncache(sid); + ssl_UncacheSessionID(ss); ssl_FreeSID(sid); sid = NULL; } @@ -8621,21 +8290,14 @@ ssl3_HandleClientHello(sslSocket *ss, PRUint8 *b, PRUint32 length) if (IS_DTLS(ss)) { ssl3_DisableNonDTLSSuites(ss); + dtls_ReceivedFirstMessageInFlight(ss); } -#ifdef PARANOID - /* Look for a matching cipher suite. */ - j = ssl3_config_match_init(ss); - if (j <= 0) { /* no ciphers are working/supported by PK11 */ - errCode = PORT_GetError(); /* error code is already set. */ - goto alert_loser; - } -#endif - if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) { - rv = tls13_HandleClientHelloPart2(ss, &suites, sid); + rv = tls13_HandleClientHelloPart2(ss, &suites, sid, savedMsg, savedLen); } else { - rv = ssl3_HandleClientHelloPart2(ss, &suites, &comps, sid); + rv = ssl3_HandleClientHelloPart2(ss, &suites, sid, + savedMsg, savedLen); } if (rv != SECSuccess) { errCode = PORT_GetError(); @@ -8652,22 +8314,60 @@ loser: } static SECStatus +ssl3_UnwrapMasterSecretServer(sslSocket *ss, sslSessionID *sid, PK11SymKey **ms) +{ + PK11SymKey *wrapKey; + CK_FLAGS keyFlags = 0; + SECItem wrappedMS = { + siBuffer, + sid->u.ssl3.keys.wrapped_master_secret, + sid->u.ssl3.keys.wrapped_master_secret_len + }; + + wrapKey = ssl3_GetWrappingKey(ss, NULL, sid->u.ssl3.masterWrapMech, + ss->pkcs11PinArg); + if (!wrapKey) { + return SECFailure; + } + + if (ss->version > SSL_LIBRARY_VERSION_3_0) { /* isTLS */ + keyFlags = CKF_SIGN | CKF_VERIFY; + } + + /* unwrap the master secret. */ + *ms = PK11_UnwrapSymKeyWithFlags(wrapKey, sid->u.ssl3.masterWrapMech, + NULL, &wrappedMS, CKM_SSL3_MASTER_KEY_DERIVE, + CKA_DERIVE, SSL3_MASTER_SECRET_LENGTH, keyFlags); + PK11_FreeSymKey(wrapKey); + if (!*ms) { + return SECFailure; + } + return SECSuccess; +} + +static SECStatus ssl3_HandleClientHelloPart2(sslSocket *ss, SECItem *suites, - SECItem *comps, - sslSessionID *sid) + sslSessionID *sid, + const PRUint8 *msg, + unsigned int len) { - PRBool haveSpecWriteLock = PR_FALSE; PRBool haveXmitBufLock = PR_FALSE; int errCode = SSL_ERROR_RX_MALFORMED_CLIENT_HELLO; SSL3AlertDescription desc = illegal_parameter; SECStatus rv; unsigned int i; - int j; + unsigned int j; + + rv = ssl_HashHandshakeMessage(ss, ssl_hs_client_hello, msg, len); + if (rv != SECSuccess) { + errCode = SEC_ERROR_LIBRARY_FAILURE; + desc = internal_error; + goto alert_loser; + } - /* If we already have a session for this client, be sure to pick the - ** same cipher suite and compression method we picked before. - ** This is not a loop, despite appearances. + /* If we already have a session for this client, be sure to pick the same + ** cipher suite we picked before. This is not a loop, despite appearances. */ if (sid) do { @@ -8676,18 +8376,6 @@ ssl3_HandleClientHelloPart2(sslSocket *ss, SSLVersionRange vrange = { ss->version, ss->version }; #endif - /* Check that the cached compression method is still enabled. */ - if (!ssl_CompressionEnabled(ss, sid->u.ssl3.compression)) - break; - - /* Check that the cached compression method is in the client's list */ - for (i = 0; i < comps->len; i++) { - if (comps->data[i] == sid->u.ssl3.compression) - break; - } - if (i == comps->len) - break; - suite = ss->cipherSuites; /* Find the entry for the cipher suite used in the cached session. */ for (j = ssl_V3_SUITES_IMPLEMENTED; j > 0; --j, ++suite) { @@ -8695,7 +8383,7 @@ ssl3_HandleClientHelloPart2(sslSocket *ss, break; } PORT_Assert(j > 0); - if (j <= 0) + if (j == 0) break; #ifdef PARANOID /* Double check that the cached cipher suite is still enabled, @@ -8714,17 +8402,15 @@ ssl3_HandleClientHelloPart2(sslSocket *ss, for (i = 0; i + 1 < suites->len; i += 2) { PRUint16 suite_i = (suites->data[i] << 8) | suites->data[i + 1]; if (suite_i == suite->cipher_suite) { - rv = ssl3_SetCipherSuite(ss, suite_i, PR_TRUE); + ss->ssl3.hs.cipher_suite = suite_i; + rv = ssl3_SetupCipherSuite(ss, PR_TRUE); if (rv != SECSuccess) { desc = internal_error; errCode = PORT_GetError(); goto alert_loser; } - /* Use the cached compression method. */ - ss->ssl3.hs.compression = - sid->u.ssl3.compression; - goto compression_found; + goto cipher_found; } } } while (0); @@ -8732,8 +8418,7 @@ ssl3_HandleClientHelloPart2(sslSocket *ss, #ifndef PARANOID /* Look for a matching cipher suite. */ - j = ssl3_config_match_init(ss); - if (j <= 0) { /* no ciphers are working/supported by PK11 */ + if (ssl3_config_match_init(ss) == 0) { desc = internal_error; errCode = PORT_GetError(); /* error code is already set. */ goto alert_loser; @@ -8747,25 +8432,8 @@ ssl3_HandleClientHelloPart2(sslSocket *ss, goto alert_loser; } - /* Select a compression algorithm. */ - for (i = 0; i < comps->len; i++) { - SSLCompressionMethod method = (SSLCompressionMethod)comps->data[i]; - if (!ssl_CompressionEnabled(ss, method)) - continue; - for (j = 0; j < ssl_compression_method_count; j++) { - if (method == ssl_compression_methods[j]) { - ss->ssl3.hs.compression = ssl_compression_methods[j]; - goto compression_found; - } - } - } - errCode = SSL_ERROR_NO_COMPRESSION_OVERLAP; - /* null compression must be supported */ - goto alert_loser; - -compression_found: +cipher_found: suites->data = NULL; - comps->data = NULL; /* If there are any failures while processing the old sid, * we don't consider them to be errors. Instead, We just behave @@ -8775,12 +8443,10 @@ compression_found: */ if (sid != NULL) do { - ssl3CipherSpec *pwSpec; - SECItem wrappedMS; /* wrapped key */ + PK11SymKey *masterSecret; if (sid->version != ss->version || - sid->u.ssl3.cipherSuite != ss->ssl3.hs.cipher_suite || - sid->u.ssl3.compression != ss->ssl3.hs.compression) { + sid->u.ssl3.cipherSuite != ss->ssl3.hs.cipher_suite) { break; /* not an error */ } @@ -8822,61 +8488,20 @@ compression_found: } if (ss->sec.ci.sid) { - ss->sec.uncache(ss->sec.ci.sid); + ssl_UncacheSessionID(ss); PORT_Assert(ss->sec.ci.sid != sid); /* should be impossible, but ... */ if (ss->sec.ci.sid != sid) { ssl_FreeSID(ss->sec.ci.sid); } ss->sec.ci.sid = NULL; } - /* we need to resurrect the master secret.... */ - - ssl_GetSpecWriteLock(ss); - haveSpecWriteLock = PR_TRUE; - pwSpec = ss->ssl3.pwSpec; - if (sid->u.ssl3.keys.msIsWrapped) { - PK11SymKey *wrapKey; /* wrapping key */ - CK_FLAGS keyFlags = 0; - - wrapKey = ssl3_GetWrappingKey(ss, NULL, - sid->u.ssl3.masterWrapMech, - ss->pkcs11PinArg); - if (!wrapKey) { - /* we have a SID cache entry, but no wrapping key for it??? */ - break; - } - - if (ss->version > SSL_LIBRARY_VERSION_3_0) { /* isTLS */ - keyFlags = CKF_SIGN | CKF_VERIFY; - } - wrappedMS.data = sid->u.ssl3.keys.wrapped_master_secret; - wrappedMS.len = sid->u.ssl3.keys.wrapped_master_secret_len; - - /* unwrap the master secret. */ - pwSpec->master_secret = - PK11_UnwrapSymKeyWithFlags(wrapKey, sid->u.ssl3.masterWrapMech, - NULL, &wrappedMS, CKM_SSL3_MASTER_KEY_DERIVE, - CKA_DERIVE, sizeof(SSL3MasterSecret), keyFlags); - PK11_FreeSymKey(wrapKey); - if (pwSpec->master_secret == NULL) { - break; /* not an error */ - } - } else { - /* need to import the raw master secret to session object */ - PK11SlotInfo *slot; - wrappedMS.data = sid->u.ssl3.keys.wrapped_master_secret; - wrappedMS.len = sid->u.ssl3.keys.wrapped_master_secret_len; - slot = PK11_GetInternalSlot(); - pwSpec->master_secret = - PK11_ImportSymKey(slot, CKM_SSL3_MASTER_KEY_DERIVE, - PK11_OriginUnwrap, CKA_ENCRYPT, &wrappedMS, - NULL); - PK11_FreeSlot(slot); - if (pwSpec->master_secret == NULL) { - break; /* not an error */ - } + /* we need to resurrect the master secret.... */ + rv = ssl3_UnwrapMasterSecretServer(ss, sid, &masterSecret); + if (rv != SECSuccess) { + break; /* not an error */ } + ss->sec.ci.sid = sid; if (sid->peerCert != NULL) { ss->sec.peerCert = CERT_DupCertificate(sid->peerCert); @@ -8884,8 +8509,6 @@ compression_found: /* * Old SID passed all tests, so resume this old session. - * - * XXX make sure compression still matches */ SSL_AtomicIncrementLong(&ssl3stats.hch_sid_cache_hits); if (ss->statelessResume) @@ -8896,6 +8519,8 @@ compression_found: ss->sec.authKeyBits = sid->authKeyBits; ss->sec.keaType = sid->keaType; ss->sec.keaKeyBits = sid->keaKeyBits; + ss->sec.originalKeaGroup = ssl_LookupNamedGroup(sid->keaGroup); + ss->sec.signatureScheme = sid->sigScheme; ss->sec.localCert = CERT_DupCertificate(ss->sec.serverCert->serverCert); @@ -8930,13 +8555,8 @@ compression_found: goto loser; } - if (haveSpecWriteLock) { - ssl_ReleaseSpecWriteLock(ss); - haveSpecWriteLock = PR_FALSE; - } - - /* NULL value for PMS because we are re-using the old MS */ - rv = ssl3_InitPendingCipherSpec(ss, NULL); + /* We are re-using the old MS, so no need to derive again. */ + rv = ssl3_InitPendingCipherSpecs(ss, masterSecret, PR_FALSE); if (rv != SECSuccess) { errCode = PORT_GetError(); goto loser; @@ -8961,14 +8581,10 @@ compression_found: return SECSuccess; } while (0); - if (haveSpecWriteLock) { - ssl_ReleaseSpecWriteLock(ss); - haveSpecWriteLock = PR_FALSE; - } - if (sid) { /* we had a sid, but it's no longer valid, free it */ + ss->statelessResume = PR_FALSE; SSL_AtomicIncrementLong(&ssl3stats.hch_sid_cache_not_ok); - ss->sec.uncache(sid); + ssl_UncacheSessionID(ss); ssl_FreeSID(sid); sid = NULL; } @@ -8985,9 +8601,8 @@ compression_found: */ if (ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn) && ssl3_KEASupportsTickets(ss->ssl3.hs.kea_def)) { - ssl3_RegisterExtensionSender(ss, &ss->xtnData, - ssl_session_ticket_xtn, - ssl3_SendSessionTicketXtn); + ssl3_RegisterExtensionSender(ss, &ss->xtnData, ssl_session_ticket_xtn, + ssl_SendEmptyExtension); } rv = ssl3_ServerCallSNICallback(ss); @@ -9031,22 +8646,14 @@ compression_found: return SECSuccess; alert_loser: - if (haveSpecWriteLock) { - ssl_ReleaseSpecWriteLock(ss); - haveSpecWriteLock = PR_FALSE; - } (void)SSL3_SendAlert(ss, alert_fatal, desc); /* FALLTHRU */ loser: if (sid && sid != ss->sec.ci.sid) { - ss->sec.uncache(sid); + ssl_UncacheSessionID(ss); ssl_FreeSID(sid); } - if (haveSpecWriteLock) { - ssl_ReleaseSpecWriteLock(ss); - } - if (haveXmitBufLock) { ssl_ReleaseXmitBufLock(ss); } @@ -9060,7 +8667,7 @@ loser: * in asking to use the V3 handshake. */ SECStatus -ssl3_HandleV2ClientHello(sslSocket *ss, unsigned char *buffer, int length, +ssl3_HandleV2ClientHello(sslSocket *ss, unsigned char *buffer, unsigned int length, PRUint8 padding) { sslSessionID *sid = NULL; @@ -9068,11 +8675,11 @@ ssl3_HandleV2ClientHello(sslSocket *ss, unsigned char *buffer, int length, unsigned char *random; SSL3ProtocolVersion version; SECStatus rv; - int i; - int j; - int sid_length; - int suite_length; - int rand_length; + unsigned int i; + unsigned int j; + unsigned int sid_length; + unsigned int suite_length; + unsigned int rand_length; int errCode = SSL_ERROR_RX_MALFORMED_CLIENT_HELLO; SSL3AlertDescription desc = handshake_failure; unsigned int total = SSL_HL_CLIENT_HELLO_HBYTES; @@ -9083,14 +8690,11 @@ ssl3_HandleV2ClientHello(sslSocket *ss, unsigned char *buffer, int length, ssl_GetSSL3HandshakeLock(ss); - ssl3_ResetExtensionData(&ss->xtnData); - version = (buffer[1] << 8) | buffer[2]; if (version < SSL_LIBRARY_VERSION_3_0) { goto loser; } - ssl3_InitState(ss); ssl3_RestartHandshakeHashes(ss); if (ss->ssl3.hs.ws != wait_client_hello) { @@ -9122,6 +8726,11 @@ ssl3_HandleV2ClientHello(sslSocket *ss, unsigned char *buffer, int length, goto alert_loser; } ss->ssl3.hs.preliminaryInfo |= ssl_preinfo_version; + if (!ss->firstHsDone) { + ssl_GetSpecWriteLock(ss); + ssl_SetSpecVersions(ss, ss->ssl3.cwSpec); + ssl_ReleaseSpecWriteLock(ss); + } /* if we get a non-zero SID, just ignore it. */ if (length != total) { @@ -9144,15 +8753,14 @@ ssl3_HandleV2ClientHello(sslSocket *ss, unsigned char *buffer, int length, PORT_Assert(SSL_MAX_CHALLENGE_BYTES == SSL3_RANDOM_LENGTH); - PORT_Memset(&ss->ssl3.hs.client_random, 0, SSL3_RANDOM_LENGTH); - PORT_Memcpy( - &ss->ssl3.hs.client_random.rand[SSL3_RANDOM_LENGTH - rand_length], - random, rand_length); + PORT_Memset(ss->ssl3.hs.client_random, 0, SSL3_RANDOM_LENGTH); + PORT_Memcpy(&ss->ssl3.hs.client_random[SSL3_RANDOM_LENGTH - rand_length], + random, rand_length); - PRINT_BUF(60, (ss, "client random:", &ss->ssl3.hs.client_random.rand[0], + PRINT_BUF(60, (ss, "client random:", ss->ssl3.hs.client_random, SSL3_RANDOM_LENGTH)); - i = ssl3_config_match_init(ss); - if (i <= 0) { + + if (ssl3_config_match_init(ss) == 0) { errCode = PORT_GetError(); /* error code is already set. */ goto alert_loser; } @@ -9161,8 +8769,6 @@ ssl3_HandleV2ClientHello(sslSocket *ss, unsigned char *buffer, int length, ** ** NOTE: This suite selection algorithm should be the same as the one in ** ssl3_HandleClientHello(). - ** - ** See the comments about export cipher suites in ssl3_HandleClientHello(). */ for (j = 0; j < ssl_V3_SUITES_IMPLEMENTED; j++) { ssl3CipherSuiteCfg *suite = &ss->cipherSuites[j]; @@ -9173,7 +8779,8 @@ ssl3_HandleV2ClientHello(sslSocket *ss, unsigned char *buffer, int length, for (i = 0; i + 2 < suite_length; i += 3) { PRUint32 suite_i = (suites[i] << 16) | (suites[i + 1] << 8) | suites[i + 2]; if (suite_i == suite->cipher_suite) { - rv = ssl3_SetCipherSuite(ss, suite_i, PR_TRUE); + ss->ssl3.hs.cipher_suite = suite_i; + rv = ssl3_SetupCipherSuite(ss, PR_TRUE); if (rv != SECSuccess) { desc = internal_error; errCode = PORT_GetError(); @@ -9209,7 +8816,7 @@ suite_found: if (suite_i == TLS_EMPTY_RENEGOTIATION_INFO_SCSV) { PRUint8 *b2 = (PRUint8 *)emptyRIext; PRUint32 L2 = sizeof emptyRIext; - (void)ssl3_HandleExtensions(ss, &b2, &L2, client_hello); + (void)ssl3_HandleExtensions(ss, &b2, &L2, ssl_hs_client_hello); break; } } @@ -9221,8 +8828,6 @@ suite_found: goto alert_loser; } - ss->ssl3.hs.compression = ssl_compression_null; - rv = ssl3_SelectServerCert(ss); if (rv != SECSuccess) { errCode = PORT_GetError(); @@ -9266,6 +8871,64 @@ loser: return SECFailure; } +SECStatus +ssl_ConstructServerHello(sslSocket *ss, PRBool helloRetry, + const sslBuffer *extensionBuf, sslBuffer *messageBuf) +{ + SECStatus rv; + 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); + } + + rv = sslBuffer_AppendNumber(messageBuf, version, 2); + if (rv != SECSuccess) { + return SECFailure; + } + /* Random already generated in ssl3_HandleClientHello */ + rv = sslBuffer_Append(messageBuf, helloRetry ? ssl_hello_retry_random : ss->ssl3.hs.server_random, + SSL3_RANDOM_LENGTH); + if (rv != SECSuccess) { + return SECFailure; + } + + if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) { + if (sid) { + rv = sslBuffer_AppendVariable(messageBuf, sid->u.ssl3.sessionID, + sid->u.ssl3.sessionIDLength, 1); + } else { + rv = sslBuffer_AppendNumber(messageBuf, 0, 1); + } + } else { + rv = sslBuffer_AppendVariable(messageBuf, ss->ssl3.hs.fakeSid.data, + ss->ssl3.hs.fakeSid.len, 1); + } + if (rv != SECSuccess) { + return SECFailure; + } + + rv = sslBuffer_AppendNumber(messageBuf, ss->ssl3.hs.cipher_suite, 2); + if (rv != SECSuccess) { + return SECFailure; + } + rv = sslBuffer_AppendNumber(messageBuf, ssl_compression_null, 1); + if (rv != SECSuccess) { + return SECFailure; + } + if (SSL_BUFFER_LEN(extensionBuf)) { + rv = sslBuffer_AppendBufferVariable(messageBuf, extensionBuf, 2); + if (rv != SECSuccess) { + return SECFailure; + } + } + + return SECSuccess; +} + /* The negotiated version number has been already placed in ss->version. ** ** Called from: ssl3_HandleClientHello (resuming session), @@ -9275,12 +8938,9 @@ loser: SECStatus ssl3_SendServerHello(sslSocket *ss) { - sslSessionID *sid; SECStatus rv; - PRUint32 maxBytes = 65535; - PRUint32 length; - PRInt32 extensions_len = 0; - SSL3ProtocolVersion version; + sslBuffer extensionBuf = SSL_BUFFER_EMPTY; + sslBuffer messageBuf = SSL_BUFFER_EMPTY; SSL_TRC(3, ("%d: SSL3[%d]: send server_hello handshake", SSL_GETPID(), ss->fd)); @@ -9294,94 +8954,43 @@ ssl3_SendServerHello(sslSocket *ss) return SECFailure; } - sid = ss->sec.ci.sid; - - extensions_len = ssl3_CallHelloExtensionSenders( - ss, PR_FALSE, maxBytes, &ss->xtnData.serverHelloSenders[0]); - if (extensions_len > 0) - extensions_len += 2; /* Add sizeof total extension length */ - - /* TLS 1.3 doesn't use the session_id or compression_method - * fields in the ServerHello. */ - length = sizeof(SSL3ProtocolVersion) + SSL3_RANDOM_LENGTH; - if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) { - length += 1 + ((sid == NULL) ? 0 : sid->u.ssl3.sessionIDLength); - } - length += sizeof(ssl3CipherSuite); - if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) { - length += 1; /* Compression */ - } - length += extensions_len; - - rv = ssl3_AppendHandshakeHeader(ss, server_hello, length); + rv = ssl_ConstructExtensions(ss, &extensionBuf, ssl_hs_server_hello); if (rv != SECSuccess) { - return rv; /* err set by AppendHandshake. */ - } - - if (IS_DTLS(ss) && ss->version < SSL_LIBRARY_VERSION_TLS_1_3) { - version = dtls_TLSVersionToDTLSVersion(ss->version); - } else { - version = tls13_EncodeDraftVersion(ss->version); + goto loser; } - rv = ssl3_AppendHandshakeNumber(ss, version, 2); - if (rv != SECSuccess) { - return rv; /* err set by AppendHandshake. */ - } - /* Random already generated in ssl3_HandleClientHello */ - rv = ssl3_AppendHandshake( - ss, &ss->ssl3.hs.server_random, SSL3_RANDOM_LENGTH); + rv = ssl_ConstructServerHello(ss, PR_FALSE, &extensionBuf, &messageBuf); if (rv != SECSuccess) { - return rv; /* err set by AppendHandshake. */ - } - - if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) { - if (sid) { - rv = ssl3_AppendHandshakeVariable( - ss, sid->u.ssl3.sessionID, sid->u.ssl3.sessionIDLength, 1); - } else { - rv = ssl3_AppendHandshakeNumber(ss, 0, 1); - } - if (rv != SECSuccess) { - return rv; /* err set by AppendHandshake. */ - } + goto loser; } - rv = ssl3_AppendHandshakeNumber(ss, ss->ssl3.hs.cipher_suite, 2); + rv = ssl3_AppendHandshakeHeader(ss, ssl_hs_server_hello, + SSL_BUFFER_LEN(&messageBuf)); if (rv != SECSuccess) { - return rv; /* err set by AppendHandshake. */ - } - if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) { - rv = ssl3_AppendHandshakeNumber(ss, ss->ssl3.hs.compression, 1); - if (rv != SECSuccess) { - return rv; /* err set by AppendHandshake. */ - } + goto loser; /* err set by AppendHandshake. */ } - if (extensions_len) { - PRInt32 sent_len; - extensions_len -= 2; - rv = ssl3_AppendHandshakeNumber(ss, extensions_len, 2); - if (rv != SECSuccess) - return rv; /* err set by ssl3_AppendHandshakeNumber */ - sent_len = ssl3_CallHelloExtensionSenders(ss, PR_TRUE, extensions_len, - &ss->xtnData.serverHelloSenders[0]); - PORT_Assert(sent_len == extensions_len); - if (sent_len != extensions_len) { - if (sent_len >= 0) - PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); - return SECFailure; - } + rv = ssl3_AppendHandshake(ss, SSL_BUFFER_BASE(&messageBuf), + SSL_BUFFER_LEN(&messageBuf)); + if (rv != SECSuccess) { + goto loser; /* err set by AppendHandshake. */ } if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) { - rv = ssl3_SetupPendingCipherSpec(ss); + rv = ssl3_SetupBothPendingCipherSpecs(ss); if (rv != SECSuccess) { - return rv; /* err set by ssl3_SetupPendingCipherSpec */ + goto loser; /* err set */ } } + sslBuffer_Clear(&extensionBuf); + sslBuffer_Clear(&messageBuf); return SECSuccess; + +loser: + sslBuffer_Clear(&extensionBuf); + sslBuffer_Clear(&messageBuf); + return SECFailure; } SECStatus @@ -9438,6 +9047,8 @@ ssl3_SendDHServerKeyExchange(sslSocket *ss) SECKEYPublicKey *pubKey; SECKEYPrivateKey *certPrivateKey; const sslNamedGroupDef *groupDef; + /* Do this on the heap, this could be over 2k long. */ + sslBuffer dhBuf = SSL_BUFFER_EMPTY; if (kea_def->kea != kea_dhe_dss && kea_def->kea != kea_dhe_rsa) { /* TODO: Support DH_anon. It might be sufficient to drop the signature. @@ -9461,7 +9072,7 @@ ssl3_SendDHServerKeyExchange(sslSocket *ss) } PR_APPEND_LINK(&keyPair->link, &ss->ephemeralKeyPairs); - if (ss->ssl3.pwSpec->version == SSL_LIBRARY_VERSION_TLS_1_2) { + if (ss->version == SSL_LIBRARY_VERSION_TLS_1_2) { hashAlg = ssl_SignatureSchemeToHashType(ss->ssl3.hs.signatureScheme); } else { /* Use ssl_hash_none to represent the MD5+SHA1 combo. */ @@ -9493,11 +9104,11 @@ ssl3_SendDHServerKeyExchange(sslSocket *ss) 2 + pubKey->u.dh.prime.len + 2 + signed_hash.len; - if (ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2) { + if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_2) { length += 2; } - rv = ssl3_AppendHandshakeHeader(ss, server_key_exchange, length); + rv = ssl3_AppendHandshakeHeader(ss, ssl_hs_server_key_exchange, length); if (rv != SECSuccess) { goto loser; /* err set by AppendHandshake. */ } @@ -9514,12 +9125,16 @@ ssl3_SendDHServerKeyExchange(sslSocket *ss) goto loser; /* err set by AppendHandshake. */ } - rv = ssl_AppendPaddedDHKeyShare(ss, pubKey, PR_TRUE); + rv = ssl_AppendPaddedDHKeyShare(&dhBuf, pubKey, PR_TRUE); + if (rv != SECSuccess) { + goto loser; /* err set by AppendPaddedDHKeyShare. */ + } + rv = ssl3_AppendBufferToHandshake(ss, &dhBuf); if (rv != SECSuccess) { goto loser; /* err set by AppendHandshake. */ } - if (ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2) { + if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_2) { rv = ssl3_AppendHandshakeNumber(ss, ss->ssl3.hs.signatureScheme, 2); if (rv != SECSuccess) { goto loser; /* err set by AppendHandshake. */ @@ -9531,12 +9146,15 @@ ssl3_SendDHServerKeyExchange(sslSocket *ss) if (rv != SECSuccess) { goto loser; /* err set by AppendHandshake. */ } + + sslBuffer_Clear(&dhBuf); PORT_Free(signed_hash.data); return SECSuccess; loser: if (signed_hash.data) PORT_Free(signed_hash.data); + sslBuffer_Clear(&dhBuf); return SECFailure; } @@ -9571,14 +9189,15 @@ ssl3_SendServerKeyExchange(sslSocket *ss) } SECStatus -ssl3_EncodeSigAlgs(const sslSocket *ss, PRUint8 *buf, unsigned maxLen, PRUint32 *len) +ssl3_EncodeSigAlgs(const sslSocket *ss, sslBuffer *buf) { + unsigned int lengthOffset; unsigned int i; - PRUint8 *p = buf; + PRBool found = PR_FALSE; + SECStatus rv; - PORT_Assert(maxLen >= ss->ssl3.signatureSchemeCount * 2); - if (maxLen < ss->ssl3.signatureSchemeCount * 2) { - PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + rv = sslBuffer_Skip(buf, 2, &lengthOffset); + if (rv != SECSuccess) { return SECFailure; } @@ -9596,16 +9215,21 @@ ssl3_EncodeSigAlgs(const sslSocket *ss, PRUint8 *buf, unsigned maxLen, PRUint32 if ((NSS_GetAlgorithmPolicy(hashOID, &policy) != SECSuccess) || (policy & NSS_USE_ALG_IN_SSL_KX)) { - p = ssl_EncodeUintX((PRUint32)ss->ssl3.signatureSchemes[i], 2, p); + rv = sslBuffer_AppendNumber(buf, ss->ssl3.signatureSchemes[i], 2); + if (rv != SECSuccess) { + return SECFailure; + } + + found = PR_TRUE; } } - if (p == buf) { + if (!found) { PORT_SetError(SSL_ERROR_NO_SUPPORTED_SIGNATURE_ALGORITHM); return SECFailure; } - *len = p - buf; - return SECSuccess; + + return sslBuffer_InsertLength(buf, lengthOffset, 2); } static SECStatus @@ -9614,15 +9238,15 @@ ssl3_SendCertificateRequest(sslSocket *ss) PRBool isTLS12; const PRUint8 *certTypes; SECStatus rv; - int length; - SECItem *names; + PRUint32 length; + const SECItem *names; unsigned int calen; unsigned int nnames; - SECItem *name; - int i; + const SECItem *name; + unsigned int i; int certTypesLength; - PRUint8 sigAlgs[MAX_SIGNATURE_SCHEMES * 2]; - unsigned int sigAlgsLength = 0; + PRUint8 sigAlgs[2 + MAX_SIGNATURE_SCHEMES * 2]; + sslBuffer sigAlgsBuf = SSL_BUFFER(sigAlgs); SSL_TRC(3, ("%d: SSL3[%d]: send certificate_request handshake", SSL_GETPID(), ss->fd)); @@ -9630,7 +9254,7 @@ ssl3_SendCertificateRequest(sslSocket *ss) PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); - isTLS12 = (PRBool)(ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2); + isTLS12 = (PRBool)(ss->version >= SSL_LIBRARY_VERSION_TLS_1_2); rv = ssl_GetCertificateRequestCAs(ss, &calen, &names, &nnames); if (rv != SECSuccess) { @@ -9641,14 +9265,14 @@ ssl3_SendCertificateRequest(sslSocket *ss) length = 1 + certTypesLength + 2 + calen; if (isTLS12) { - rv = ssl3_EncodeSigAlgs(ss, sigAlgs, sizeof(sigAlgs), &sigAlgsLength); + rv = ssl3_EncodeSigAlgs(ss, &sigAlgsBuf); if (rv != SECSuccess) { return rv; } - length += 2 + sigAlgsLength; + length += SSL_BUFFER_LEN(&sigAlgsBuf); } - rv = ssl3_AppendHandshakeHeader(ss, certificate_request, length); + rv = ssl3_AppendHandshakeHeader(ss, ssl_hs_certificate_request, length); if (rv != SECSuccess) { return rv; /* err set by AppendHandshake. */ } @@ -9657,7 +9281,8 @@ ssl3_SendCertificateRequest(sslSocket *ss) return rv; /* err set by AppendHandshake. */ } if (isTLS12) { - rv = ssl3_AppendHandshakeVariable(ss, sigAlgs, sigAlgsLength, 2); + rv = ssl3_AppendHandshake(ss, SSL_BUFFER_BASE(&sigAlgsBuf), + SSL_BUFFER_LEN(&sigAlgsBuf)); if (rv != SECSuccess) { return rv; /* err set by AppendHandshake. */ } @@ -9687,7 +9312,7 @@ ssl3_SendServerHelloDone(sslSocket *ss) PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); - rv = ssl3_AppendHandshakeHeader(ss, server_hello_done, 0); + rv = ssl3_AppendHandshakeHeader(ss, ssl_hs_server_hello_done, 0); if (rv != SECSuccess) { return rv; /* err set by AppendHandshake. */ } @@ -9703,8 +9328,7 @@ ssl3_SendServerHelloDone(sslSocket *ss) * Caller must hold Handshake and RecvBuf locks. */ static SECStatus -ssl3_HandleCertificateVerify(sslSocket *ss, PRUint8 *b, PRUint32 length, - SSL3Hashes *hashes) +ssl3_HandleCertificateVerify(sslSocket *ss, PRUint8 *b, PRUint32 length) { SECItem signed_hash = { siBuffer, NULL, 0 }; SECStatus rv; @@ -9712,9 +9336,9 @@ ssl3_HandleCertificateVerify(sslSocket *ss, PRUint8 *b, PRUint32 length, SSL3AlertDescription desc = handshake_failure; PRBool isTLS; SSLSignatureScheme sigScheme; - SSLHashType hashAlg; - SSL3Hashes localHashes; - SSL3Hashes *hashesForVerify = NULL; + SSL3Hashes hashes; + const PRUint8 *savedMsg = b; + const PRUint32 savedLen = length; SSL_TRC(3, ("%d: SSL3[%d]: handle certificate_verify handshake", SSL_GETPID(), ss->fd)); @@ -9730,14 +9354,8 @@ ssl3_HandleCertificateVerify(sslSocket *ss, PRUint8 *b, PRUint32 length, /* TLS 1.3 is handled by tls13_HandleCertificateVerify */ PORT_Assert(ss->ssl3.prSpec->version <= SSL_LIBRARY_VERSION_TLS_1_2); - if (!hashes) { - PORT_Assert(0); - desc = internal_error; - errCode = SEC_ERROR_LIBRARY_FAILURE; - goto alert_loser; - } - - if (ss->ssl3.hs.hashType == handshake_hash_record) { + if (ss->ssl3.prSpec->version == SSL_LIBRARY_VERSION_TLS_1_2) { + PORT_Assert(ss->ssl3.hs.hashType == handshake_hash_record); rv = ssl_ConsumeSignatureScheme(ss, &b, &length, &sigScheme); if (rv != SECSuccess) { goto loser; /* malformed or unsupported. */ @@ -9750,25 +9368,20 @@ ssl3_HandleCertificateVerify(sslSocket *ss, PRUint8 *b, PRUint32 length, goto alert_loser; } - hashAlg = ssl_SignatureSchemeToHashType(sigScheme); - - /* Read from the message buffer, but we need to use only up to the end - * of the previous handshake message. The length of the transcript up to - * that point is saved in |hashes->u.transcriptLen|. */ rv = ssl3_ComputeHandshakeHash(ss->ssl3.hs.messages.buf, - hashes->u.transcriptLen, - hashAlg, &localHashes); - - if (rv == SECSuccess) { - hashesForVerify = &localHashes; - } else { - errCode = SSL_ERROR_DIGEST_FAILURE; - desc = decrypt_error; - goto alert_loser; - } + ss->ssl3.hs.messages.len, + ssl_SignatureSchemeToHashType(sigScheme), + &hashes); } else { - hashesForVerify = hashes; + PORT_Assert(ss->ssl3.hs.hashType != handshake_hash_record); sigScheme = ssl_sig_none; + rv = ssl3_ComputeHandshakeHashes(ss, ss->ssl3.prSpec, &hashes, 0); + } + + if (rv != SECSuccess) { + errCode = SSL_ERROR_DIGEST_FAILURE; + desc = decrypt_error; + goto alert_loser; } rv = ssl3_ConsumeHandshakeVariable(ss, &signed_hash, 2, &b, &length); @@ -9779,7 +9392,7 @@ ssl3_HandleCertificateVerify(sslSocket *ss, PRUint8 *b, PRUint32 length, isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0); /* XXX verify that the key & kea match */ - rv = ssl3_VerifySignedHashes(ss, sigScheme, hashesForVerify, &signed_hash); + rv = ssl3_VerifySignedHashes(ss, sigScheme, &hashes, &signed_hash); if (rv != SECSuccess) { errCode = PORT_GetError(); desc = isTLS ? decrypt_error : handshake_failure; @@ -9792,6 +9405,14 @@ ssl3_HandleCertificateVerify(sslSocket *ss, PRUint8 *b, PRUint32 length, desc = isTLS ? decode_error : illegal_parameter; goto alert_loser; /* malformed */ } + + rv = ssl_HashHandshakeMessage(ss, ssl_hs_certificate_verify, + savedMsg, savedLen); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return rv; + } + ss->ssl3.hs.ws = wait_change_cipher; return SECSuccess; @@ -9832,9 +9453,9 @@ ssl3_GenerateRSAPMS(sslSocket *ss, ssl3CipherSpec *spec, ** slot already hold the SpecWriteLock. */ PORT_Assert(ss->opt.noLocks || ssl_HaveSpecWriteLock(ss)); - PORT_Assert(ss->ssl3.prSpec == ss->ssl3.pwSpec); + PORT_Assert(ss->ssl3.prSpec->epoch == ss->ssl3.pwSpec->epoch); - calg = spec->cipher_def->calg; + calg = spec->cipherDef->calg; /* First get an appropriate slot. */ mechanism_array[0] = CKM_SSL3_PRE_MASTER_KEY_GEN; @@ -9902,7 +9523,7 @@ ssl3_HandleRSAClientKeyExchange(sslSocket *ss, PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss)); PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); - PORT_Assert(ss->ssl3.prSpec == ss->ssl3.pwSpec); + PORT_Assert(ss->ssl3.prSpec->epoch == ss->ssl3.pwSpec->epoch); enc_pms.data = b; enc_pms.len = length; @@ -9999,7 +9620,7 @@ ssl3_HandleRSAClientKeyExchange(sslSocket *ss, } /* This step will derive the MS from the PMS, among other things. */ - rv = ssl3_InitPendingCipherSpec(ss, currentPms); + rv = ssl3_InitPendingCipherSpecs(ss, currentPms, PR_TRUE); PK11_FreeSymKey(currentPms); if (rv != SECSuccess) { @@ -10064,7 +9685,7 @@ ssl3_HandleDHClientKeyExchange(sslSocket *ss, return SECFailure; } - rv = ssl3_InitPendingCipherSpec(ss, pms); + rv = ssl3_InitPendingCipherSpecs(ss, pms, PR_TRUE); PK11_FreeSymKey(pms); ssl_FreeEphemeralKeyPairs(ss); return rv; @@ -10163,13 +9784,13 @@ ssl3_SendEmptyCertificate(sslSocket *ss) const SECItem *context; if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) { - PORT_Assert(ss->ssl3.hs.certificateRequest); - context = &ss->ssl3.hs.certificateRequest->context; + PORT_Assert(ss->ssl3.hs.clientCertRequested); + context = &ss->xtnData.certReqContext; len = context->len + 1; isTLS13 = PR_TRUE; } - rv = ssl3_AppendHandshakeHeader(ss, certificate, len + 3); + rv = ssl3_AppendHandshakeHeader(ss, ssl_hs_certificate, len + 3); if (rv != SECSuccess) { return rv; } @@ -10195,13 +9816,14 @@ ssl3_SendNewSessionTicket(sslSocket *ss) SECStatus rv; NewSessionTicket nticket = { 0 }; - rv = ssl3_EncodeSessionTicket(ss, &nticket, &ticket); + rv = ssl3_EncodeSessionTicket(ss, &nticket, NULL, 0, + ss->ssl3.pwSpec->masterSecret, &ticket); if (rv != SECSuccess) goto loser; /* Serialize the handshake message. Length = * lifetime (4) + ticket length (2) + ticket. */ - rv = ssl3_AppendHandshakeHeader(ss, new_session_ticket, + rv = ssl3_AppendHandshakeHeader(ss, ssl_hs_new_session_ticket, 4 + 2 + ticket.len); if (rv != SECSuccess) goto loser; @@ -10251,7 +9873,7 @@ ssl3_HandleNewSessionTicket(sslSocket *ss, PRUint8 *b, PRUint32 length) * until it has verified the server's Finished message." See the comment in * ssl3_FinishHandshake for more details. */ - ss->ssl3.hs.newSessionTicket.received_timestamp = PR_Now(); + ss->ssl3.hs.newSessionTicket.received_timestamp = ssl_TimeUsec(); if (length < 4) { (void)SSL3_SendAlert(ss, alert_fatal, decode_error); PORT_SetError(SSL_ERROR_RX_MALFORMED_NEW_SESSION_TICKET); @@ -10393,8 +10015,8 @@ ssl3_SendCertificate(sslSocket *ss) if (isTLS13) { contextLen = 1; /* Size of the context length */ if (!ss->sec.isServer) { - PORT_Assert(ss->ssl3.hs.certificateRequest); - context = ss->ssl3.hs.certificateRequest->context; + PORT_Assert(ss->ssl3.hs.clientCertRequested); + context = ss->xtnData.certReqContext; contextLen += context.len; } } @@ -10412,7 +10034,7 @@ ssl3_SendCertificate(sslSocket *ss) } } - rv = ssl3_AppendHandshakeHeader(ss, certificate, + rv = ssl3_AppendHandshakeHeader(ss, ssl_hs_certificate, contextLen + certChainLen + 3); if (rv != SECSuccess) { return rv; /* err set by AppendHandshake. */ @@ -10487,7 +10109,7 @@ ssl3_SendCertificateStatus(sslSocket *ss) /* Use the array's first item only (single stapling) */ len = 1 + statusToSend->items[0].len + 3; - rv = ssl3_AppendHandshakeHeader(ss, certificate_status, len); + rv = ssl3_AppendHandshakeHeader(ss, ssl_hs_certificate_status, len); if (rv != SECSuccess) { return rv; /* err set by AppendHandshake. */ } @@ -10618,6 +10240,10 @@ ssl3_HandleCertificate(sslSocket *ss, PRUint8 *b, PRUint32 length) return SECFailure; } + if (ss->sec.isServer) { + dtls_ReceivedFirstMessageInFlight(ss); + } + return ssl3_CompleteHandleCertificate(ss, b, length); } @@ -10837,7 +10463,8 @@ ssl3_AuthCertificate(sslSocket *ss) } if (pubKey) { KeyType pubKeyType; - PRInt32 minKey; + PRUint32 minKey; + PRInt32 optval; /* This partly fixes Bug 124230 and may cause problems for * callers which depend on the old (wrong) behavior. */ ss->sec.authKeyBits = SECKEY_PublicKeyStrengthInBits(pubKey); @@ -10848,29 +10475,29 @@ ssl3_AuthCertificate(sslSocket *ss) case rsaPssKey: case rsaOaepKey: rv = - NSS_OptionGet(NSS_RSA_MIN_KEY_SIZE, &minKey); - if (rv != - SECSuccess) { - minKey = - SSL_RSA_MIN_MODULUS_BITS; + NSS_OptionGet(NSS_RSA_MIN_KEY_SIZE, &optval); + if (rv == SECSuccess && optval > 0) { + minKey = (PRUint32)optval; + } else { + minKey = SSL_RSA_MIN_MODULUS_BITS; } break; case dsaKey: rv = - NSS_OptionGet(NSS_DSA_MIN_KEY_SIZE, &minKey); - if (rv != - SECSuccess) { - minKey = - SSL_DSA_MIN_P_BITS; + NSS_OptionGet(NSS_DSA_MIN_KEY_SIZE, &optval); + if (rv == SECSuccess && optval > 0) { + minKey = (PRUint32)optval; + } else { + minKey = SSL_DSA_MIN_P_BITS; } break; case dhKey: rv = - NSS_OptionGet(NSS_DH_MIN_KEY_SIZE, &minKey); - if (rv != - SECSuccess) { - minKey = - SSL_DH_MIN_P_BITS; + NSS_OptionGet(NSS_DH_MIN_KEY_SIZE, &optval); + if (rv == SECSuccess && optval > 0) { + minKey = (PRUint32)optval; + } else { + minKey = SSL_DH_MIN_P_BITS; } break; default: @@ -11029,8 +10656,8 @@ ssl3_ComputeTLSFinished(sslSocket *ss, ssl3CipherSpec *spec, PK11Context *prf_context; unsigned int retLen; - PORT_Assert(spec->master_secret); - if (!spec->master_secret) { + PORT_Assert(spec->masterSecret); + if (!spec->masterSecret) { PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); return SECFailure; } @@ -11045,7 +10672,7 @@ ssl3_ComputeTLSFinished(sslSocket *ss, ssl3CipherSpec *spec, param.data = (unsigned char *)&tls_mac_params; param.len = sizeof(tls_mac_params); prf_context = PK11_CreateContextBySymKey(CKM_TLS_MAC, CKA_SIGN, - spec->master_secret, ¶m); + spec->masterSecret, ¶m); if (!prf_context) return SECFailure; @@ -11070,40 +10697,39 @@ ssl3_TLSPRFWithMasterSecret(sslSocket *ss, ssl3CipherSpec *spec, const unsigned char *val, unsigned int valLen, unsigned char *out, unsigned int outLen) { - SECStatus rv = SECSuccess; + SECItem param = { siBuffer, NULL, 0 }; + CK_MECHANISM_TYPE mech = CKM_TLS_PRF_GENERAL; + PK11Context *prf_context; + unsigned int retLen; + SECStatus rv; - if (spec->master_secret) { - SECItem param = { siBuffer, NULL, 0 }; - CK_MECHANISM_TYPE mech = CKM_TLS_PRF_GENERAL; - PK11Context *prf_context; - unsigned int retLen; + if (!spec->masterSecret) { + PORT_Assert(spec->masterSecret); + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } - if (spec->version >= SSL_LIBRARY_VERSION_TLS_1_2) { - /* Bug 1312976 non-SHA256 exporters are broken. */ - if (ssl3_GetPrfHashMechanism(ss) != CKM_SHA256) { - PORT_Assert(0); - PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); - return SECFailure; - } - mech = CKM_NSS_TLS_PRF_GENERAL_SHA256; - } - prf_context = PK11_CreateContextBySymKey(mech, CKA_SIGN, - spec->master_secret, ¶m); - if (!prf_context) + if (spec->version >= SSL_LIBRARY_VERSION_TLS_1_2) { + /* Bug 1312976 non-SHA256 exporters are broken. */ + if (ssl3_GetPrfHashMechanism(ss) != CKM_SHA256) { + PORT_Assert(0); + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); return SECFailure; + } + mech = CKM_NSS_TLS_PRF_GENERAL_SHA256; + } + prf_context = PK11_CreateContextBySymKey(mech, CKA_SIGN, + spec->masterSecret, ¶m); + if (!prf_context) + return SECFailure; - rv = PK11_DigestBegin(prf_context); - rv |= PK11_DigestOp(prf_context, (unsigned char *)label, labelLen); - rv |= PK11_DigestOp(prf_context, val, valLen); - rv |= PK11_DigestFinal(prf_context, out, &retLen, outLen); - PORT_Assert(rv != SECSuccess || retLen == outLen); + rv = PK11_DigestBegin(prf_context); + rv |= PK11_DigestOp(prf_context, (unsigned char *)label, labelLen); + rv |= PK11_DigestOp(prf_context, val, valLen); + rv |= PK11_DigestFinal(prf_context, out, &retLen, outLen); + PORT_Assert(rv != SECSuccess || retLen == outLen); - PK11_DestroyContext(prf_context, PR_TRUE); - } else { - PORT_Assert(spec->master_secret); - PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); - rv = SECFailure; - } + PK11_DestroyContext(prf_context, PR_TRUE); return rv; } @@ -11127,7 +10753,7 @@ ssl3_SendNextProto(sslSocket *ss) padding_len = 32 - ((ss->xtnData.nextProto.len + 2) % 32); - rv = ssl3_AppendHandshakeHeader(ss, next_proto, ss->xtnData.nextProto.len + 2 + padding_len); + rv = ssl3_AppendHandshakeHeader(ss, ssl_hs_next_proto, ss->xtnData.nextProto.len + 2 + padding_len); if (rv != SECSuccess) { return rv; /* error code set by AppendHandshakeHeader */ } @@ -11143,40 +10769,44 @@ ssl3_SendNextProto(sslSocket *ss) return rv; } -/* called from ssl3_SendFinished +/* called from ssl3_SendFinished and tls13_DeriveSecret. * * This function is simply a debugging aid and therefore does not return a * SECStatus. */ -static void -ssl3_RecordKeyLog(sslSocket *ss) +void +ssl3_RecordKeyLog(sslSocket *ss, const char *label, PK11SymKey *secret) { #ifdef NSS_ALLOW_SSLKEYLOGFILE SECStatus rv; SECItem *keyData; - char buf[14 /* "CLIENT_RANDOM " */ + - SSL3_RANDOM_LENGTH * 2 /* client_random */ + - 1 /* " " */ + - 48 * 2 /* master secret */ + - 1 /* new line */]; - unsigned int j; + /* Longest label is "CLIENT_HANDSHAKE_TRAFFIC_SECRET", master secret is 48 + * bytes which happens to be the largest in TLS 1.3 as well (SHA384). + * Maximum line length: "CLIENT_HANDSHAKE_TRAFFIC_SECRET" (31) + " " (1) + + * client_random (32*2) + " " (1) + + * traffic_secret (48*2) + "\n" (1) = 194. */ + char buf[200]; + unsigned int offset, len; PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); if (!ssl_keylog_iob) return; - rv = PK11_ExtractKeyValue(ss->ssl3.cwSpec->master_secret); + rv = PK11_ExtractKeyValue(secret); if (rv != SECSuccess) return; - ssl_GetSpecReadLock(ss); - /* keyData does not need to be freed. */ - keyData = PK11_GetKeyData(ss->ssl3.cwSpec->master_secret); - if (!keyData || !keyData->data || keyData->len != 48) { - ssl_ReleaseSpecReadLock(ss); + keyData = PK11_GetKeyData(secret); + if (!keyData || !keyData->data) + return; + + len = strlen(label) + 1 + /* label + space */ + SSL3_RANDOM_LENGTH * 2 + 1 + /* client random (hex) + space */ + keyData->len * 2 + 1; /* secret (hex) + newline */ + PORT_Assert(len <= sizeof(buf)); + if (len > sizeof(buf)) return; - } /* https://developer.mozilla.org/en/NSS_Key_Log_Format */ @@ -11184,23 +10814,22 @@ ssl3_RecordKeyLog(sslSocket *ss) * keylog, so we have to do everything in a single call to * fwrite. */ - memcpy(buf, "CLIENT_RANDOM ", 14); - j = 14; - hexEncode(buf + j, ss->ssl3.hs.client_random.rand, SSL3_RANDOM_LENGTH); - j += SSL3_RANDOM_LENGTH * 2; - buf[j++] = ' '; - hexEncode(buf + j, keyData->data, 48); - j += 48 * 2; - buf[j++] = '\n'; - - PORT_Assert(j == sizeof(buf)); - - ssl_ReleaseSpecReadLock(ss); - - if (fwrite(buf, sizeof(buf), 1, ssl_keylog_iob) != 1) - return; - fflush(ssl_keylog_iob); - return; + strcpy(buf, label); + offset = strlen(label); + buf[offset++] += ' '; + hexEncode(buf + offset, ss->ssl3.hs.client_random, SSL3_RANDOM_LENGTH); + offset += SSL3_RANDOM_LENGTH * 2; + buf[offset++] = ' '; + hexEncode(buf + offset, keyData->data, keyData->len); + offset += keyData->len * 2; + buf[offset++] = '\n'; + + PORT_Assert(offset == len); + + PZ_Lock(ssl_keylog_lock); + if (fwrite(buf, len, 1, ssl_keylog_iob) == 1) + fflush(ssl_keylog_iob); + PZ_Unlock(ssl_keylog_lock); #endif } @@ -11242,7 +10871,7 @@ ssl3_SendFinished(sslSocket *ss, PRInt32 flags) else ss->ssl3.hs.finishedMsgs.tFinished[0] = tlsFinished; ss->ssl3.hs.finishedBytes = sizeof tlsFinished; - rv = ssl3_AppendHandshakeHeader(ss, finished, sizeof tlsFinished); + rv = ssl3_AppendHandshakeHeader(ss, ssl_hs_finished, sizeof tlsFinished); if (rv != SECSuccess) goto fail; /* err set by AppendHandshake. */ rv = ssl3_AppendHandshake(ss, &tlsFinished, sizeof tlsFinished); @@ -11255,7 +10884,7 @@ ssl3_SendFinished(sslSocket *ss, PRInt32 flags) ss->ssl3.hs.finishedMsgs.sFinished[0] = hashes.u.s; PORT_Assert(hashes.len == sizeof hashes.u.s); ss->ssl3.hs.finishedBytes = sizeof hashes.u.s; - rv = ssl3_AppendHandshakeHeader(ss, finished, sizeof hashes.u.s); + rv = ssl3_AppendHandshakeHeader(ss, ssl_hs_finished, sizeof hashes.u.s); if (rv != SECSuccess) goto fail; /* err set by AppendHandshake. */ rv = ssl3_AppendHandshake(ss, &hashes.u.s, sizeof hashes.u.s); @@ -11267,7 +10896,7 @@ ssl3_SendFinished(sslSocket *ss, PRInt32 flags) goto fail; /* error code set by ssl3_FlushHandshake */ } - ssl3_RecordKeyLog(ss); + ssl3_RecordKeyLog(ss, "CLIENT_RANDOM", ss->ssl3.cwSpec->masterSecret); return SECSuccess; @@ -11279,8 +10908,8 @@ fail: * Caller holds the Spec read lock. */ SECStatus -ssl3_CacheWrappedMasterSecret(sslSocket *ss, sslSessionID *sid, - ssl3CipherSpec *spec) +ssl3_CacheWrappedSecret(sslSocket *ss, sslSessionID *sid, + PK11SymKey *secret) { PK11SymKey *wrappingKey = NULL; PK11SlotInfo *symKeySlot; @@ -11289,7 +10918,7 @@ ssl3_CacheWrappedMasterSecret(sslSocket *ss, sslSessionID *sid, PRBool isServer = ss->sec.isServer; CK_MECHANISM_TYPE mechanism = CKM_INVALID_MECHANISM; - symKeySlot = PK11_GetSlotFromKey(spec->master_secret); + symKeySlot = PK11_GetSlotFromKey(secret); if (!isServer) { int wrapKeyIndex; int incarnation; @@ -11350,7 +10979,7 @@ ssl3_CacheWrappedMasterSecret(sslSocket *ss, sslSessionID *sid, wmsItem.data = sid->u.ssl3.keys.wrapped_master_secret; wmsItem.len = sizeof sid->u.ssl3.keys.wrapped_master_secret; rv = PK11_WrapSymKey(mechanism, NULL, wrappingKey, - spec->master_secret, &wmsItem); + secret, &wmsItem); /* rv is examined below. */ sid->u.ssl3.keys.wrapped_master_secret_len = wmsItem.len; PK11_FreeSymKey(wrappingKey); @@ -11363,13 +10992,13 @@ ssl3_CacheWrappedMasterSecret(sslSocket *ss, sslSessionID *sid, * Caller must hold Handshake and RecvBuf locks. */ static SECStatus -ssl3_HandleFinished(sslSocket *ss, PRUint8 *b, PRUint32 length, - const SSL3Hashes *hashes) +ssl3_HandleFinished(sslSocket *ss, PRUint8 *b, PRUint32 length) { sslSessionID *sid = ss->sec.ci.sid; SECStatus rv = SECSuccess; PRBool isServer = ss->sec.isServer; PRBool isTLS; + SSL3Hashes hashes; PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss)); PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); @@ -11383,13 +11012,23 @@ ssl3_HandleFinished(sslSocket *ss, PRUint8 *b, PRUint32 length, return SECFailure; } - if (!hashes) { - PORT_Assert(0); - SSL3_SendAlert(ss, alert_fatal, internal_error); + if (!ss->sec.isServer || !ss->opt.requestCertificate) { + dtls_ReceivedFirstMessageInFlight(ss); + } + + rv = ssl3_ComputeHandshakeHashes(ss, ss->ssl3.crSpec, &hashes, + isServer ? sender_client : sender_server); + if (rv != SECSuccess) { PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); return SECFailure; } + rv = ssl_HashHandshakeMessage(ss, ssl_hs_finished, b, length); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return rv; + } + isTLS = (PRBool)(ss->ssl3.crSpec->version > SSL_LIBRARY_VERSION_3_0); if (isTLS) { TLSFinished tlsFinished; @@ -11402,7 +11041,7 @@ ssl3_HandleFinished(sslSocket *ss, PRUint8 *b, PRUint32 length, #endif } rv = ssl3_ComputeTLSFinished(ss, ss->ssl3.crSpec, !isServer, - hashes, &tlsFinished); + &hashes, &tlsFinished); if (!isServer) ss->ssl3.hs.finishedMsgs.tFinished[1] = tlsFinished; else @@ -11425,12 +11064,12 @@ ssl3_HandleFinished(sslSocket *ss, PRUint8 *b, PRUint32 length, } if (!isServer) - ss->ssl3.hs.finishedMsgs.sFinished[1] = hashes->u.s; + ss->ssl3.hs.finishedMsgs.sFinished[1] = hashes.u.s; else - ss->ssl3.hs.finishedMsgs.sFinished[0] = hashes->u.s; - PORT_Assert(hashes->len == sizeof hashes->u.s); - ss->ssl3.hs.finishedBytes = sizeof hashes->u.s; - if (0 != NSS_SecureMemcmp(&hashes->u.s, b, length)) { + ss->ssl3.hs.finishedMsgs.sFinished[0] = hashes.u.s; + PORT_Assert(hashes.len == sizeof hashes.u.s); + ss->ssl3.hs.finishedBytes = sizeof hashes.u.s; + if (0 != NSS_SecureMemcmp(&hashes.u.s, b, length)) { (void)ssl3_HandshakeFailure(ss); PORT_SetError(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE); return SECFailure; @@ -11500,7 +11139,7 @@ xmit_loser: } if (sid->cached == never_cached && !ss->opt.noCache) { - rv = ssl3_FillInCachedSID(ss, sid); + rv = ssl3_FillInCachedSID(ss, sid, ss->ssl3.crSpec->masterSecret); /* If the wrap failed, we don't cache the sid. * The connection continues normally however. @@ -11524,21 +11163,26 @@ xmit_loser: } SECStatus -ssl3_FillInCachedSID(sslSocket *ss, sslSessionID *sid) +ssl3_FillInCachedSID(sslSocket *ss, sslSessionID *sid, PK11SymKey *secret) { - SECStatus rv; + PORT_Assert(secret); /* fill in the sid */ sid->u.ssl3.cipherSuite = ss->ssl3.hs.cipher_suite; - sid->u.ssl3.compression = ss->ssl3.hs.compression; sid->u.ssl3.policy = ss->ssl3.policy; sid->version = ss->version; sid->authType = ss->sec.authType; sid->authKeyBits = ss->sec.authKeyBits; sid->keaType = ss->sec.keaType; sid->keaKeyBits = ss->sec.keaKeyBits; - sid->lastAccessTime = sid->creationTime = ssl_Time(); - sid->expirationTime = sid->creationTime + ssl3_sid_timeout; + if (ss->sec.keaGroup) { + sid->keaGroup = ss->sec.keaGroup->name; + } else { + sid->keaGroup = ssl_grp_none; + } + sid->sigScheme = ss->sec.signatureScheme; + sid->lastAccessTime = sid->creationTime = ssl_TimeUsec(); + sid->expirationTime = sid->creationTime + ssl3_sid_timeout * PR_USEC_PER_SEC; sid->localCert = CERT_DupCertificate(ss->sec.localCert); if (ss->sec.isServer) { sid->namedCurve = ss->sec.serverCert->namedCurve; @@ -11546,31 +11190,15 @@ ssl3_FillInCachedSID(sslSocket *ss, sslSessionID *sid) if (ss->xtnData.nextProtoState != SSL_NEXT_PROTO_NO_SUPPORT && ss->xtnData.nextProto.data) { + SECITEM_FreeItem(&sid->u.ssl3.alpnSelection, PR_FALSE); if (SECITEM_CopyItem( NULL, &sid->u.ssl3.alpnSelection, &ss->xtnData.nextProto) != SECSuccess) { return SECFailure; /* error already set. */ } } - ssl_GetSpecReadLock(ss); /*************************************/ - /* Copy the master secret (wrapped or unwrapped) into the sid */ - if (ss->ssl3.crSpec->msItem.len && ss->ssl3.crSpec->msItem.data) { - sid->u.ssl3.keys.wrapped_master_secret_len = - ss->ssl3.crSpec->msItem.len; - memcpy(sid->u.ssl3.keys.wrapped_master_secret, - ss->ssl3.crSpec->msItem.data, ss->ssl3.crSpec->msItem.len); - sid->u.ssl3.masterValid = PR_TRUE; - sid->u.ssl3.keys.msIsWrapped = PR_FALSE; - rv = SECSuccess; - } else { - rv = ssl3_CacheWrappedMasterSecret(ss, ss->sec.ci.sid, - ss->ssl3.crSpec); - sid->u.ssl3.keys.msIsWrapped = PR_TRUE; - } - ssl_ReleaseSpecReadLock(ss); /*************************************/ - - return rv; + return ssl3_CacheWrappedSecret(ss, ss->sec.ci.sid, secret); } /* The return type is SECStatus instead of void because this function needs @@ -11592,7 +11220,7 @@ ssl3_FinishHandshake(sslSocket *ss) * the handshake is finished (we have verified the server's Finished * AND the server's certificate) before we update the ticket in the sid. * - * This must be done before we call ss->sec.cache(ss->sec.ci.sid) + * This must be done before we call ssl_CacheSessionID(ss) * because CacheSID requires the session ticket to already be set, and also * because of the lazy lock creation scheme used by CacheSID and * ssl3_SetSIDSessionTicket. @@ -11607,7 +11235,7 @@ ssl3_FinishHandshake(sslSocket *ss) if (ss->ssl3.hs.cacheSID) { PORT_Assert(ss->sec.ci.sid->cached == never_cached); - ss->sec.cache(ss->sec.ci.sid); + ssl_CacheSessionID(ss); ss->ssl3.hs.cacheSID = PR_FALSE; } @@ -11619,8 +11247,66 @@ ssl3_FinishHandshake(sslSocket *ss) return SECSuccess; } +SECStatus +ssl_HashHandshakeMessageInt(sslSocket *ss, SSLHandshakeType type, + PRUint32 dtlsSeq, + const PRUint8 *b, PRUint32 length) +{ + PRUint8 hdr[4]; + PRUint8 dtlsData[8]; + SECStatus rv; + + PRINT_BUF(50, (ss, "Hash handshake message:", b, length)); + + hdr[0] = (PRUint8)type; + hdr[1] = (PRUint8)(length >> 16); + hdr[2] = (PRUint8)(length >> 8); + hdr[3] = (PRUint8)(length); + + rv = ssl3_UpdateHandshakeHashes(ss, (unsigned char *)hdr, 4); + if (rv != SECSuccess) + return rv; /* err code already set. */ + + /* Extra data to simulate a complete DTLS handshake fragment */ + if (IS_DTLS(ss)) { + /* Sequence number */ + dtlsData[0] = MSB(dtlsSeq); + dtlsData[1] = LSB(dtlsSeq); + + /* Fragment offset */ + dtlsData[2] = 0; + dtlsData[3] = 0; + dtlsData[4] = 0; + + /* Fragment length */ + dtlsData[5] = (PRUint8)(length >> 16); + dtlsData[6] = (PRUint8)(length >> 8); + dtlsData[7] = (PRUint8)(length); + + rv = ssl3_UpdateHandshakeHashes(ss, (unsigned char *)dtlsData, + sizeof(dtlsData)); + if (rv != SECSuccess) + return rv; /* err code already set. */ + } + + /* The message body */ + rv = ssl3_UpdateHandshakeHashes(ss, b, length); + if (rv != SECSuccess) + return rv; /* err code already set. */ + + return SECSuccess; +} + +SECStatus +ssl_HashHandshakeMessage(sslSocket *ss, SSLHandshakeType type, + const PRUint8 *b, PRUint32 length) +{ + return ssl_HashHandshakeMessageInt(ss, type, ss->ssl3.hs.recvMessageSeq, + b, length); +} + /* Called from ssl3_HandleHandshake() when it has gathered a complete ssl3 - * hanshake message. + * handshake message. * Caller must hold Handshake and RecvBuf locks. */ SECStatus @@ -11628,130 +11314,43 @@ ssl3_HandleHandshakeMessage(sslSocket *ss, PRUint8 *b, PRUint32 length, PRBool endOfRecord) { SECStatus rv = SECSuccess; - SSL3HandshakeType type = ss->ssl3.hs.msg_type; - SSL3Hashes hashes; /* computed hashes are put here. */ - SSL3Hashes *hashesPtr = NULL; /* Set when hashes are computed */ - PRUint8 hdr[4]; - PRUint8 dtlsData[8]; - PRBool computeHashes = PR_FALSE; PRUint16 epoch; PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss)); PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); - /* - * We have to compute the hashes before we update them with the - * current message. - */ - if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) { - if ((type == finished) && (ss->ssl3.hs.ws == wait_finished)) { - computeHashes = PR_TRUE; - } else if ((type == certificate_verify) && (ss->ssl3.hs.ws == wait_cert_verify)) { - if (ss->ssl3.hs.hashType == handshake_hash_record) { - /* We cannot compute the hash yet. We must wait until we have - * decoded the certificate_verify message in - * ssl3_HandleCertificateVerify, which will tell us which - * hash function we must use. - * - * (ssl3_HandleCertificateVerify cannot simply look at the - * buffer length itself, because at the time we reach it, - * additional handshake messages will have been added to the - * buffer, e.g. the certificate_verify message itself.) - * - * Therefore, we use SSL3Hashes.u.transcriptLen to save how much - * data there is and read directly from ss->ssl3.hs.messages - * when calculating the hashes. - * - * ssl3_HandleCertificateVerify will detect - * hashType == handshake_hash_record - * and use that information to calculate the hash. - */ - hashes.u.transcriptLen = ss->ssl3.hs.messages.len; - hashesPtr = &hashes; - } else { - computeHashes = PR_TRUE; - } - } - } else { - if (type == certificate_verify) { - computeHashes = TLS13_IN_HS_STATE(ss, wait_cert_verify); - } else if (type == finished) { - computeHashes = - TLS13_IN_HS_STATE(ss, wait_cert_request, wait_finished); - } - } - - ssl_GetSpecReadLock(ss); /************************************/ - if (computeHashes) { - SSL3Sender sender = (SSL3Sender)0; - ssl3CipherSpec *rSpec = ss->version >= SSL_LIBRARY_VERSION_TLS_1_3 ? ss->ssl3.crSpec - : ss->ssl3.prSpec; - if (type == finished) { - sender = ss->sec.isServer ? sender_client : sender_server; - rSpec = ss->ssl3.crSpec; - } - rv = ssl3_ComputeHandshakeHashes(ss, rSpec, &hashes, sender); - if (rv == SECSuccess) { - hashesPtr = &hashes; - } - } - ssl_ReleaseSpecReadLock(ss); /************************************/ - if (rv != SECSuccess) { - return rv; /* error code was set by ssl3_ComputeHandshakeHashes*/ - } SSL_TRC(30, ("%d: SSL3[%d]: handle handshake message: %s", SSL_GETPID(), ss->fd, ssl3_DecodeHandshakeType(ss->ssl3.hs.msg_type))); - hdr[0] = (PRUint8)ss->ssl3.hs.msg_type; - hdr[1] = (PRUint8)(length >> 16); - hdr[2] = (PRUint8)(length >> 8); - hdr[3] = (PRUint8)(length); - - /* Start new handshake hashes when we start a new handshake. Unless this is - * TLS 1.3 and we sent a HelloRetryRequest. */ - if (ss->ssl3.hs.msg_type == client_hello && !ss->ssl3.hs.helloRetry) { + /* Start new handshake hashes when we start a new handshake. */ + if (ss->ssl3.hs.msg_type == ssl_hs_client_hello) { ssl3_RestartHandshakeHashes(ss); } - /* We should not include hello_request and hello_verify_request messages - * in the handshake hashes */ - if ((ss->ssl3.hs.msg_type != hello_request) && - (ss->ssl3.hs.msg_type != hello_verify_request)) { - rv = ssl3_UpdateHandshakeHashes(ss, (unsigned char *)hdr, 4); - if (rv != SECSuccess) - return rv; /* err code already set. */ - - /* Extra data to simulate a complete DTLS handshake fragment */ - if (IS_DTLS(ss)) { - /* Sequence number */ - dtlsData[0] = MSB(ss->ssl3.hs.recvMessageSeq); - dtlsData[1] = LSB(ss->ssl3.hs.recvMessageSeq); - - /* Fragment offset */ - dtlsData[2] = 0; - dtlsData[3] = 0; - dtlsData[4] = 0; - - /* Fragment length */ - dtlsData[5] = (PRUint8)(length >> 16); - dtlsData[6] = (PRUint8)(length >> 8); - dtlsData[7] = (PRUint8)(length); + switch (ss->ssl3.hs.msg_type) { + case ssl_hs_hello_request: + case ssl_hs_hello_verify_request: + /* We don't include hello_request and hello_verify_request messages + * in the handshake hashes */ + break; - rv = ssl3_UpdateHandshakeHashes(ss, (unsigned char *)dtlsData, - sizeof(dtlsData)); - if (rv != SECSuccess) - return rv; /* err code already set. */ - } + /* Defer hashing of these messages until the message handlers. */ + case ssl_hs_client_hello: + case ssl_hs_server_hello: + case ssl_hs_certificate_verify: + case ssl_hs_finished: + break; - /* The message body */ - rv = ssl3_UpdateHandshakeHashes(ss, b, length); - if (rv != SECSuccess) - return rv; /* err code already set. */ + default: + rv = ssl_HashHandshakeMessage(ss, ss->ssl3.hs.msg_type, b, length); + if (rv != SECSuccess) { + return SECFailure; + } } PORT_SetError(0); /* each message starts with no error. */ if (ss->ssl3.hs.ws == wait_certificate_status && - ss->ssl3.hs.msg_type != certificate_status) { + ss->ssl3.hs.msg_type != ssl_hs_certificate_status) { /* If we negotiated the certificate_status extension then we deferred * certificate validation until we get the CertificateStatus messsage. * But the CertificateStatus message is optional. If the server did @@ -11768,7 +11367,7 @@ ssl3_HandleHandshakeMessage(sslSocket *ss, PRUint8 *b, PRUint32 length, epoch = ss->ssl3.crSpec->epoch; switch (ss->ssl3.hs.msg_type) { - case client_hello: + case ssl_hs_client_hello: if (!ss->sec.isServer) { (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message); PORT_SetError(SSL_ERROR_RX_UNEXPECTED_CLIENT_HELLO); @@ -11776,7 +11375,7 @@ ssl3_HandleHandshakeMessage(sslSocket *ss, PRUint8 *b, PRUint32 length, } rv = ssl3_HandleClientHello(ss, b, length); break; - case server_hello: + case ssl_hs_server_hello: if (ss->sec.isServer) { (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message); PORT_SetError(SSL_ERROR_RX_UNEXPECTED_SERVER_HELLO); @@ -11786,10 +11385,9 @@ ssl3_HandleHandshakeMessage(sslSocket *ss, PRUint8 *b, PRUint32 length, break; default: if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) { - rv = ssl3_HandlePostHelloHandshakeMessage(ss, b, length, hashesPtr); + rv = ssl3_HandlePostHelloHandshakeMessage(ss, b, length); } else { - rv = tls13_HandlePostHelloHandshakeMessage(ss, b, length, - hashesPtr); + rv = tls13_HandlePostHelloHandshakeMessage(ss, b, length); } break; } @@ -11811,13 +11409,13 @@ ssl3_HandleHandshakeMessage(sslSocket *ss, PRUint8 *b, PRUint32 length, static SECStatus ssl3_HandlePostHelloHandshakeMessage(sslSocket *ss, PRUint8 *b, - PRUint32 length, SSL3Hashes *hashesPtr) + PRUint32 length) { SECStatus rv; PORT_Assert(ss->version < SSL_LIBRARY_VERSION_TLS_1_3); switch (ss->ssl3.hs.msg_type) { - case hello_request: + case ssl_hs_hello_request: if (length != 0) { (void)ssl3_DecodeError(ss); PORT_SetError(SSL_ERROR_RX_MALFORMED_HELLO_REQUEST); @@ -11831,13 +11429,7 @@ ssl3_HandlePostHelloHandshakeMessage(sslSocket *ss, PRUint8 *b, rv = ssl3_HandleHelloRequest(ss); break; - case hello_retry_request: - /* This arrives here because - as a client - we haven't received a - * final decision on the version from the server. */ - rv = tls13_HandleHelloRetryRequest(ss, b, length); - break; - - case hello_verify_request: + case ssl_hs_hello_verify_request: if (!IS_DTLS(ss) || ss->sec.isServer) { (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message); PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HELLO_VERIFY_REQUEST); @@ -11845,13 +11437,13 @@ ssl3_HandlePostHelloHandshakeMessage(sslSocket *ss, PRUint8 *b, } rv = dtls_HandleHelloVerifyRequest(ss, b, length); break; - case certificate: + case ssl_hs_certificate: rv = ssl3_HandleCertificate(ss, b, length); break; - case certificate_status: + case ssl_hs_certificate_status: rv = ssl3_HandleCertificateStatus(ss, b, length); break; - case server_key_exchange: + case ssl_hs_server_key_exchange: if (ss->sec.isServer) { (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message); PORT_SetError(SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH); @@ -11859,7 +11451,7 @@ ssl3_HandlePostHelloHandshakeMessage(sslSocket *ss, PRUint8 *b, } rv = ssl3_HandleServerKeyExchange(ss, b, length); break; - case certificate_request: + case ssl_hs_certificate_request: if (ss->sec.isServer) { (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message); PORT_SetError(SSL_ERROR_RX_UNEXPECTED_CERT_REQUEST); @@ -11867,7 +11459,7 @@ ssl3_HandlePostHelloHandshakeMessage(sslSocket *ss, PRUint8 *b, } rv = ssl3_HandleCertificateRequest(ss, b, length); break; - case server_hello_done: + case ssl_hs_server_hello_done: if (length != 0) { (void)ssl3_DecodeError(ss); PORT_SetError(SSL_ERROR_RX_MALFORMED_HELLO_DONE); @@ -11880,15 +11472,15 @@ ssl3_HandlePostHelloHandshakeMessage(sslSocket *ss, PRUint8 *b, } rv = ssl3_HandleServerHelloDone(ss); break; - case certificate_verify: + case ssl_hs_certificate_verify: if (!ss->sec.isServer) { (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message); PORT_SetError(SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY); return SECFailure; } - rv = ssl3_HandleCertificateVerify(ss, b, length, hashesPtr); + rv = ssl3_HandleCertificateVerify(ss, b, length); break; - case client_key_exchange: + case ssl_hs_client_key_exchange: if (!ss->sec.isServer) { (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message); PORT_SetError(SSL_ERROR_RX_UNEXPECTED_CLIENT_KEY_EXCH); @@ -11896,7 +11488,7 @@ ssl3_HandlePostHelloHandshakeMessage(sslSocket *ss, PRUint8 *b, } rv = ssl3_HandleClientKeyExchange(ss, b, length); break; - case new_session_ticket: + case ssl_hs_new_session_ticket: if (ss->sec.isServer) { (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message); PORT_SetError(SSL_ERROR_RX_UNEXPECTED_NEW_SESSION_TICKET); @@ -11904,8 +11496,8 @@ ssl3_HandlePostHelloHandshakeMessage(sslSocket *ss, PRUint8 *b, } rv = ssl3_HandleNewSessionTicket(ss, b, length); break; - case finished: - rv = ssl3_HandleFinished(ss, b, length, hashesPtr); + case ssl_hs_finished: + rv = ssl3_HandleFinished(ss, b, length); break; default: (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message); @@ -11946,7 +11538,7 @@ ssl3_HandleHandshake(sslSocket *ss, sslBuffer *origBuf) t = *(buf->buf++); buf->len--; if (ss->ssl3.hs.header_bytes++ == 0) - ss->ssl3.hs.msg_type = (SSL3HandshakeType)t; + ss->ssl3.hs.msg_type = (SSLHandshakeType)t; else ss->ssl3.hs.msg_len = (ss->ssl3.hs.msg_len << 8) + t; if (ss->ssl3.hs.header_bytes < 4) @@ -12276,31 +11868,34 @@ ssl_CBCExtractMAC(sslBuffer *plaintext, * */ static SECStatus -ssl3_UnprotectRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *plaintext, +ssl3_UnprotectRecord(sslSocket *ss, + ssl3CipherSpec *spec, + SSL3Ciphertext *cText, sslBuffer *plaintext, SSL3AlertDescription *alert) { - ssl3CipherSpec *crSpec = ss->ssl3.crSpec; - const ssl3BulkCipherDef *cipher_def = crSpec->cipher_def; + const ssl3BulkCipherDef *cipher_def = spec->cipherDef; PRBool isTLS; unsigned int good; unsigned int ivLen = 0; SSL3ContentType rType; unsigned int minLength; unsigned int originalLen = 0; - unsigned char header[13]; - unsigned int headerLen; + PRUint8 headerBuf[13]; + sslBuffer header = SSL_BUFFER(headerBuf); PRUint8 hash[MAX_MAC_LENGTH]; PRUint8 givenHashBuf[MAX_MAC_LENGTH]; PRUint8 *givenHash; unsigned int hashBytes = MAX_MAC_LENGTH + 1; SECStatus rv; + PORT_Assert(spec->direction == CipherSpecRead); + good = ~0U; - minLength = crSpec->mac_size; + minLength = spec->macDef->mac_size; if (cipher_def->type == type_block) { /* CBC records have a padding length byte at the end. */ minLength++; - if (crSpec->version >= SSL_LIBRARY_VERSION_TLS_1_1) { + if (spec->version >= SSL_LIBRARY_VERSION_TLS_1_1) { /* With >= TLS 1.1, CBC records have an explicit IV. */ minLength += cipher_def->iv_size; } @@ -12315,7 +11910,7 @@ ssl3_UnprotectRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *plaintext, } if (cipher_def->type == type_block && - crSpec->version >= SSL_LIBRARY_VERSION_TLS_1_1) { + spec->version >= SSL_LIBRARY_VERSION_TLS_1_1) { /* Consume the per-record explicit IV. RFC 4346 Section 6.2.3.2 states * "The receiver decrypts the entire GenericBlockCipher structure and * then discards the first cipher block corresponding to the IV @@ -12338,8 +11933,8 @@ ssl3_UnprotectRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *plaintext, * the block it doesn't matter. The decryption of the next block * depends only on the ciphertext of the IV block. */ - rv = crSpec->decode(crSpec->decodeContext, iv, &decoded, - sizeof(iv), cText->buf->buf, ivLen); + rv = spec->cipher(spec->cipherContext, iv, &decoded, + sizeof(iv), cText->buf->buf, ivLen); good &= SECStatusToMask(rv); } @@ -12347,7 +11942,7 @@ ssl3_UnprotectRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *plaintext, PRINT_BUF(80, (ss, "ciphertext:", cText->buf->buf + ivLen, cText->buf->len - ivLen)); - isTLS = (PRBool)(crSpec->version > SSL_LIBRARY_VERSION_3_0); + isTLS = (PRBool)(spec->version > SSL_LIBRARY_VERSION_3_0); if (isTLS && cText->buf->len - ivLen > (MAX_FRAGMENT_LENGTH + 2048)) { *alert = record_overflow; @@ -12364,19 +11959,18 @@ ssl3_UnprotectRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *plaintext, unsigned int decryptedLen = cText->buf->len - cipher_def->explicit_nonce_size - cipher_def->tag_size; - headerLen = ssl3_BuildRecordPseudoHeader( - header, IS_DTLS(ss) ? cText->seq_num : crSpec->read_seq_num, - rType, isTLS, cText->version, IS_DTLS(ss), decryptedLen); - PORT_Assert(headerLen <= sizeof(header)); - rv = crSpec->aead( - ss->sec.isServer ? &crSpec->client : &crSpec->server, - PR_TRUE, /* do decrypt */ - plaintext->buf, /* out */ - (int *)&plaintext->len, /* outlen */ - plaintext->space, /* maxout */ - cText->buf->buf, /* in */ - cText->buf->len, /* inlen */ - header, headerLen); + rv = ssl3_BuildRecordPseudoHeader( + spec->epoch, IS_DTLS(ss) ? cText->seq_num : spec->seqNum, + rType, isTLS, cText->version, IS_DTLS(ss), decryptedLen, &header); + PORT_Assert(rv == SECSuccess); + rv = spec->aead(&spec->keyMaterial, + PR_TRUE, /* do decrypt */ + plaintext->buf, /* out */ + (int *)&plaintext->len, /* outlen */ + plaintext->space, /* maxout */ + cText->buf->buf, /* in */ + cText->buf->len, /* inlen */ + SSL_BUFFER_BASE(&header), SSL_BUFFER_LEN(&header)); if (rv != SECSuccess) { good = 0; } @@ -12387,8 +11981,8 @@ ssl3_UnprotectRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *plaintext, } /* decrypt from cText buf to plaintext. */ - rv = crSpec->decode( - crSpec->decodeContext, plaintext->buf, (int *)&plaintext->len, + rv = spec->cipher( + spec->cipherContext, plaintext->buf, (int *)&plaintext->len, plaintext->space, cText->buf->buf + ivLen, cText->buf->len - ivLen); if (rv != SECSuccess) { goto decrypt_loser; @@ -12401,7 +11995,7 @@ ssl3_UnprotectRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *plaintext, /* If it's a block cipher, check and strip the padding. */ if (cipher_def->type == type_block) { const unsigned int blockSize = cipher_def->block_size; - const unsigned int macSize = crSpec->mac_size; + const unsigned int macSize = spec->macDef->mac_size; if (!isTLS) { good &= SECStatusToMask(ssl_RemoveSSLv3CBCPadding( @@ -12413,32 +12007,32 @@ ssl3_UnprotectRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *plaintext, } /* compute the MAC */ - headerLen = ssl3_BuildRecordPseudoHeader( - header, IS_DTLS(ss) ? cText->seq_num : crSpec->read_seq_num, + rv = ssl3_BuildRecordPseudoHeader( + spec->epoch, IS_DTLS(ss) ? cText->seq_num : spec->seqNum, rType, isTLS, cText->version, IS_DTLS(ss), - plaintext->len - crSpec->mac_size); - PORT_Assert(headerLen <= sizeof(header)); + plaintext->len - spec->macDef->mac_size, &header); + PORT_Assert(rv == SECSuccess); if (cipher_def->type == type_block) { rv = ssl3_ComputeRecordMACConstantTime( - crSpec, (PRBool)(!ss->sec.isServer), header, headerLen, + spec, SSL_BUFFER_BASE(&header), SSL_BUFFER_LEN(&header), plaintext->buf, plaintext->len, originalLen, hash, &hashBytes); ssl_CBCExtractMAC(plaintext, originalLen, givenHashBuf, - crSpec->mac_size); + spec->macDef->mac_size); givenHash = givenHashBuf; /* plaintext->len will always have enough space to remove the MAC * because in ssl_Remove{SSLv3|TLS}CBCPadding we only adjust * plaintext->len if the result has enough space for the MAC and we * tested the unadjusted size against minLength, above. */ - plaintext->len -= crSpec->mac_size; + plaintext->len -= spec->macDef->mac_size; } else { /* This is safe because we checked the minLength above. */ - plaintext->len -= crSpec->mac_size; + plaintext->len -= spec->macDef->mac_size; rv = ssl3_ComputeRecordMAC( - crSpec, (PRBool)(!ss->sec.isServer), header, headerLen, + spec, SSL_BUFFER_BASE(&header), SSL_BUFFER_LEN(&header), plaintext->buf, plaintext->len, hash, &hashBytes); /* We can read the MAC directly from the record because its location @@ -12448,8 +12042,8 @@ ssl3_UnprotectRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *plaintext, good &= SECStatusToMask(rv); - if (hashBytes != (unsigned)crSpec->mac_size || - NSS_SecureMemcmp(givenHash, hash, crSpec->mac_size) != 0) { + if (hashBytes != (unsigned)spec->macDef->mac_size || + NSS_SecureMemcmp(givenHash, hash, spec->macDef->mac_size) != 0) { /* We're allowed to leak whether or not the MAC check was correct */ good = 0; } @@ -12465,7 +12059,84 @@ ssl3_UnprotectRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *plaintext, return SECSuccess; } -/* if cText is non-null, then decipher, check MAC, and decompress the +static SECStatus +ssl3_HandleNonApplicationData(sslSocket *ss, SSL3ContentType rType, + DTLSEpoch epoch, sslSequenceNumber seqNum, + sslBuffer *databuf) +{ + SECStatus rv; + + ssl_GetSSL3HandshakeLock(ss); + + /* All the functions called in this switch MUST set error code if + ** they return SECFailure or SECWouldBlock. + */ + switch (rType) { + case content_change_cipher_spec: + rv = ssl3_HandleChangeCipherSpecs(ss, databuf); + break; + case content_alert: + rv = ssl3_HandleAlert(ss, databuf); + break; + case content_handshake: + if (!IS_DTLS(ss)) { + rv = ssl3_HandleHandshake(ss, databuf); + } else { + rv = dtls_HandleHandshake(ss, epoch, seqNum, databuf); + } + break; + case content_ack: + if (IS_DTLS(ss) && tls13_MaybeTls13(ss)) { + rv = dtls13_HandleAck(ss, databuf); + break; + } + /* Fall through. */ + default: + SSL_DBG(("%d: SSL3[%d]: bogus content type=%d", + SSL_GETPID(), ss->fd, rType)); + PORT_SetError(SSL_ERROR_RX_UNKNOWN_RECORD_TYPE); + ssl3_DecodeError(ss); + rv = SECFailure; + break; + } + + ssl_ReleaseSSL3HandshakeLock(ss); + return rv; +} + +/* Find the cipher spec to use for a given record. For TLS, this + * is the current cipherspec. For DTLS, we look up by epoch. + * In DTLS < 1.3 this just means the current epoch or nothing, + * but in DTLS >= 1.3, we keep multiple reading cipherspecs. + * Returns NULL if no appropriate cipher spec is found. + */ +static ssl3CipherSpec * +ssl3_GetCipherSpec(sslSocket *ss, sslSequenceNumber seq) +{ + ssl3CipherSpec *crSpec = ss->ssl3.crSpec; + ssl3CipherSpec *newSpec = NULL; + DTLSEpoch epoch = seq >> 48; + + if (!IS_DTLS(ss)) { + return crSpec; + } + if (crSpec->epoch == epoch) { + return crSpec; + } + if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) { + /* Try to find the cipher spec. */ + newSpec = ssl_FindCipherSpecByEpoch(ss, CipherSpecRead, + epoch); + if (newSpec != NULL) { + return newSpec; + } + } + SSL_TRC(10, ("%d: DTLS[%d]: Couldn't find cipherspec from epoch %d", + SSL_GETPID(), ss->fd, epoch)); + return NULL; +} + +/* 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 * is lost. Then handle databuf according to its SSL record type, @@ -12475,8 +12146,8 @@ ssl3_UnprotectRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *plaintext, * checked, and is already sitting in databuf. It is processed as an SSL * Handshake message. * - * DOES NOT process the decrypted/decompressed application data. - * On return, databuf contains the decrypted/decompressed record. + * DOES NOT process the decrypted application data. + * On return, databuf contains the decrypted record. * * Called from ssl3_GatherCompleteHandshake * ssl3_RestartHandshakeAfterCertReq @@ -12492,20 +12163,15 @@ ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *databuf) { SECStatus rv; PRBool isTLS; - sslSequenceNumber seq_num = 0; - ssl3CipherSpec *crSpec; + DTLSEpoch epoch; + sslSequenceNumber seqNum = 0; + ssl3CipherSpec *spec = NULL; + PRBool outOfOrderSpec = PR_FALSE; SSL3ContentType rType; sslBuffer *plaintext; - sslBuffer temp_buf = { NULL, 0, 0 }; SSL3AlertDescription alert = internal_error; PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss)); - if (!ss->ssl3.initialized) { - ssl_GetSSL3HandshakeLock(ss); - ssl3_InitState(ss); - ssl_ReleaseSSL3HandshakeLock(ss); - } - /* check for Token Presence */ if (!ssl3_ClientAuthTokenPresent(ss->sec.ci.sid)) { PORT_SetError(SSL_ERROR_TOKEN_INSERTION_REMOVAL); @@ -12519,41 +12185,48 @@ ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *databuf) if (cText == NULL) { SSL_DBG(("%d: SSL3[%d]: HandleRecord, resuming handshake", SSL_GETPID(), ss->fd)); - rType = content_handshake; - goto process_it; + /* 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); } ssl_GetSpecReadLock(ss); /******************************************/ - crSpec = ss->ssl3.crSpec; - isTLS = (PRBool)(crSpec->version > SSL_LIBRARY_VERSION_3_0); - + spec = ssl3_GetCipherSpec(ss, cText->seq_num); + 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) { + PORT_Assert(IS_DTLS(ss)); + SSL_TRC(3, ("%d: DTLS[%d]: Handling out-of-epoch record from epoch=%d", + SSL_GETPID(), ss->fd, spec->epoch)); + outOfOrderSpec = PR_TRUE; + } + isTLS = (PRBool)(spec->version > SSL_LIBRARY_VERSION_3_0); if (IS_DTLS(ss)) { - PRBool sameEpoch; - if (!dtls_IsRelevant(ss, cText, &sameEpoch, &seq_num)) { + if (!dtls_IsRelevant(ss, spec, cText, &seqNum)) { ssl_ReleaseSpecReadLock(ss); /*****************************/ databuf->len = 0; /* Needed to ensure data not left around */ - /* Maybe retransmit if needed. */ - return dtls_MaybeRetransmitHandshake(ss, cText, sameEpoch); + return SECSuccess; } } else { - seq_num = crSpec->read_seq_num + 1; + seqNum = spec->seqNum + 1; } - if (seq_num >= crSpec->cipher_def->max_records) { + if (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, seq_num)); + SSL_GETPID(), ss->fd, seqNum)); PORT_SetError(SSL_ERROR_TOO_MANY_RECORDS); return SECFailure; } - /* If we will be decompressing the buffer we need to decrypt somewhere - * other than into databuf */ - if (crSpec->decompressor) { - plaintext = &temp_buf; - } else { - plaintext = databuf; - } + plaintext = databuf; plaintext->len = 0; /* filled in by Unprotect call below. */ /* We're waiting for another ClientHello, which will appear unencrypted. @@ -12588,12 +12261,12 @@ ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *databuf) /* 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 (crSpec->version < SSL_LIBRARY_VERSION_TLS_1_3 || - crSpec->cipher_def->calg == ssl_calg_null) { + 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, cText, plaintext, &alert); + rv = ssl3_UnprotectRecord(ss, spec, cText, plaintext, &alert); } else { - rv = tls13_UnprotectRecord(ss, cText, plaintext, &alert); + rv = tls13_UnprotectRecord(ss, spec, cText, plaintext, &alert); } #endif @@ -12602,14 +12275,25 @@ ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *databuf) SSL_DBG(("%d: SSL3[%d]: decryption failed", SSL_GETPID(), ss->fd)); - /* Clear the temp buffer used for decompression upon failure. */ - sslBuffer_Clear(&temp_buf); + /* Ensure that we don't process this data again. */ + databuf->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. */ + if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3 && + cText->type == 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 */ - databuf->len = 0; /* Needed to ensure data not left around */ return SECSuccess; } else { int errCode = PORT_GetError(); @@ -12622,10 +12306,11 @@ ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *databuf) } /* SECSuccess */ - crSpec->read_seq_num = seq_num; + spec->seqNum = PR_MAX(spec->seqNum, seqNum); if (IS_DTLS(ss)) { - dtls_RecordSetRecvd(&crSpec->recvdRecords, seq_num); + dtls_RecordSetRecvd(&spec->recvdRecords, seqNum); } + epoch = spec->epoch; ssl_ReleaseSpecReadLock(ss); /*****************************************/ @@ -12635,70 +12320,16 @@ ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *databuf) rType = cText->type; /* This must go after decryption because TLS 1.3 * has encrypted content types. */ - /* possibly decompress the record. If we aren't using compression then - * plaintext == databuf and so the uncompressed data is already in - * databuf. */ - if (crSpec->decompressor) { - if (databuf->space < plaintext->len + SSL3_COMPRESSION_MAX_EXPANSION) { - rv = sslBuffer_Grow( - databuf, plaintext->len + SSL3_COMPRESSION_MAX_EXPANSION); - if (rv != SECSuccess) { - SSL_DBG(("%d: SSL3[%d]: HandleRecord, tried to get %d bytes", - SSL_GETPID(), ss->fd, - plaintext->len + - SSL3_COMPRESSION_MAX_EXPANSION)); - /* sslBuffer_Grow has set a memory error code. */ - /* Perhaps we should send an alert. (but we have no memory!) */ - sslBuffer_Clear(&temp_buf); - return SECFailure; - } - } - - rv = crSpec->decompressor(crSpec->decompressContext, - databuf->buf, - (int *)&databuf->len, - databuf->space, - plaintext->buf, - plaintext->len); - - if (rv != SECSuccess) { - int err = ssl_MapLowLevelError(SSL_ERROR_DECOMPRESSION_FAILURE); - SSL3_SendAlert(ss, alert_fatal, - isTLS ? decompression_failure - : bad_record_mac); - - /* There appears to be a bug with (at least) Apache + OpenSSL where - * resumed SSLv3 connections don't actually use compression. See - * comments 93-95 of - * https://bugzilla.mozilla.org/show_bug.cgi?id=275744 - * - * So, if we get a decompression error, and the record appears to - * be already uncompressed, then we return a more specific error - * code to hopefully save somebody some debugging time in the - * future. - */ - if (plaintext->len >= 4) { - unsigned int len = ((unsigned int)plaintext->buf[1] << 16) | - ((unsigned int)plaintext->buf[2] << 8) | - (unsigned int)plaintext->buf[3]; - if (len == plaintext->len - 4) { - /* This appears to be uncompressed already */ - err = SSL_ERROR_RX_UNEXPECTED_UNCOMPRESSED_RECORD; - } - } - - sslBuffer_Clear(&temp_buf); - PORT_SetError(err); - return SECFailure; - } - - sslBuffer_Clear(&temp_buf); + /* 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); } - /* - ** Having completed the decompression, check the length again. - */ - if (isTLS && databuf->len > (MAX_FRAGMENT_LENGTH + 1024)) { + /* Check the length of the plaintext. */ + if (isTLS && databuf->len > MAX_FRAGMENT_LENGTH) { SSL3_SendAlert(ss, alert_fatal, record_overflow); PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG); return SECFailure; @@ -12720,45 +12351,7 @@ ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *databuf) return SECFailure; } -/* It's a record that must be handled by ssl itself, not the application. - */ -process_it: - /* XXX Get the xmit lock here. Odds are very high that we'll be xmiting - * data ang getting the xmit lock here prevents deadlocks. - */ - ssl_GetSSL3HandshakeLock(ss); - - /* All the functions called in this switch MUST set error code if - ** they return SECFailure or SECWouldBlock. - */ - switch (rType) { - case content_change_cipher_spec: - rv = ssl3_HandleChangeCipherSpecs(ss, databuf); - break; - case content_alert: - rv = ssl3_HandleAlert(ss, databuf); - break; - case content_handshake: - if (!IS_DTLS(ss)) { - rv = ssl3_HandleHandshake(ss, databuf); - } else { - rv = dtls_HandleHandshake(ss, databuf); - } - break; - /* - case content_application_data is handled before this switch - */ - default: - SSL_DBG(("%d: SSL3[%d]: bogus content type=%d", - SSL_GETPID(), ss->fd, cText->type)); - PORT_SetError(SSL_ERROR_RX_UNKNOWN_RECORD_TYPE); - ssl3_DecodeError(ss); - rv = SECFailure; - break; - } - - ssl_ReleaseSSL3HandshakeLock(ss); - return rv; + return ssl3_HandleNonApplicationData(ss, rType, epoch, seqNum, databuf); } /* @@ -12776,83 +12369,36 @@ ssl_InitSecState(sslSecurityInfo *sec) sec->keaGroup = NULL; } -/* Called from ssl3_InitState, immediately below. */ -/* Caller must hold the SpecWriteLock. */ -void -ssl3_InitCipherSpec(ssl3CipherSpec *spec) -{ - spec->cipher_def = &bulk_cipher_defs[cipher_null]; - PORT_Assert(spec->cipher_def->cipher == cipher_null); - spec->mac_def = &mac_defs[mac_null]; - PORT_Assert(spec->mac_def->mac == mac_null); - spec->encode = Null_Cipher; - spec->decode = Null_Cipher; - spec->compressor = NULL; - spec->decompressor = NULL; - spec->destroyCompressContext = NULL; - spec->destroyDecompressContext = NULL; - spec->mac_size = 0; - spec->master_secret = NULL; - - spec->msItem.data = NULL; - spec->msItem.len = 0; - - spec->client.write_key = NULL; - spec->client.write_mac_key = NULL; - spec->client.write_mac_context = NULL; - - spec->server.write_key = NULL; - spec->server.write_mac_key = NULL; - spec->server.write_mac_context = NULL; - - spec->write_seq_num = 0; - spec->read_seq_num = 0; - spec->epoch = 0; - - spec->refCt = 128; /* Arbitrarily high number to prevent - * non-TLS 1.3 cipherSpecs from being - * GCed. This will be overwritten with - * a valid refCt for TLS 1.3. */ - dtls_InitRecvdRecords(&spec->recvdRecords); -} - -/* Called from: ssl3_SendRecord -** ssl3_SendClientHello() -** ssl3_HandleV2ClientHello() -** ssl3_HandleRecord() -** -** This function should perhaps acquire and release the SpecWriteLock. -*/ -void +SECStatus ssl3_InitState(sslSocket *ss) { - PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); - - if (ss->ssl3.initialized) - return; /* Function should be idempotent */ + SECStatus rv; ss->ssl3.policy = SSL_ALLOWED; ssl_InitSecState(&ss->sec); ssl_GetSpecWriteLock(ss); - ss->ssl3.crSpec = ss->ssl3.cwSpec = &ss->ssl3.specs[0]; - ss->ssl3.prSpec = ss->ssl3.pwSpec = &ss->ssl3.specs[1]; - ssl3_InitCipherSpec(ss->ssl3.crSpec); - ssl3_InitCipherSpec(ss->ssl3.prSpec); - ss->ssl3.crSpec->version = ss->ssl3.prSpec->version = ss->vrange.max; + PR_INIT_CLIST(&ss->ssl3.hs.cipherSpecs); + rv = ssl_SetupNullCipherSpec(ss, CipherSpecRead); + rv |= ssl_SetupNullCipherSpec(ss, CipherSpecWrite); + ss->ssl3.pwSpec = ss->ssl3.prSpec = NULL; ssl_ReleaseSpecWriteLock(ss); + if (rv != SECSuccess) { + /* Rely on ssl_CreateNullCipherSpec() to set error code. */ + return SECFailure; + } ss->ssl3.hs.sendingSCSV = PR_FALSE; ss->ssl3.hs.preliminaryInfo = 0; - ss->ssl3.hs.ws = (ss->sec.isServer) ? wait_client_hello : wait_server_hello; + ss->ssl3.hs.ws = (ss->sec.isServer) ? wait_client_hello : idle_handshake; - ssl3_ResetExtensionData(&ss->xtnData); + ssl3_ResetExtensionData(&ss->xtnData, ss); PR_INIT_CLIST(&ss->ssl3.hs.remoteExtensions); if (IS_DTLS(ss)) { ss->ssl3.hs.sendMessageSeq = 0; ss->ssl3.hs.recvMessageSeq = 0; - ss->ssl3.hs.rtTimeoutMs = DTLS_RETRANSMIT_INITIAL_MS; + ss->ssl3.hs.rtTimer->timeout = DTLS_RETRANSMIT_INITIAL_MS; ss->ssl3.hs.rtRetries = 0; ss->ssl3.hs.recvdHighWater = -1; PR_INIT_CLIST(&ss->ssl3.hs.lastMessageFlight); @@ -12868,8 +12414,6 @@ ssl3_InitState(sslSocket *ss) ss->ssl3.hs.serverHsTrafficSecret = NULL; ss->ssl3.hs.clientTrafficSecret = NULL; ss->ssl3.hs.serverTrafficSecret = NULL; - ss->ssl3.hs.certificateRequest = NULL; - PR_INIT_CLIST(&ss->ssl3.hs.cipherSpecs); PORT_Assert(!ss->ssl3.hs.messages.buf && !ss->ssl3.hs.messages.space); ss->ssl3.hs.messages.buf = NULL; @@ -12881,9 +12425,7 @@ ssl3_InitState(sslSocket *ss) ss->ssl3.hs.zeroRttState = ssl_0rtt_none; - ssl_FilterSupportedGroups(ss); - - ss->ssl3.initialized = PR_TRUE; + return SECSuccess; } /* record the export policy for this cipher suite */ @@ -13137,8 +12679,7 @@ ssl3_RedoHandshake(sslSocket *ss, PRBool flushCache) PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); - if (!ss->firstHsDone || - (ss->ssl3.initialized && (ss->ssl3.hs.ws != idle_handshake))) { + if (!ss->firstHsDone || (ss->ssl3.hs.ws != idle_handshake)) { PORT_SetError(SSL_ERROR_HANDSHAKE_NOT_COMPLETED); return SECFailure; } @@ -13152,9 +12693,14 @@ ssl3_RedoHandshake(sslSocket *ss, PRBool flushCache) PORT_SetError(SSL_ERROR_RENEGOTIATION_NOT_ALLOWED); return SECFailure; } + if (ss->version > ss->vrange.max || ss->version < ss->vrange.min) { + PORT_SetError(SSL_ERROR_UNSUPPORTED_VERSION); + return SECFailure; + } + if (sid && flushCache) { - ss->sec.uncache(sid); /* remove it from whichever cache it's in. */ - ssl_FreeSID(sid); /* dec ref count and free if zero. */ + ssl_UncacheSessionID(ss); /* remove it from whichever cache it's in. */ + ssl_FreeSID(sid); /* dec ref count and free if zero. */ ss->sec.ci.sid = NULL; } @@ -13209,15 +12755,7 @@ ssl3_DestroySSL3Info(sslSocket *ss) SECITEM_FreeItem(&ss->ssl3.hs.newSessionTicket.ticket, PR_FALSE); SECITEM_FreeItem(&ss->ssl3.hs.srvVirtName, PR_FALSE); - - if (ss->ssl3.hs.certificateRequest) { - PORT_FreeArena(ss->ssl3.hs.certificateRequest->arena, PR_FALSE); - ss->ssl3.hs.certificateRequest = NULL; - } - - /* free up the CipherSpecs */ - ssl3_DestroyCipherSpec(&ss->ssl3.specs[0], PR_TRUE /*freeSrvName*/); - ssl3_DestroyCipherSpec(&ss->ssl3.specs[1], PR_TRUE /*freeSrvName*/); + SECITEM_FreeItem(&ss->ssl3.hs.fakeSid, PR_FALSE); /* Destroy the DTLS data */ if (IS_DTLS(ss)) { @@ -13229,10 +12767,10 @@ ssl3_DestroySSL3Info(sslSocket *ss) /* Destroy remote extensions */ ssl3_DestroyRemoteExtensions(&ss->ssl3.hs.remoteExtensions); - ssl3_ResetExtensionData(&ss->xtnData); + ssl3_DestroyExtensionData(&ss->xtnData); - /* Destroy TLS 1.3 cipher specs */ - tls13_DestroyCipherSpecs(&ss->ssl3.hs.cipherSpecs); + /* Destroy cipher specs */ + ssl_DestroyCipherSpecs(&ss->ssl3.hs.cipherSpecs); /* Destroy TLS 1.3 keys */ if (ss->ssl3.hs.currentSecret) @@ -13261,8 +12799,6 @@ ssl3_DestroySSL3Info(sslSocket *ss) ss->ssl3.hs.zeroRttState = ssl_0rtt_none; /* Destroy TLS 1.3 buffered early data. */ tls13_DestroyEarlyData(&ss->ssl3.hs.bufferedEarlyData); - - ss->ssl3.initialized = PR_FALSE; } #define MAP_NULL(x) (((x) != 0) ? (x) : SEC_OID_NULL_CIPHER) @@ -13301,7 +12837,7 @@ ssl3_ApplyNSSPolicy(void) } if (ssl_GetBulkCipherDef(suite)->type != type_aead) { - policyOid = MAP_NULL(mac_defs[suite->mac_alg].oid); + policyOid = MAP_NULL(ssl_GetMacDefByAlg(suite->mac_alg)->oid); rv = NSS_GetAlgorithmPolicy(policyOid, &policy); if (rv == SECSuccess && !(policy & NSS_USE_ALG_IN_SSL)) { ssl_CipherPrefSetDefault(suite->cipher_suite, PR_FALSE); diff --git a/security/nss/lib/ssl/ssl3ecc.c b/security/nss/lib/ssl/ssl3ecc.c index b440b4b02..913a14f63 100644 --- a/security/nss/lib/ssl/ssl3ecc.c +++ b/security/nss/lib/ssl/ssl3ecc.c @@ -111,7 +111,7 @@ ssl_ECPubKey2NamedGroup(const SECKEYPublicKey *pubKey) static SECStatus ssl3_ComputeECDHKeyHash(SSLHashType hashAlg, SECItem ec_params, SECItem server_ecpoint, - SSL3Random *client_rand, SSL3Random *server_rand, + PRUint8 *client_rand, PRUint8 *server_rand, SSL3Hashes *hashes) { PRUint8 *hashBuf; @@ -175,8 +175,8 @@ ssl3_SendECDHClientKeyExchange(sslSocket *ss, SECKEYPublicKey *svrPubKey) PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); - isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0); - isTLS12 = (PRBool)(ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2); + isTLS = (PRBool)(ss->version > SSL_LIBRARY_VERSION_3_0); + isTLS12 = (PRBool)(ss->version >= SSL_LIBRARY_VERSION_TLS_1_2); /* Generate ephemeral EC keypair */ if (svrPubKey->keyType != ecKey) { @@ -219,7 +219,7 @@ ssl3_SendECDHClientKeyExchange(sslSocket *ss, SECKEYPublicKey *svrPubKey) goto loser; } - rv = ssl3_AppendHandshakeHeader(ss, client_key_exchange, + rv = ssl3_AppendHandshakeHeader(ss, ssl_hs_client_key_exchange, pubKey->u.ec.publicValue.len + 1); if (rv != SECSuccess) { goto loser; /* err set by ssl3_AppendHandshake* */ @@ -232,7 +232,7 @@ ssl3_SendECDHClientKeyExchange(sslSocket *ss, SECKEYPublicKey *svrPubKey) goto loser; /* err set by ssl3_AppendHandshake* */ } - rv = ssl3_InitPendingCipherSpec(ss, pms); + rv = ssl3_InitPendingCipherSpecs(ss, pms, PR_TRUE); if (rv != SECSuccess) { ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE); goto loser; @@ -250,19 +250,6 @@ loser: return SECFailure; } -/* This function encodes the key_exchange field in - * the KeyShareEntry structure. */ -SECStatus -tls13_EncodeECDHEKeyShareKEX(const sslSocket *ss, const SECKEYPublicKey *pubKey) -{ - PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); - PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); - PORT_Assert(pubKey->keyType == ecKey); - - return ssl3_ExtAppendHandshake(ss, pubKey->u.ec.publicValue.data, - pubKey->u.ec.publicValue.len); -} - /* ** Called from ssl3_HandleClientKeyExchange() */ @@ -326,7 +313,7 @@ ssl3_HandleECDHClientKeyExchange(sslSocket *ss, PRUint8 *b, return SECFailure; } - rv = ssl3_InitPendingCipherSpec(ss, pms); + rv = ssl3_InitPendingCipherSpecs(ss, pms, PR_TRUE); PK11_FreeSymKey(pms); if (rv != SECSuccess) { /* error code set by ssl3_InitPendingCipherSpec */ @@ -597,8 +584,8 @@ ssl3_HandleECDHServerKeyExchange(sslSocket *ss, PRUint8 *b, PRUint32 length) * check to make sure the hash is signed by right guy */ rv = ssl3_ComputeECDHKeyHash(hashAlg, ec_params, ec_point, - &ss->ssl3.hs.client_random, - &ss->ssl3.hs.server_random, + ss->ssl3.hs.client_random, + ss->ssl3.hs.server_random, &hashes); if (rv != SECSuccess) { @@ -703,7 +690,7 @@ ssl3_SendECDHServerKeyExchange(sslSocket *ss) ec_params.data[2] = keyPair->group->name & 0xff; pubKey = keyPair->keys->pubKey; - if (ss->ssl3.pwSpec->version == SSL_LIBRARY_VERSION_TLS_1_2) { + if (ss->version == SSL_LIBRARY_VERSION_TLS_1_2) { hashAlg = ssl_SignatureSchemeToHashType(ss->ssl3.hs.signatureScheme); } else { /* Use ssl_hash_none to represent the MD5+SHA1 combo. */ @@ -711,15 +698,15 @@ ssl3_SendECDHServerKeyExchange(sslSocket *ss) } rv = ssl3_ComputeECDHKeyHash(hashAlg, ec_params, pubKey->u.ec.publicValue, - &ss->ssl3.hs.client_random, - &ss->ssl3.hs.server_random, + ss->ssl3.hs.client_random, + ss->ssl3.hs.server_random, &hashes); if (rv != SECSuccess) { ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE); goto loser; } - isTLS12 = (PRBool)(ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2); + isTLS12 = (PRBool)(ss->version >= SSL_LIBRARY_VERSION_TLS_1_2); rv = ssl3_SignHashes(ss, &hashes, ss->sec.serverCert->serverKeyPair->privKey, &signed_hash); @@ -731,7 +718,7 @@ ssl3_SendECDHServerKeyExchange(sslSocket *ss) 1 + pubKey->u.ec.publicValue.len + (isTLS12 ? 2 : 0) + 2 + signed_hash.len; - rv = ssl3_AppendHandshakeHeader(ss, server_key_exchange, length); + rv = ssl3_AppendHandshakeHeader(ss, ssl_hs_server_key_exchange, length); if (rv != SECSuccess) { goto loser; /* err set by AppendHandshake. */ } @@ -870,20 +857,16 @@ ssl_IsDHEEnabled(const sslSocket *ss) } /* Send our Supported Groups extension. */ -PRInt32 -ssl_SendSupportedGroupsXtn(const sslSocket *ss, - TLSExtensionData *xtnData, - PRBool append, PRUint32 maxBytes) +SECStatus +ssl_SendSupportedGroupsXtn(const sslSocket *ss, TLSExtensionData *xtnData, + sslBuffer *buf, PRBool *added) { - PRInt32 extension_length; - unsigned char enabledGroups[64]; - unsigned int enabledGroupsLen = 0; unsigned int i; PRBool ec; PRBool ff = PR_FALSE; - - if (!ss) - return 0; + PRBool found = PR_FALSE; + SECStatus rv; + unsigned int lengthOffset; /* We only send FF supported groups if we require DH named groups * or if TLS 1.3 is a possibility. */ @@ -892,13 +875,19 @@ ssl_SendSupportedGroupsXtn(const sslSocket *ss, if (ss->opt.requireDHENamedGroups) { ff = ssl_IsDHEEnabled(ss); } - if (!ec && !ff) - return 0; + if (!ec && !ff) { + return SECSuccess; + } } else { ec = ff = PR_TRUE; } - PORT_Assert(sizeof(enabledGroups) > SSL_NAMED_GROUP_COUNT * 2); + /* Mark the location of the length. */ + rv = sslBuffer_Skip(buf, 2, &lengthOffset); + if (rv != SECSuccess) { + return SECFailure; + } + for (i = 0; i < SSL_NAMED_GROUP_COUNT; ++i) { const sslNamedGroupDef *group = ss->namedGroupPreferences[i]; if (!group) { @@ -911,78 +900,53 @@ ssl_SendSupportedGroupsXtn(const sslSocket *ss, continue; } - if (append) { - (void)ssl_EncodeUintX(group->name, 2, &enabledGroups[enabledGroupsLen]); - } - enabledGroupsLen += 2; - } - - if (enabledGroupsLen == 0) { - return 0; - } - - extension_length = - 2 /* extension type */ + - 2 /* extension length */ + - 2 /* enabled groups length */ + - enabledGroupsLen; - - if (maxBytes < (PRUint32)extension_length) { - return 0; - } - - if (append) { - SECStatus rv; - rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_supported_groups_xtn, 2); - if (rv != SECSuccess) - return -1; - rv = ssl3_ExtAppendHandshakeNumber(ss, extension_length - 4, 2); - if (rv != SECSuccess) - return -1; - rv = ssl3_ExtAppendHandshakeVariable(ss, enabledGroups, - enabledGroupsLen, 2); - if (rv != SECSuccess) - return -1; - if (!ss->sec.isServer) { - xtnData->advertised[xtnData->numAdvertised++] = - ssl_supported_groups_xtn; + found = PR_TRUE; + rv = sslBuffer_AppendNumber(buf, group->name, 2); + if (rv != SECSuccess) { + return SECFailure; } } - return extension_length; + + if (!found) { + /* We added nothing, don't send the extension. */ + return SECSuccess; + } + + rv = sslBuffer_InsertLength(buf, lengthOffset, 2); + if (rv != SECSuccess) { + return SECFailure; + } + + *added = PR_TRUE; + return SECSuccess; } /* Send our "canned" (precompiled) Supported Point Formats extension, * which says that we only support uncompressed points. */ -PRInt32 -ssl3_SendSupportedPointFormatsXtn( - const sslSocket *ss, - TLSExtensionData *xtnData, - PRBool append, - PRUint32 maxBytes) +SECStatus +ssl3_SendSupportedPointFormatsXtn(const sslSocket *ss, TLSExtensionData *xtnData, + sslBuffer *buf, PRBool *added) { - static const PRUint8 ecPtFmt[6] = { - 0, 11, /* Extension type */ - 0, 2, /* octets that follow */ - 1, /* octets that follow */ - 0 /* uncompressed type only */ - }; + SECStatus rv; /* No point in doing this unless we have a socket that supports ECC. * Similarly, no point if we are going to do TLS 1.3 only or we have already * picked TLS 1.3 (server) given that it doesn't use point formats. */ if (!ss || !ssl_IsECCEnabled(ss) || ss->vrange.min >= SSL_LIBRARY_VERSION_TLS_1_3 || - (ss->sec.isServer && ss->version >= SSL_LIBRARY_VERSION_TLS_1_3)) - return 0; - if (append && maxBytes >= (sizeof ecPtFmt)) { - SECStatus rv = ssl3_ExtAppendHandshake(ss, ecPtFmt, (sizeof ecPtFmt)); - if (rv != SECSuccess) - return -1; - if (!ss->sec.isServer) { - xtnData->advertised[xtnData->numAdvertised++] = - ssl_ec_point_formats_xtn; - } + (ss->sec.isServer && ss->version >= SSL_LIBRARY_VERSION_TLS_1_3)) { + return SECSuccess; } - return sizeof(ecPtFmt); + rv = sslBuffer_AppendNumber(buf, 1, 1); /* length */ + if (rv != SECSuccess) { + return SECFailure; + } + rv = sslBuffer_AppendNumber(buf, 0, 1); /* uncompressed type only */ + if (rv != SECSuccess) { + return SECFailure; + } + + *added = PR_TRUE; + return SECSuccess; } diff --git a/security/nss/lib/ssl/ssl3encode.c b/security/nss/lib/ssl/ssl3encode.c deleted file mode 100644 index 960208a0f..000000000 --- a/security/nss/lib/ssl/ssl3encode.c +++ /dev/null @@ -1,85 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is PRIVATE to SSL. - * - * 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 "prnetdb.h" -#include "seccomon.h" -#include "secerr.h" -#include "ssl3encode.h" - -SECStatus -ssl3_AppendToItem(SECItem *item, const unsigned char *buf, PRUint32 bytes) -{ - if (bytes > item->len) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - - PORT_Memcpy(item->data, buf, bytes); - item->data += bytes; - item->len -= bytes; - return SECSuccess; -} - -SECStatus -ssl3_AppendNumberToItem(SECItem *item, PRUint32 num, PRInt32 lenSize) -{ - SECStatus rv; - PRUint8 b[4]; - - ssl_EncodeUintX(num, lenSize, b); - rv = ssl3_AppendToItem(item, &b[0], lenSize); - return rv; -} - -SECStatus -ssl3_ConsumeFromItem(SECItem *item, unsigned char **buf, PRUint32 bytes) -{ - if (bytes > item->len) { - PORT_SetError(SEC_ERROR_BAD_DATA); - return SECFailure; - } - - *buf = item->data; - item->data += bytes; - item->len -= bytes; - return SECSuccess; -} - -SECStatus -ssl3_ConsumeNumberFromItem(SECItem *item, PRUint32 *num, PRUint32 bytes) -{ - int i; - - if (bytes > item->len || bytes > sizeof(*num)) { - PORT_SetError(SEC_ERROR_BAD_DATA); - return SECFailure; - } - - *num = 0; - for (i = 0; i < bytes; i++) { - *num = (*num << 8) + item->data[i]; - } - - item->data += bytes; - item->len -= bytes; - - return SECSuccess; -} - -/* Helper function to encode an unsigned integer into a buffer. */ -PRUint8 * -ssl_EncodeUintX(PRUint64 value, unsigned int bytes, PRUint8 *to) -{ - PRUint64 encoded; - - PORT_Assert(bytes > 0 && bytes <= sizeof(encoded)); - - encoded = PR_htonll(value); - memcpy(to, ((unsigned char *)(&encoded)) + (sizeof(encoded) - bytes), bytes); - return to + bytes; -} diff --git a/security/nss/lib/ssl/ssl3encode.h b/security/nss/lib/ssl/ssl3encode.h deleted file mode 100644 index 3b88f7e7b..000000000 --- a/security/nss/lib/ssl/ssl3encode.h +++ /dev/null @@ -1,26 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is PRIVATE to SSL. - * - * 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 __ssl3encode_h_ -#define __ssl3encode_h_ - -#include "seccomon.h" - -/* All of these functions modify the underlying SECItem, and so should - * be performed on a shallow copy.*/ -SECStatus ssl3_AppendToItem(SECItem *item, - const unsigned char *buf, PRUint32 bytes); -SECStatus ssl3_AppendNumberToItem(SECItem *item, - PRUint32 num, PRInt32 lenSize); -SECStatus ssl3_ConsumeFromItem(SECItem *item, - unsigned char **buf, PRUint32 bytes); -SECStatus ssl3_ConsumeNumberFromItem(SECItem *item, - PRUint32 *num, PRUint32 bytes); -PRUint8 *ssl_EncodeUintX(PRUint64 value, unsigned int bytes, PRUint8 *to); - -#endif diff --git a/security/nss/lib/ssl/ssl3ext.c b/security/nss/lib/ssl/ssl3ext.c index 271084cf7..5a5077998 100644 --- a/security/nss/lib/ssl/ssl3ext.c +++ b/security/nss/lib/ssl/ssl3ext.c @@ -14,8 +14,20 @@ #include "sslimpl.h" #include "sslproto.h" #include "ssl3exthandle.h" +#include "tls13err.h" #include "tls13exthandle.h" +/* Callback function that handles a received extension. */ +typedef SECStatus (*ssl3ExtensionHandlerFunc)(const sslSocket *ss, + TLSExtensionData *xtnData, + SECItem *data); + +/* Row in a table of hello extension handlers. */ +typedef struct { + SSLExtensionType ex_type; + ssl3ExtensionHandlerFunc ex_handler; +} ssl3ExtensionHandler; + /* Table of handlers for received TLS hello extensions, one per extension. * In the second generation, this table will be dynamic, and functions * will be registered here. @@ -31,16 +43,15 @@ static const ssl3ExtensionHandler clientHelloHandlers[] = { { ssl_app_layer_protocol_xtn, &ssl3_ServerHandleAppProtoXtn }, { ssl_use_srtp_xtn, &ssl3_ServerHandleUseSRTPXtn }, { ssl_cert_status_xtn, &ssl3_ServerHandleStatusRequestXtn }, - { ssl_signature_algorithms_xtn, &ssl3_ServerHandleSigAlgsXtn }, + { ssl_signature_algorithms_xtn, &ssl3_HandleSigAlgsXtn }, { ssl_extended_master_secret_xtn, &ssl3_HandleExtendedMasterSecretXtn }, { ssl_signed_cert_timestamp_xtn, &ssl3_ServerHandleSignedCertTimestampXtn }, { ssl_tls13_key_share_xtn, &tls13_ServerHandleKeyShareXtn }, { ssl_tls13_pre_shared_key_xtn, &tls13_ServerHandlePreSharedKeyXtn }, { ssl_tls13_early_data_xtn, &tls13_ServerHandleEarlyDataXtn }, - { ssl_tls13_psk_key_exchange_modes_xtn, - &tls13_ServerHandlePskKeyExchangeModesXtn }, - { ssl_tls13_short_header_xtn, &tls13_HandleShortHeaderXtn }, - { -1, NULL } + { ssl_tls13_psk_key_exchange_modes_xtn, &tls13_ServerHandlePskModesXtn }, + { ssl_tls13_cookie_xtn, &tls13_ServerHandleCookieXtn }, + { 0, NULL } }; /* These two tables are used by the client, to handle server hello @@ -59,36 +70,38 @@ 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_tls13_short_header_xtn, &tls13_HandleShortHeaderXtn }, - { -1, NULL } + { 0, NULL } }; static const ssl3ExtensionHandler helloRetryRequestHandlers[] = { { ssl_tls13_key_share_xtn, tls13_ClientHandleKeyShareXtnHrr }, { ssl_tls13_cookie_xtn, tls13_ClientHandleHrrCookie }, - { -1, NULL } + { 0, NULL } }; static const ssl3ExtensionHandler serverHelloHandlersSSL3[] = { { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, - { -1, NULL } + { 0, NULL } }; static const ssl3ExtensionHandler newSessionTicketHandlers[] = { - { ssl_tls13_ticket_early_data_info_xtn, - &tls13_ClientHandleTicketEarlyDataInfoXtn }, - { -1, NULL } + { ssl_tls13_early_data_xtn, + &tls13_ClientHandleTicketEarlyDataXtn }, + { 0, NULL } }; /* This table is used by the client to handle server certificates in TLS 1.3 */ static const ssl3ExtensionHandler serverCertificateHandlers[] = { { ssl_signed_cert_timestamp_xtn, &ssl3_ClientHandleSignedCertTimestampXtn }, { ssl_cert_status_xtn, &ssl3_ClientHandleStatusRequestXtn }, - { -1, NULL } + { 0, NULL } }; static const ssl3ExtensionHandler certificateRequestHandlers[] = { - { -1, NULL } + { ssl_signature_algorithms_xtn, &ssl3_HandleSigAlgsXtn }, + { ssl_tls13_certificate_authorities_xtn, + &tls13_ClientHandleCertAuthoritiesXtn }, + { 0, NULL } }; /* Tables of functions to format TLS hello extensions, one function per @@ -101,14 +114,14 @@ static const ssl3ExtensionHandler certificateRequestHandlers[] = { * the client hello is empty (for example, the extended master secret * extension, if it were listed last). See bug 1243641. */ -static const ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = +static const sslExtensionBuilder clientHelloSendersTLS[] = { - { ssl_server_name_xtn, &ssl3_SendServerNameXtn }, + { ssl_server_name_xtn, &ssl3_ClientSendServerNameXtn }, { ssl_extended_master_secret_xtn, &ssl3_SendExtendedMasterSecretXtn }, { ssl_renegotiation_info_xtn, &ssl3_SendRenegotiationInfoXtn }, { ssl_supported_groups_xtn, &ssl_SendSupportedGroupsXtn }, { ssl_ec_point_formats_xtn, &ssl3_SendSupportedPointFormatsXtn }, - { ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn }, + { 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 }, @@ -121,22 +134,155 @@ static const ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] * client hello is empty. They are not intolerant of TLS 1.2, so list * signature_algorithms at the end. See bug 1243641. */ { ssl_tls13_supported_versions_xtn, &tls13_ClientSendSupportedVersionsXtn }, - { ssl_tls13_short_header_xtn, &tls13_SendShortHeaderXtn }, - { ssl_signature_algorithms_xtn, &ssl3_ClientSendSigAlgsXtn }, + { ssl_signature_algorithms_xtn, &ssl3_SendSigAlgsXtn }, { ssl_tls13_cookie_xtn, &tls13_ClientSendHrrCookieXtn }, - { ssl_tls13_psk_key_exchange_modes_xtn, - &tls13_ClientSendPskKeyExchangeModesXtn }, - { ssl_padding_xtn, &ssl3_ClientSendPaddingExtension }, + { ssl_tls13_psk_key_exchange_modes_xtn, &tls13_ClientSendPskModesXtn }, /* The pre_shared_key extension MUST be last. */ { ssl_tls13_pre_shared_key_xtn, &tls13_ClientSendPreSharedKeyXtn }, - /* any extra entries will appear as { 0, NULL } */ + { 0, NULL } }; -static const ssl3HelloExtensionSender clientHelloSendersSSL3[SSL_MAX_EXTENSIONS] = { - { ssl_renegotiation_info_xtn, &ssl3_SendRenegotiationInfoXtn } - /* any extra entries will appear as { 0, NULL } */ +static const sslExtensionBuilder clientHelloSendersSSL3[] = { + { ssl_renegotiation_info_xtn, &ssl3_SendRenegotiationInfoXtn }, + { 0, NULL } +}; + +static const sslExtensionBuilder tls13_cert_req_senders[] = { + { ssl_signature_algorithms_xtn, &ssl3_SendSigAlgsXtn }, + { ssl_tls13_certificate_authorities_xtn, &tls13_SendCertAuthoritiesXtn }, + { 0, NULL } +}; + +static const sslExtensionBuilder tls13_hrr_senders[] = { + { ssl_tls13_key_share_xtn, &tls13_ServerSendHrrKeyShareXtn }, + { ssl_tls13_cookie_xtn, &tls13_ServerSendHrrCookieXtn }, + { ssl_tls13_supported_versions_xtn, &tls13_ServerSendSupportedVersionsXtn }, + { 0, NULL } +}; + +static const struct { + SSLExtensionType type; + SSLExtensionSupport support; +} ssl_supported_extensions[] = { + { ssl_server_name_xtn, ssl_ext_native_only }, + { ssl_cert_status_xtn, ssl_ext_native }, + { ssl_supported_groups_xtn, ssl_ext_native_only }, + { ssl_ec_point_formats_xtn, ssl_ext_native }, + { ssl_signature_algorithms_xtn, ssl_ext_native_only }, + { ssl_use_srtp_xtn, ssl_ext_native }, + { ssl_app_layer_protocol_xtn, ssl_ext_native_only }, + { ssl_signed_cert_timestamp_xtn, ssl_ext_native }, + { ssl_padding_xtn, ssl_ext_native }, + { ssl_extended_master_secret_xtn, ssl_ext_native_only }, + { ssl_session_ticket_xtn, ssl_ext_native_only }, + { ssl_tls13_key_share_xtn, ssl_ext_native_only }, + { ssl_tls13_pre_shared_key_xtn, ssl_ext_native_only }, + { ssl_tls13_early_data_xtn, ssl_ext_native_only }, + { ssl_tls13_supported_versions_xtn, ssl_ext_native_only }, + { ssl_tls13_cookie_xtn, ssl_ext_native_only }, + { 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 } }; +static SSLExtensionSupport +ssl_GetExtensionSupport(PRUint16 type) +{ + unsigned int i; + for (i = 0; i < PR_ARRAY_SIZE(ssl_supported_extensions); ++i) { + if (type == ssl_supported_extensions[i].type) { + return ssl_supported_extensions[i].support; + } + } + return ssl_ext_none; +} + +SECStatus +SSLExp_GetExtensionSupport(PRUint16 type, SSLExtensionSupport *support) +{ + *support = ssl_GetExtensionSupport(type); + return SECSuccess; +} + +SECStatus +SSLExp_InstallExtensionHooks(PRFileDesc *fd, PRUint16 extension, + SSLExtensionWriter writer, void *writerArg, + SSLExtensionHandler handler, void *handlerArg) +{ + sslSocket *ss = ssl_FindSocket(fd); + PRCList *cursor; + sslCustomExtensionHooks *hook; + + if (!ss) { + return SECFailure; /* Code already set. */ + } + + /* Need to specify both or neither, but not just one. */ + if ((writer && !handler) || (!writer && handler)) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + + if (ssl_GetExtensionSupport(extension) == ssl_ext_native_only) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + + if (ss->firstHsDone || ((ss->ssl3.hs.ws != idle_handshake) && + (ss->ssl3.hs.ws != wait_client_hello))) { + PORT_SetError(PR_INVALID_STATE_ERROR); + return SECFailure; + } + + /* Remove any old handler. */ + for (cursor = PR_NEXT_LINK(&ss->extensionHooks); + cursor != &ss->extensionHooks; + cursor = PR_NEXT_LINK(cursor)) { + hook = (sslCustomExtensionHooks *)cursor; + if (hook->type == extension) { + PR_REMOVE_LINK(&hook->link); + PORT_Free(hook); + break; + } + } + + if (!writer && !handler) { + return SECSuccess; + } + + hook = PORT_ZNew(sslCustomExtensionHooks); + if (!hook) { + return SECFailure; /* This removed the old one, oh well. */ + } + + hook->type = extension; + hook->writer = writer; + hook->writerArg = writerArg; + hook->handler = handler; + hook->handlerArg = handlerArg; + PR_APPEND_LINK(&hook->link, &ss->extensionHooks); + return SECSuccess; +} + +static sslCustomExtensionHooks * +ssl_FindCustomExtensionHooks(sslSocket *ss, PRUint16 extension) +{ + PRCList *cursor; + + for (cursor = PR_NEXT_LINK(&ss->extensionHooks); + cursor != &ss->extensionHooks; + cursor = PR_NEXT_LINK(cursor)) { + sslCustomExtensionHooks *hook = (sslCustomExtensionHooks *)cursor; + if (hook->type == extension) { + return hook; + } + } + + return NULL; +} + static PRBool arrayContainsExtension(const PRUint16 *array, PRUint32 len, PRUint16 ex_type) { @@ -156,8 +302,11 @@ ssl3_ExtensionNegotiated(const sslSocket *ss, PRUint16 ex_type) xtnData->numNegotiated, ex_type); } +/* This checks for whether an extension was advertised. On the client, this + * covers extensions that are sent in ClientHello; on the server, extensions + * sent in CertificateRequest (TLS 1.3 only). */ PRBool -ssl3_ClientExtensionAdvertised(const sslSocket *ss, PRUint16 ex_type) +ssl3_ExtensionAdvertised(const sslSocket *ss, PRUint16 ex_type) { const TLSExtensionData *xtnData = &ss->xtnData; return arrayContainsExtension(xtnData->advertised, @@ -240,6 +389,44 @@ ssl3_FindExtension(sslSocket *ss, SSLExtensionType extension_type) return NULL; } +static SECStatus +ssl_CallExtensionHandler(sslSocket *ss, SSLHandshakeType handshakeMessage, + TLSExtension *extension, + const ssl3ExtensionHandler *handler) +{ + SECStatus rv = SECSuccess; + SSLAlertDescription alert = handshake_failure; + sslCustomExtensionHooks *customHooks; + + customHooks = ssl_FindCustomExtensionHooks(ss, extension->type); + if (customHooks) { + if (customHooks->handler) { + rv = customHooks->handler(ss->fd, handshakeMessage, + extension->data.data, + extension->data.len, + &alert, customHooks->handlerArg); + } + } else { + /* Find extension_type in table of Hello Extension Handlers. */ + for (; handler->ex_handler != NULL; ++handler) { + if (handler->ex_type == extension->type) { + rv = (*handler->ex_handler)(ss, &ss->xtnData, &extension->data); + break; + } + } + } + + if (rv != SECSuccess) { + if (!ss->ssl3.fatalAlertSent) { + /* Send an alert if the handler didn't already. */ + (void)SSL3_SendAlert(ss, alert_fatal, alert); + } + return SECFailure; + } + + return SECSuccess; +} + /* Go through the hello extensions in |ss->ssl3.hs.remoteExtensions|. * For each one, find the extension handler in the table, and * if present, invoke that handler. @@ -250,42 +437,46 @@ ssl3_FindExtension(sslSocket *ss, SSLExtensionType extension_type) * right phase. */ SECStatus -ssl3_HandleParsedExtensions(sslSocket *ss, - SSL3HandshakeType handshakeMessage) +ssl3_HandleParsedExtensions(sslSocket *ss, SSLHandshakeType message) { const ssl3ExtensionHandler *handlers; /* HelloRetryRequest doesn't set ss->version. It might be safe to * do so, but we weren't entirely sure. TODO(ekr@rtfm.com). */ PRBool isTLS13 = (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) || - (handshakeMessage == hello_retry_request); + (message == ssl_hs_hello_retry_request); + /* The following messages can include extensions that were not included in + * the original ClientHello. */ + PRBool allowNotOffered = (message == ssl_hs_client_hello) || + (message == ssl_hs_certificate_request) || + (message == ssl_hs_new_session_ticket); PRCList *cursor; - switch (handshakeMessage) { - case client_hello: + switch (message) { + case ssl_hs_client_hello: handlers = clientHelloHandlers; break; - case new_session_ticket: + case ssl_hs_new_session_ticket: PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_TLS_1_3); handlers = newSessionTicketHandlers; break; - case hello_retry_request: + case ssl_hs_hello_retry_request: handlers = helloRetryRequestHandlers; break; - case encrypted_extensions: + case ssl_hs_encrypted_extensions: PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_TLS_1_3); /* fall through */ - case server_hello: + case ssl_hs_server_hello: if (ss->version > SSL_LIBRARY_VERSION_3_0) { handlers = serverHelloHandlersTLS; } else { handlers = serverHelloHandlersSSL3; } break; - case certificate: + case ssl_hs_certificate: PORT_Assert(!ss->sec.isServer); handlers = serverCertificateHandlers; break; - case certificate_request: + case ssl_hs_certificate_request: PORT_Assert(!ss->sec.isServer); handlers = certificateRequestHandlers; break; @@ -299,28 +490,41 @@ ssl3_HandleParsedExtensions(sslSocket *ss, cursor != &ss->ssl3.hs.remoteExtensions; cursor = PR_NEXT_LINK(cursor)) { TLSExtension *extension = (TLSExtension *)cursor; - const ssl3ExtensionHandler *handler; + SECStatus rv; /* Check whether the server sent an extension which was not advertised - * in the ClientHello */ - if (!ss->sec.isServer && - !ssl3_ClientExtensionAdvertised(ss, extension->type) && - (handshakeMessage != new_session_ticket) && - (extension->type != ssl_tls13_cookie_xtn)) { + * in the ClientHello. + * + * Note that a TLS 1.3 server should check if CertificateRequest + * extensions were sent. But the extensions used for CertificateRequest + * do not have any response, so we rely on + * ssl3_ExtensionAdvertised to return false on the server. That + * results in the server only rejecting any extension. */ + if (!allowNotOffered && (extension->type != ssl_tls13_cookie_xtn) && + !ssl3_ExtensionAdvertised(ss, extension->type)) { (void)SSL3_SendAlert(ss, alert_fatal, unsupported_extension); PORT_SetError(SSL_ERROR_RX_UNEXPECTED_EXTENSION); return SECFailure; } /* Check that this is a legal extension in TLS 1.3 */ - if (isTLS13 && !tls13_ExtensionAllowed(extension->type, handshakeMessage)) { - if (handshakeMessage == client_hello) { - /* Skip extensions not used in TLS 1.3 */ - continue; + if (isTLS13 && + !ssl_FindCustomExtensionHooks(ss, extension->type)) { + switch (tls13_ExtensionStatus(extension->type, message)) { + case tls13_extension_allowed: + break; + case tls13_extension_unknown: + if (allowNotOffered) { + continue; /* Skip over unknown extensions. */ + } + /* Fall through. */ + case tls13_extension_disallowed: + SSL_TRC(3, ("%d: TLS13: unexpected extension %d in message %d", + SSL_GETPID(), extension, message)); + tls13_FatalError(ss, SSL_ERROR_EXTENSION_DISALLOWED_FOR_VERSION, + unsupported_extension); + return SECFailure; } - tls13_FatalError(ss, SSL_ERROR_EXTENSION_DISALLOWED_FOR_VERSION, - unsupported_extension); - return SECFailure; } /* Special check for this being the last extension if it's @@ -334,23 +538,9 @@ ssl3_HandleParsedExtensions(sslSocket *ss, return SECFailure; } - /* find extension_type in table of Hello Extension Handlers */ - for (handler = handlers; handler->ex_type >= 0; handler++) { - /* if found, call this handler */ - if (handler->ex_type == extension->type) { - SECStatus rv; - - rv = (*handler->ex_handler)(ss, &ss->xtnData, - (PRUint16)extension->type, - &extension->data); - if (rv != SECSuccess) { - if (!ss->ssl3.fatalAlertSent) { - /* send a generic alert if the handler didn't already */ - (void)SSL3_SendAlert(ss, alert_fatal, handshake_failure); - } - return SECFailure; - } - } + rv = ssl_CallExtensionHandler(ss, message, extension, handlers); + if (rv != SECSuccess) { + return SECFailure; } } return SECSuccess; @@ -361,7 +551,7 @@ ssl3_HandleParsedExtensions(sslSocket *ss, SECStatus ssl3_HandleExtensions(sslSocket *ss, PRUint8 **b, PRUint32 *length, - SSL3HandshakeType handshakeMessage) + SSLHandshakeType handshakeMessage) { SECStatus rv; @@ -383,21 +573,30 @@ SECStatus ssl3_RegisterExtensionSender(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, - ssl3HelloExtensionSenderFunc cb) + sslExtensionBuilderFunc cb) { int i; - ssl3HelloExtensionSender *sender; + sslExtensionBuilder *sender; if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) { sender = &xtnData->serverHelloSenders[0]; } else { - if (tls13_ExtensionAllowed(ex_type, server_hello)) { - PORT_Assert(!tls13_ExtensionAllowed(ex_type, encrypted_extensions)); + if (tls13_ExtensionStatus(ex_type, ssl_hs_server_hello) == + tls13_extension_allowed) { + PORT_Assert(tls13_ExtensionStatus(ex_type, + ssl_hs_encrypted_extensions) == + tls13_extension_disallowed); sender = &xtnData->serverHelloSenders[0]; - } else if (tls13_ExtensionAllowed(ex_type, certificate)) { + } else if (tls13_ExtensionStatus(ex_type, + ssl_hs_encrypted_extensions) == + tls13_extension_allowed) { + sender = &xtnData->encryptedExtensionsSenders[0]; + } else if (tls13_ExtensionStatus(ex_type, ssl_hs_certificate) == + tls13_extension_allowed) { sender = &xtnData->certificateSenders[0]; } else { - PORT_Assert(tls13_ExtensionAllowed(ex_type, encrypted_extensions)); - sender = &xtnData->encryptedExtensionsSenders[0]; + PORT_Assert(0); + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; } } for (i = 0; i < SSL_MAX_EXTENSIONS; ++i, ++sender) { @@ -418,32 +617,289 @@ ssl3_RegisterExtensionSender(const sslSocket *ss, return SECFailure; } -/* call each of the extension senders and return the accumulated length */ -PRInt32 -ssl3_CallHelloExtensionSenders(sslSocket *ss, PRBool append, PRUint32 maxBytes, - const ssl3HelloExtensionSender *sender) +static SECStatus +ssl_CallCustomExtensionSenders(sslSocket *ss, sslBuffer *buf, + SSLHandshakeType message) { - PRInt32 total_exten_len = 0; - int i; + sslBuffer tail = SSL_BUFFER_EMPTY; + SECStatus rv; + PRCList *cursor; - if (!sender) { - if (ss->vrange.max > SSL_LIBRARY_VERSION_3_0) { - sender = &clientHelloSendersTLS[0]; - } else { - sender = &clientHelloSendersSSL3[0]; + /* Save any extensions that want to be last. */ + if (ss->xtnData.lastXtnOffset) { + rv = sslBuffer_Append(&tail, buf->buf + ss->xtnData.lastXtnOffset, + buf->len - ss->xtnData.lastXtnOffset); + if (rv != SECSuccess) { + return SECFailure; } + buf->len = ss->xtnData.lastXtnOffset; } - for (i = 0; i < SSL_MAX_EXTENSIONS; ++i, ++sender) { - if (sender->ex_sender) { - PRInt32 extLen = (*sender->ex_sender)(ss, &ss->xtnData, append, maxBytes); - if (extLen < 0) - return -1; - maxBytes -= extLen; - total_exten_len += extLen; + /* Reserve the maximum amount of space possible. */ + rv = sslBuffer_Grow(buf, 65535); + if (rv != SECSuccess) { + return SECFailure; + } + + for (cursor = PR_NEXT_LINK(&ss->extensionHooks); + cursor != &ss->extensionHooks; + cursor = PR_NEXT_LINK(cursor)) { + sslCustomExtensionHooks *hook = + (sslCustomExtensionHooks *)cursor; + PRBool append = PR_FALSE; + unsigned int len = 0; + + if (hook->writer) { + /* The writer writes directly into |buf|. Provide space that allows + * for the existing extensions, any tail, plus type and length. */ + unsigned int space = buf->space - (buf->len + tail.len + 4); + append = (*hook->writer)(ss->fd, message, + buf->buf + buf->len + 4, &len, space, + hook->writerArg); + if (len > space) { + PORT_SetError(SEC_ERROR_APPLICATION_CALLBACK_ERROR); + goto loser; + } + } + if (!append) { + continue; + } + + rv = sslBuffer_AppendNumber(buf, hook->type, 2); + if (rv != SECSuccess) { + goto loser; /* Code already set. */ + } + rv = sslBuffer_AppendNumber(buf, len, 2); + if (rv != SECSuccess) { + goto loser; /* Code already set. */ + } + buf->len += len; + + if (message == ssl_hs_client_hello || + message == ssl_hs_certificate_request) { + ss->xtnData.advertised[ss->xtnData.numAdvertised++] = hook->type; } } - return total_exten_len; + + sslBuffer_Append(buf, tail.buf, tail.len); + sslBuffer_Clear(&tail); + return SECSuccess; + +loser: + sslBuffer_Clear(&tail); + return SECFailure; +} + +/* Call extension handlers for the given message. */ +SECStatus +ssl_ConstructExtensions(sslSocket *ss, sslBuffer *buf, SSLHandshakeType message) +{ + const sslExtensionBuilder *sender; + SECStatus rv; + + PORT_Assert(buf->len == 0); + + switch (message) { + case ssl_hs_client_hello: + if (ss->vrange.max > SSL_LIBRARY_VERSION_3_0) { + sender = clientHelloSendersTLS; + } else { + sender = clientHelloSendersSSL3; + } + break; + + case ssl_hs_server_hello: + sender = ss->xtnData.serverHelloSenders; + break; + + case ssl_hs_certificate_request: + PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_TLS_1_3); + sender = tls13_cert_req_senders; + break; + + case ssl_hs_certificate: + PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_TLS_1_3); + sender = ss->xtnData.certificateSenders; + break; + + case ssl_hs_encrypted_extensions: + PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_TLS_1_3); + sender = ss->xtnData.encryptedExtensionsSenders; + break; + + case ssl_hs_hello_retry_request: + PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_TLS_1_3); + sender = tls13_hrr_senders; + break; + + default: + PORT_Assert(0); + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + + for (; sender->ex_sender != NULL; ++sender) { + PRBool append = PR_FALSE; + unsigned int start = buf->len; + unsigned int length; + + if (ssl_FindCustomExtensionHooks(ss, sender->ex_type)) { + continue; + } + + /* Save space for the extension type and length. Note that we don't grow + * the buffer now; rely on sslBuffer_Append* to do that. */ + buf->len += 4; + rv = (*sender->ex_sender)(ss, &ss->xtnData, buf, &append); + if (rv != SECSuccess) { + goto loser; + } + + /* Save the length and go back to the start. */ + length = buf->len - start - 4; + buf->len = start; + if (!append) { + continue; + } + + buf->len = start; + rv = sslBuffer_AppendNumber(buf, sender->ex_type, 2); + if (rv != SECSuccess) { + goto loser; /* Code already set. */ + } + rv = sslBuffer_AppendNumber(buf, length, 2); + if (rv != SECSuccess) { + goto loser; /* Code already set. */ + } + /* Skip over the extension body. */ + buf->len += length; + + if (message == ssl_hs_client_hello || + message == ssl_hs_certificate_request) { + ss->xtnData.advertised[ss->xtnData.numAdvertised++] = + sender->ex_type; + } + } + + if (!PR_CLIST_IS_EMPTY(&ss->extensionHooks)) { + rv = ssl_CallCustomExtensionSenders(ss, buf, message); + if (rv != SECSuccess) { + goto loser; + } + } + + if (buf->len > 0xffff) { + PORT_SetError(SSL_ERROR_TX_RECORD_TOO_LONG); + goto loser; + } + + return SECSuccess; + +loser: + sslBuffer_Clear(buf); + return SECFailure; +} + +/* This extension sender can be used anywhere that an always empty extension is + * needed. Mostly that is for ServerHello where sender registration is dynamic; + * ClientHello senders are usually conditional in some way. */ +SECStatus +ssl_SendEmptyExtension(const sslSocket *ss, TLSExtensionData *xtnData, + sslBuffer *buf, PRBool *append) +{ + *append = PR_TRUE; + return SECSuccess; +} + +/* Takes the size of the ClientHello, less the record header, and determines how + * much padding is required. */ +static unsigned int +ssl_CalculatePaddingExtLen(const sslSocket *ss, unsigned int clientHelloLength) +{ + unsigned int recordLength = 1 /* handshake message type */ + + 3 /* handshake message length */ + + clientHelloLength; + unsigned int extensionLen; + + /* Don't pad for DTLS, for SSLv3, or for renegotiation. */ + if (IS_DTLS(ss) || + ss->vrange.max < SSL_LIBRARY_VERSION_TLS_1_0 || + ss->firstHsDone) { + return 0; + } + + /* A padding extension may be included to ensure that the record containing + * the ClientHello doesn't have a length between 256 and 511 bytes + * (inclusive). Initial ClientHello records with such lengths trigger bugs + * in F5 devices. */ + if (recordLength < 256 || recordLength >= 512) { + return 0; + } + + extensionLen = 512 - recordLength; + /* Extensions take at least four bytes to encode. Always include at least + * one byte of data if we are padding. Some servers will time out or + * terminate the connection if the last ClientHello extension is empty. */ + if (extensionLen < 5) { + extensionLen = 5; + } + + return extensionLen - 4; +} + +/* ssl3_SendPaddingExtension possibly adds an extension which ensures that a + * ClientHello record is either < 256 bytes or is >= 512 bytes. This ensures + * that we don't trigger bugs in F5 products. + * + * This takes an existing extension buffer, |buf|, and the length of the + * remainder of the ClientHello, |prefixLen|. It modifies the extension buffer + * to insert padding at the right place. + */ +SECStatus +ssl_InsertPaddingExtension(const sslSocket *ss, unsigned int prefixLen, + sslBuffer *buf) +{ + static unsigned char padding[252] = { 0 }; + unsigned int paddingLen; + unsigned int tailLen; + SECStatus rv; + + /* Account for the size of the header, the length field of the extensions + * block and the size of the existing extensions. */ + paddingLen = ssl_CalculatePaddingExtLen(ss, prefixLen + 2 + buf->len); + if (!paddingLen) { + return SECSuccess; + } + + /* Move the tail if there is one. This only happens if we are sending the + * TLS 1.3 PSK extension, which needs to be at the end. */ + if (ss->xtnData.lastXtnOffset) { + PORT_Assert(buf->len > ss->xtnData.lastXtnOffset); + tailLen = buf->len - ss->xtnData.lastXtnOffset; + rv = sslBuffer_Grow(buf, buf->len + 4 + paddingLen); + if (rv != SECSuccess) { + return SECFailure; + } + PORT_Memmove(buf->buf + ss->xtnData.lastXtnOffset + 4 + paddingLen, + buf->buf + ss->xtnData.lastXtnOffset, + tailLen); + buf->len = ss->xtnData.lastXtnOffset; + } else { + tailLen = 0; + } + + rv = sslBuffer_AppendNumber(buf, ssl_padding_xtn, 2); + if (rv != SECSuccess) { + return SECFailure; /* Code already set. */ + } + rv = sslBuffer_AppendVariable(buf, padding, paddingLen, 2); + if (rv != SECSuccess) { + return SECFailure; /* Code already set. */ + } + + buf->len += tailLen; + + return SECSuccess; } void @@ -460,52 +916,59 @@ ssl3_DestroyRemoteExtensions(PRCList *list) /* Initialize the extension data block. */ void -ssl3_InitExtensionData(TLSExtensionData *xtnData) +ssl3_InitExtensionData(TLSExtensionData *xtnData, const sslSocket *ss) { + unsigned int advertisedMax; + PRCList *cursor; + /* Set things up to the right starting state. */ PORT_Memset(xtnData, 0, sizeof(*xtnData)); xtnData->peerSupportsFfdheGroups = PR_FALSE; PR_INIT_CLIST(&xtnData->remoteKeyShares); + + /* Allocate enough to allow for native extensions, plus any custom ones. */ + if (ss->sec.isServer) { + advertisedMax = PR_MAX(PR_ARRAY_SIZE(certificateRequestHandlers), + PR_ARRAY_SIZE(tls13_cert_req_senders)); + } else { + advertisedMax = PR_MAX(PR_ARRAY_SIZE(clientHelloHandlers), + PR_ARRAY_SIZE(clientHelloSendersTLS)); + ++advertisedMax; /* For the RI SCSV, which we also track. */ + } + for (cursor = PR_NEXT_LINK(&ss->extensionHooks); + cursor != &ss->extensionHooks; + cursor = PR_NEXT_LINK(cursor)) { + ++advertisedMax; + } + xtnData->advertised = PORT_ZNewArray(PRUint16, advertisedMax); } -/* Free everything that has been allocated and then reset back to - * the starting state. */ void -ssl3_ResetExtensionData(TLSExtensionData *xtnData) +ssl3_DestroyExtensionData(TLSExtensionData *xtnData) { - /* Clean up. */ ssl3_FreeSniNameArray(xtnData); - PORT_Free(xtnData->clientSigSchemes); + PORT_Free(xtnData->sigSchemes); SECITEM_FreeItem(&xtnData->nextProto, PR_FALSE); tls13_DestroyKeyShares(&xtnData->remoteKeyShares); - - /* Now reinit. */ - ssl3_InitExtensionData(xtnData); -} - -/* Thunks to let extension handlers operate on const sslSocket* objects. */ -SECStatus -ssl3_ExtAppendHandshake(const sslSocket *ss, const void *void_src, - PRInt32 bytes) -{ - return ssl3_AppendHandshake((sslSocket *)ss, void_src, bytes); -} - -SECStatus -ssl3_ExtAppendHandshakeNumber(const sslSocket *ss, PRInt32 num, - PRInt32 lenSize) -{ - return ssl3_AppendHandshakeNumber((sslSocket *)ss, num, lenSize); + SECITEM_FreeItem(&xtnData->certReqContext, PR_FALSE); + SECITEM_FreeItem(&xtnData->applicationToken, PR_FALSE); + if (xtnData->certReqAuthorities.arena) { + PORT_FreeArena(xtnData->certReqAuthorities.arena, PR_FALSE); + xtnData->certReqAuthorities.arena = NULL; + } + PORT_Free(xtnData->advertised); } -SECStatus -ssl3_ExtAppendHandshakeVariable(const sslSocket *ss, - const PRUint8 *src, PRInt32 bytes, - PRInt32 lenSize) +/* Free everything that has been allocated and then reset back to + * the starting state. */ +void +ssl3_ResetExtensionData(TLSExtensionData *xtnData, const sslSocket *ss) { - return ssl3_AppendHandshakeVariable((sslSocket *)ss, src, bytes, lenSize); + ssl3_DestroyExtensionData(xtnData); + ssl3_InitExtensionData(xtnData, ss); } +/* Thunks to let extension handlers operate on const sslSocket* objects. */ void ssl3_ExtSendAlert(const sslSocket *ss, SSL3AlertLevel level, SSL3AlertDescription desc) diff --git a/security/nss/lib/ssl/ssl3ext.h b/security/nss/lib/ssl/ssl3ext.h index 90407375a..d0f75a599 100644 --- a/security/nss/lib/ssl/ssl3ext.h +++ b/security/nss/lib/ssl/ssl3ext.h @@ -9,54 +9,38 @@ #ifndef __ssl3ext_h_ #define __ssl3ext_h_ +#include "sslencode.h" + typedef enum { sni_nametype_hostname } SNINameType; typedef struct TLSExtensionDataStr TLSExtensionData; -/* registerable callback function that either appends extension to buffer +/* Registerable callback function that either appends extension to buffer * or returns length of data that it would have appended. */ -typedef PRInt32 (*ssl3HelloExtensionSenderFunc)(const sslSocket *ss, - TLSExtensionData *xtnData, - PRBool append, - PRUint32 maxBytes); - -/* registerable callback function that handles a received extension, - * of the given type. - */ -typedef SECStatus (*ssl3ExtensionHandlerFunc)(const sslSocket *ss, - TLSExtensionData *xtnData, - PRUint16 ex_type, - SECItem *data); +typedef SECStatus (*sslExtensionBuilderFunc)(const sslSocket *ss, + TLSExtensionData *xtnData, + sslBuffer *buf, PRBool *added); /* row in a table of hello extension senders */ typedef struct { PRInt32 ex_type; - ssl3HelloExtensionSenderFunc ex_sender; -} ssl3HelloExtensionSender; - -/* row in a table of hello extension handlers */ -typedef struct { - PRInt32 ex_type; - ssl3ExtensionHandlerFunc ex_handler; -} ssl3ExtensionHandler; + sslExtensionBuilderFunc ex_sender; +} sslExtensionBuilder; struct TLSExtensionDataStr { /* registered callbacks that send server hello extensions */ - ssl3HelloExtensionSender serverHelloSenders[SSL_MAX_EXTENSIONS]; - ssl3HelloExtensionSender encryptedExtensionsSenders[SSL_MAX_EXTENSIONS]; - ssl3HelloExtensionSender certificateSenders[SSL_MAX_EXTENSIONS]; + sslExtensionBuilder serverHelloSenders[SSL_MAX_EXTENSIONS]; + sslExtensionBuilder encryptedExtensionsSenders[SSL_MAX_EXTENSIONS]; + sslExtensionBuilder certificateSenders[SSL_MAX_EXTENSIONS]; - /* Keep track of the extensions that are negotiated. */ + /* Keep track of the extensions that are advertised or negotiated. */ PRUint16 numAdvertised; + PRUint16 *advertised; /* Allocated dynamically. */ PRUint16 numNegotiated; - PRUint16 advertised[SSL_MAX_EXTENSIONS]; PRUint16 negotiated[SSL_MAX_EXTENSIONS]; - /* Amount of padding we need to add. */ - PRUint16 paddingLen; - /* SessionTicket Extension related data. */ PRBool ticketTimestampVerified; PRBool emptySessionTicket; @@ -86,10 +70,13 @@ struct TLSExtensionDataStr { PRBool peerSupportsFfdheGroups; /* if the peer supports named ffdhe groups */ /* clientSigAndHash contains the contents of the signature_algorithms - * extension (if any) from the client. This is only valid for TLS 1.2 - * or later. */ - SSLSignatureScheme *clientSigSchemes; - unsigned int numClientSigScheme; + * extension (if any) the other side supports. This is only valid for TLS + * 1.2 or later. In TLS 1.3, it is also used for CertificateRequest. */ + SSLSignatureScheme *sigSchemes; + unsigned int numSigSchemes; + + SECItem certReqContext; + CERTDistNames certReqAuthorities; /* In a client: if the server supports Next Protocol Negotiation, then * this is the protocol that was negotiated. @@ -99,9 +86,18 @@ struct TLSExtensionDataStr { PRUint16 dtlsSRTPCipherSuite; /* 0 if not selected */ - SECItem pskBinder; /* The PSK binder for the first PSK (TLS 1.3) */ - unsigned long pskBinderPrefixLen; /* The length of the binder input. */ - PRCList remoteKeyShares; /* The other side's public keys (TLS 1.3) */ + unsigned int lastXtnOffset; /* Where to insert padding. 0 = end. */ + PRCList remoteKeyShares; /* The other side's public keys (TLS 1.3) */ + + /* The following are used by a TLS 1.3 server. */ + SECItem pskBinder; /* The binder for the first PSK. */ + unsigned int pskBindersLen; /* The length of the binders. */ + PRUint32 ticketAge; /* Used to accept early data. */ + SECItem cookie; /* HRR Cookie. */ + const sslNamedGroupDef *selectedGroup; /* For HRR. */ + /* The application token contains a value that was passed to the client via + * a session ticket, or the cookie in a HelloRetryRequest. */ + SECItem applicationToken; }; typedef struct TLSExtensionStr { @@ -110,40 +106,44 @@ typedef struct TLSExtensionStr { SECItem data; /* Pointers into the handshake data. */ } TLSExtension; +typedef struct sslCustomExtensionHooks { + PRCList link; + PRUint16 type; + SSLExtensionWriter writer; + void *writerArg; + SSLExtensionHandler handler; + void *handlerArg; +} sslCustomExtensionHooks; + SECStatus ssl3_HandleExtensions(sslSocket *ss, PRUint8 **b, PRUint32 *length, - SSL3HandshakeType handshakeMessage); + SSLHandshakeType handshakeMessage); SECStatus ssl3_ParseExtensions(sslSocket *ss, PRUint8 **b, PRUint32 *length); SECStatus ssl3_HandleParsedExtensions(sslSocket *ss, - SSL3HandshakeType handshakeMessage); + SSLHandshakeType handshakeMessage); TLSExtension *ssl3_FindExtension(sslSocket *ss, SSLExtensionType extension_type); void ssl3_DestroyRemoteExtensions(PRCList *list); -void ssl3_InitExtensionData(TLSExtensionData *xtnData); -void ssl3_ResetExtensionData(TLSExtensionData *xtnData); +void ssl3_InitExtensionData(TLSExtensionData *xtnData, const sslSocket *ss); +void ssl3_DestroyExtensionData(TLSExtensionData *xtnData); +void ssl3_ResetExtensionData(TLSExtensionData *xtnData, const sslSocket *ss); PRBool ssl3_ExtensionNegotiated(const sslSocket *ss, PRUint16 ex_type); -PRBool ssl3_ClientExtensionAdvertised(const sslSocket *ss, PRUint16 ex_type); +PRBool ssl3_ExtensionAdvertised(const sslSocket *ss, PRUint16 ex_type); SECStatus ssl3_RegisterExtensionSender(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, - ssl3HelloExtensionSenderFunc cb); -PRInt32 ssl3_CallHelloExtensionSenders(sslSocket *ss, PRBool append, PRUint32 maxBytes, - const ssl3HelloExtensionSender *sender); - -void ssl3_CalculatePaddingExtLen(sslSocket *ss, - unsigned int clientHelloLength); + sslExtensionBuilderFunc cb); +SECStatus ssl_ConstructExtensions(sslSocket *ss, sslBuffer *buf, + SSLHandshakeType message); +SECStatus ssl_SendEmptyExtension(const sslSocket *ss, TLSExtensionData *xtnData, + sslBuffer *buf, PRBool *append); +SECStatus ssl_InsertPaddingExtension(const sslSocket *ss, unsigned int prefixLen, + sslBuffer *buf); /* Thunks to let us operate on const sslSocket* objects. */ -SECStatus ssl3_ExtAppendHandshake(const sslSocket *ss, const void *void_src, - PRInt32 bytes); -SECStatus ssl3_ExtAppendHandshakeNumber(const sslSocket *ss, PRInt32 num, - PRInt32 lenSize); -SECStatus ssl3_ExtAppendHandshakeVariable(const sslSocket *ss, - const PRUint8 *src, PRInt32 bytes, - PRInt32 lenSize); void ssl3_ExtSendAlert(const sslSocket *ss, SSL3AlertLevel level, SSL3AlertDescription desc); void ssl3_ExtDecodeError(const sslSocket *ss); @@ -156,4 +156,10 @@ SECStatus ssl3_ExtConsumeHandshakeVariable(const sslSocket *ss, SECItem *i, PRUint32 bytes, PRUint8 **b, PRUint32 *length); +SECStatus SSLExp_GetExtensionSupport(PRUint16 type, + SSLExtensionSupport *support); +SECStatus SSLExp_InstallExtensionHooks( + PRFileDesc *fd, PRUint16 extension, SSLExtensionWriter writer, + void *writerArg, SSLExtensionHandler handler, void *handlerArg); + #endif diff --git a/security/nss/lib/ssl/ssl3exthandle.c b/security/nss/lib/ssl/ssl3exthandle.c index 370bd8b3e..e6388945e 100644 --- a/security/nss/lib/ssl/ssl3exthandle.c +++ b/security/nss/lib/ssl/ssl3exthandle.c @@ -13,7 +13,6 @@ #include "blapit.h" #include "prinit.h" #include "selfencrypt.h" -#include "ssl3encode.h" #include "ssl3ext.h" #include "ssl3exthandle.h" #include "tls13exthandle.h" /* For tls13_ServerSendStatusRequestXtn. */ @@ -22,70 +21,48 @@ * unless that name is a dotted decimal string. * Used by client and server. */ -PRInt32 -ssl3_SendServerNameXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, - PRUint32 maxBytes) +SECStatus +ssl3_ClientSendServerNameXtn(const sslSocket *ss, TLSExtensionData *xtnData, + sslBuffer *buf, PRBool *added) { + unsigned int len; + PRNetAddr netAddr; SECStatus rv; - if (!ss) - return 0; - if (!ss->sec.isServer) { - PRUint32 len; - PRNetAddr netAddr; - - /* must have a hostname */ - if (!ss->url || !ss->url[0]) - return 0; - /* must not be an IPv4 or IPv6 address */ - if (PR_SUCCESS == PR_StringToNetAddr(ss->url, &netAddr)) { - /* is an IP address (v4 or v6) */ - return 0; - } - len = PORT_Strlen(ss->url); - if (append && maxBytes >= len + 9) { - /* extension_type */ - rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_server_name_xtn, 2); - if (rv != SECSuccess) - return -1; - /* length of extension_data */ - rv = ssl3_ExtAppendHandshakeNumber(ss, len + 5, 2); - if (rv != SECSuccess) - return -1; - /* length of server_name_list */ - rv = ssl3_ExtAppendHandshakeNumber(ss, len + 3, 2); - if (rv != SECSuccess) - return -1; - /* Name Type (sni_host_name) */ - rv = ssl3_ExtAppendHandshake(ss, "\0", 1); - if (rv != SECSuccess) - return -1; - /* HostName (length and value) */ - rv = ssl3_ExtAppendHandshakeVariable(ss, (PRUint8 *)ss->url, len, 2); - if (rv != SECSuccess) - return -1; - if (!ss->sec.isServer) { - xtnData->advertised[xtnData->numAdvertised++] = - ssl_server_name_xtn; - } - } - return len + 9; + + /* must have a hostname */ + if (!ss->url || !ss->url[0]) { + return SECSuccess; } - /* Server side */ - if (append && maxBytes >= 4) { - rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_server_name_xtn, 2); - if (rv != SECSuccess) - return -1; - /* length of extension_data */ - rv = ssl3_ExtAppendHandshakeNumber(ss, 0, 2); - if (rv != SECSuccess) - return -1; + /* must not be an IPv4 or IPv6 address */ + if (PR_SUCCESS == PR_StringToNetAddr(ss->url, &netAddr)) { + /* is an IP address (v4 or v6) */ + return SECSuccess; + } + len = PORT_Strlen(ss->url); + /* length of server_name_list */ + rv = sslBuffer_AppendNumber(buf, len + 3, 2); + if (rv != SECSuccess) { + return SECFailure; + } + /* Name Type (sni_host_name) */ + rv = sslBuffer_AppendNumber(buf, 0, 1); + if (rv != SECSuccess) { + return SECFailure; + } + /* HostName (length and value) */ + rv = sslBuffer_AppendVariable(buf, (const PRUint8 *)ss->url, len, 2); + if (rv != SECSuccess) { + return SECFailure; } - return 4; + + *added = PR_TRUE; + return SECSuccess; } /* Handle an incoming SNI extension. */ SECStatus -ssl3_HandleServerNameXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data) +ssl3_HandleServerNameXtn(const sslSocket *ss, TLSExtensionData *xtnData, + SECItem *data) { SECItem *names = NULL; PRUint32 listLenBytes = 0; @@ -194,88 +171,54 @@ ssl3_FreeSniNameArray(TLSExtensionData *xtnData) * sends an empty ticket. Servers always send empty tickets. */ PRInt32 -ssl3_SendSessionTicketXtn( - const sslSocket *ss, - TLSExtensionData *xtnData, - PRBool append, - PRUint32 maxBytes) +ssl3_ClientSendSessionTicketXtn(const sslSocket *ss, TLSExtensionData *xtnData, + sslBuffer *buf, PRBool *added) { - PRInt32 extension_length; NewSessionTicket *session_ticket = NULL; sslSessionID *sid = ss->sec.ci.sid; + SECStatus rv; + + PORT_Assert(!ss->sec.isServer); /* Never send an extension with a ticket for TLS 1.3, but * OK to send the empty one in case the server does 1.2. */ - if (sid->cached == in_client_cache && + if ((sid->cached == in_client_cache || sid->cached == in_external_cache) && sid->version >= SSL_LIBRARY_VERSION_TLS_1_3) { - return 0; + return SECSuccess; } /* Ignore the SessionTicket extension if processing is disabled. */ - if (!ss->opt.enableSessionTickets) - return 0; - - /* Empty extension length = extension_type (2-bytes) + - * length(extension_data) (2-bytes) - */ - extension_length = 4; + if (!ss->opt.enableSessionTickets) { + return SECSuccess; + } - /* If we are a client then send a session ticket if one is availble. - * Servers that support the extension and are willing to negotiate the - * the extension always respond with an empty extension. + /* Send a session ticket if one is available. + * + * The caller must be holding sid->u.ssl3.lock for reading. We cannot + * just acquire and release the lock within this function because the + * caller will call this function twice, and we need the inputs to be + * consistent between the two calls. Note that currently the caller + * will only be holding the lock when we are the client and when we're + * attempting to resume an existing session. */ - if (!ss->sec.isServer) { - /* The caller must be holding sid->u.ssl3.lock for reading. We cannot - * just acquire and release the lock within this function because the - * caller will call this function twice, and we need the inputs to be - * consistent between the two calls. Note that currently the caller - * will only be holding the lock when we are the client and when we're - * attempting to resume an existing session. - */ + session_ticket = &sid->u.ssl3.locked.sessionTicket; + if (session_ticket->ticket.data && + (xtnData->ticketTimestampVerified || + ssl_TicketTimeValid(session_ticket))) { - session_ticket = &sid->u.ssl3.locked.sessionTicket; - if (session_ticket->ticket.data) { - if (xtnData->ticketTimestampVerified) { - extension_length += session_ticket->ticket.len; - } else if (!append && ssl_TicketTimeValid(session_ticket)) { - extension_length += session_ticket->ticket.len; - xtnData->ticketTimestampVerified = PR_TRUE; - } - } - } + xtnData->ticketTimestampVerified = PR_FALSE; - if (maxBytes < (PRUint32)extension_length) { - PORT_Assert(0); - return 0; - } - if (append) { - SECStatus rv; - /* extension_type */ - rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_session_ticket_xtn, 2); - if (rv != SECSuccess) - goto loser; - if (session_ticket && session_ticket->ticket.data && - xtnData->ticketTimestampVerified) { - rv = ssl3_ExtAppendHandshakeVariable(ss, session_ticket->ticket.data, - session_ticket->ticket.len, 2); - xtnData->ticketTimestampVerified = PR_FALSE; - xtnData->sentSessionTicketInClientHello = PR_TRUE; - } else { - rv = ssl3_ExtAppendHandshakeNumber(ss, 0, 2); + rv = sslBuffer_Append(buf, session_ticket->ticket.data, + session_ticket->ticket.len); + if (rv != SECSuccess) { + return SECFailure; } - if (rv != SECSuccess) - goto loser; - if (!ss->sec.isServer) { - xtnData->advertised[xtnData->numAdvertised++] = - ssl_session_ticket_xtn; - } + xtnData->sentSessionTicketInClientHello = PR_TRUE; } - return extension_length; -loser: - xtnData->ticketTimestampVerified = PR_FALSE; - return -1; + *added = PR_TRUE; + return SECSuccess; } PRBool @@ -301,16 +244,18 @@ ssl_AlpnTagAllowed(const sslSocket *ss, const SECItem *tag) /* handle an incoming Next Protocol Negotiation extension. */ SECStatus -ssl3_ServerHandleNextProtoNegoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, +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++] = ex_type; + 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 @@ -344,7 +289,7 @@ ssl3_ValidateNextProtoNego(const unsigned char *data, unsigned int length) /* protocol selection handler for ALPN (server side) and NPN (client side) */ static SECStatus ssl3_SelectAppProtocol(const sslSocket *ss, TLSExtensionData *xtnData, - PRUint16 ex_type, SECItem *data) + PRUint16 extension, SECItem *data) { SECStatus rv; unsigned char resultBuffer[255]; @@ -381,7 +326,7 @@ ssl3_SelectAppProtocol(const sslSocket *ss, TLSExtensionData *xtnData, SECITEM_FreeItem(&xtnData->nextProto, PR_FALSE); - if (ex_type == ssl_app_layer_protocol_xtn && + 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. */ @@ -390,13 +335,14 @@ ssl3_SelectAppProtocol(const sslSocket *ss, TLSExtensionData *xtnData, return SECFailure; } - xtnData->negotiated[xtnData->numNegotiated++] = ex_type; + xtnData->negotiated[xtnData->numNegotiated++] = extension; return SECITEM_CopyItem(NULL, &xtnData->nextProto, &result); } /* handle an incoming ALPN extension at the server */ SECStatus -ssl3_ServerHandleAppProtoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data) +ssl3_ServerHandleAppProtoXtn(const sslSocket *ss, TLSExtensionData *xtnData, + SECItem *data) { PRUint32 count; SECStatus rv; @@ -423,15 +369,16 @@ ssl3_ServerHandleAppProtoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRU return SECSuccess; } - rv = ssl3_SelectAppProtocol(ss, xtnData, ex_type, data); + rv = ssl3_SelectAppProtocol(ss, xtnData, ssl_app_layer_protocol_xtn, data); if (rv != SECSuccess) { return rv; } /* prepare to send back a response, if we negotiated */ if (xtnData->nextProtoState == SSL_NEXT_PROTO_NEGOTIATED) { - rv = ssl3_RegisterExtensionSender( - ss, xtnData, ex_type, ssl3_ServerSendAppProtoXtn); + rv = ssl3_RegisterExtensionSender(ss, xtnData, + ssl_app_layer_protocol_xtn, + ssl3_ServerSendAppProtoXtn); if (rv != SECSuccess) { ssl3_ExtSendAlert(ss, alert_fatal, internal_error); PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); @@ -442,9 +389,10 @@ ssl3_ServerHandleAppProtoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRU } SECStatus -ssl3_ClientHandleNextProtoNegoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, +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)) { @@ -470,11 +418,12 @@ ssl3_ClientHandleNextProtoNegoXtn(const sslSocket *ss, TLSExtensionData *xtnData return SECFailure; } - return ssl3_SelectAppProtocol(ss, xtnData, ex_type, data); + return ssl3_SelectAppProtocol(ss, xtnData, ssl_next_proto_nego_xtn, data); } SECStatus -ssl3_ClientHandleAppProtoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data) +ssl3_ClientHandleAppProtoXtn(const sslSocket *ss, TLSExtensionData *xtnData, + SECItem *data) { SECStatus rv; PRUint32 list_len; @@ -521,265 +470,168 @@ ssl3_ClientHandleAppProtoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRU SECITEM_FreeItem(&xtnData->nextProto, PR_FALSE); xtnData->nextProtoState = SSL_NEXT_PROTO_SELECTED; - xtnData->negotiated[xtnData->numNegotiated++] = ex_type; + xtnData->negotiated[xtnData->numNegotiated++] = ssl_app_layer_protocol_xtn; return SECITEM_CopyItem(NULL, &xtnData->nextProto, &protocol_name); } -PRInt32 -ssl3_ClientSendNextProtoNegoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, - PRUint32 maxBytes) +SECStatus +ssl3_ClientSendNextProtoNegoXtn(const sslSocket *ss, TLSExtensionData *xtnData, + sslBuffer *buf, PRBool *added) { - PRInt32 extension_length; - /* Renegotiations do not send this extension. */ if (!ss->opt.enableNPN || !ss->nextProtoCallback || ss->firstHsDone) { - return 0; - } - - extension_length = 4; - - if (maxBytes < (PRUint32)extension_length) { - return 0; - } - if (append) { - SECStatus rv; - rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_next_proto_nego_xtn, 2); - if (rv != SECSuccess) - goto loser; - rv = ssl3_ExtAppendHandshakeNumber(ss, 0, 2); - if (rv != SECSuccess) - goto loser; - xtnData->advertised[xtnData->numAdvertised++] = - ssl_next_proto_nego_xtn; + return SECSuccess; } - return extension_length; - -loser: - return -1; + *added = PR_TRUE; + return SECSuccess; } -PRInt32 -ssl3_ClientSendAppProtoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes) +SECStatus +ssl3_ClientSendAppProtoXtn(const sslSocket *ss, TLSExtensionData *xtnData, + sslBuffer *buf, PRBool *added) { - PRInt32 extension_length; - unsigned char *alpn_protos = NULL; + SECStatus rv; + const unsigned int len = ss->opt.nextProtoNego.len; /* Renegotiations do not send this extension. */ if (!ss->opt.enableALPN || !ss->opt.nextProtoNego.data || ss->firstHsDone) { - return 0; + return SECSuccess; } - extension_length = 2 /* extension type */ + 2 /* extension length */ + - 2 /* protocol name list length */ + - ss->opt.nextProtoNego.len; + /* 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 (maxBytes < (PRUint32)extension_length) { - return 0; - } - if (append) { - /* NPN requires that the client's fallback protocol is first in the - * list. However, ALPN sends protocols in preference order. So we - * allocate a buffer and move the first protocol to the end of the - * list. */ - SECStatus rv; - const unsigned int len = ss->opt.nextProtoNego.len; + if (len > 0) { + /* Each protocol string is prefixed with a single byte length. */ + unsigned int i; - alpn_protos = PORT_Alloc(len); - if (alpn_protos == NULL) { + rv = sslBuffer_AppendNumber(buf, len, 2); + if (rv != SECSuccess) { return SECFailure; } - if (len > 0) { - /* Each protocol string is prefixed with a single byte length. */ - unsigned int i = ss->opt.nextProtoNego.data[0] + 1; - if (i <= len) { - memcpy(alpn_protos, &ss->opt.nextProtoNego.data[i], len - i); - memcpy(alpn_protos + len - i, ss->opt.nextProtoNego.data, i); - } else { - /* This seems to be invalid data so we'll send as-is. */ - memcpy(alpn_protos, ss->opt.nextProtoNego.data, len); - } - } - rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_app_layer_protocol_xtn, 2); - if (rv != SECSuccess) { - goto loser; - } - rv = ssl3_ExtAppendHandshakeNumber(ss, extension_length - 4, 2); - if (rv != SECSuccess) { - goto loser; - } - rv = ssl3_ExtAppendHandshakeVariable(ss, alpn_protos, len, 2); - PORT_Free(alpn_protos); - alpn_protos = NULL; - if (rv != SECSuccess) { - goto loser; + 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; + } } - xtnData->advertised[xtnData->numAdvertised++] = - ssl_app_layer_protocol_xtn; } - return extension_length; - -loser: - if (alpn_protos) { - PORT_Free(alpn_protos); - } - return -1; + *added = PR_TRUE; + return SECSuccess; } -PRInt32 -ssl3_ServerSendAppProtoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes) +SECStatus +ssl3_ServerSendAppProtoXtn(const sslSocket *ss, TLSExtensionData *xtnData, + sslBuffer *buf, PRBool *added) { - PRInt32 extension_length; + SECStatus rv; - /* we're in over our heads if any of these fail */ + /* We're in over our heads if any of these fail */ PORT_Assert(ss->opt.enableALPN); PORT_Assert(xtnData->nextProto.data); PORT_Assert(xtnData->nextProto.len > 0); PORT_Assert(xtnData->nextProtoState == SSL_NEXT_PROTO_NEGOTIATED); PORT_Assert(!ss->firstHsDone); - extension_length = 2 /* extension type */ + 2 /* extension length */ + - 2 /* protocol name list */ + 1 /* name length */ + - xtnData->nextProto.len; - - if (maxBytes < (PRUint32)extension_length) { - return 0; + rv = sslBuffer_AppendNumber(buf, xtnData->nextProto.len + 1, 2); + if (rv != SECSuccess) { + return SECFailure; } - if (append) { - SECStatus rv; - rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_app_layer_protocol_xtn, 2); - if (rv != SECSuccess) { - return -1; - } - rv = ssl3_ExtAppendHandshakeNumber(ss, extension_length - 4, 2); - if (rv != SECSuccess) { - return -1; - } - rv = ssl3_ExtAppendHandshakeNumber(ss, xtnData->nextProto.len + 1, 2); - if (rv != SECSuccess) { - return -1; - } - rv = ssl3_ExtAppendHandshakeVariable(ss, xtnData->nextProto.data, - xtnData->nextProto.len, 1); - if (rv != SECSuccess) { - return -1; - } + rv = sslBuffer_AppendVariable(buf, xtnData->nextProto.data, + xtnData->nextProto.len, 1); + if (rv != SECSuccess) { + return SECFailure; } - return extension_length; + *added = PR_TRUE; + return SECSuccess; } SECStatus -ssl3_ServerHandleStatusRequestXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, +ssl3_ServerHandleStatusRequestXtn(const sslSocket *ss, TLSExtensionData *xtnData, SECItem *data) { - ssl3HelloExtensionSenderFunc sender; + sslExtensionBuilderFunc sender; PORT_Assert(ss->sec.isServer); /* remember that we got this extension. */ - xtnData->negotiated[xtnData->numNegotiated++] = ex_type; + xtnData->negotiated[xtnData->numNegotiated++] = ssl_cert_status_xtn; if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) { sender = tls13_ServerSendStatusRequestXtn; } else { sender = ssl3_ServerSendStatusRequestXtn; } - return ssl3_RegisterExtensionSender(ss, xtnData, ex_type, sender); + return ssl3_RegisterExtensionSender(ss, xtnData, ssl_cert_status_xtn, sender); } -PRInt32 -ssl3_ServerSendStatusRequestXtn( - const sslSocket *ss, - TLSExtensionData *xtnData, - PRBool append, - PRUint32 maxBytes) +SECStatus +ssl3_ServerSendStatusRequestXtn(const sslSocket *ss, TLSExtensionData *xtnData, + sslBuffer *buf, PRBool *added) { - PRInt32 extension_length; const sslServerCert *serverCert = ss->sec.serverCert; - SECStatus rv; if (!serverCert->certStatusArray || !serverCert->certStatusArray->len) { - return 0; - } - - extension_length = 2 + 2; - if (maxBytes < (PRUint32)extension_length) { - return 0; - } - if (append) { - /* extension_type */ - rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_cert_status_xtn, 2); - if (rv != SECSuccess) - return -1; - /* length of extension_data */ - rv = ssl3_ExtAppendHandshakeNumber(ss, 0, 2); - if (rv != SECSuccess) - return -1; - /* The certificate status data is sent in ssl3_SendCertificateStatus. */ + return SECSuccess; } - return extension_length; + *added = PR_TRUE; + return SECSuccess; } /* ssl3_ClientSendStatusRequestXtn builds the status_request extension on the * client side. See RFC 6066 section 8. */ -PRInt32 -ssl3_ClientSendStatusRequestXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, - PRUint32 maxBytes) +SECStatus +ssl3_ClientSendStatusRequestXtn(const sslSocket *ss, TLSExtensionData *xtnData, + sslBuffer *buf, PRBool *added) { - PRInt32 extension_length; - - if (!ss->opt.enableOCSPStapling) - return 0; - - /* extension_type (2-bytes) + - * length(extension_data) (2-bytes) + - * status_type (1) + - * responder_id_list length (2) + - * request_extensions length (2) - */ - extension_length = 9; + SECStatus rv; - if (maxBytes < (PRUint32)extension_length) { - PORT_Assert(0); - return 0; + if (!ss->opt.enableOCSPStapling) { + return SECSuccess; } - if (append) { - SECStatus rv; - /* extension_type */ - rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_cert_status_xtn, 2); - if (rv != SECSuccess) - return -1; - rv = ssl3_ExtAppendHandshakeNumber(ss, extension_length - 4, 2); - if (rv != SECSuccess) - return -1; - rv = ssl3_ExtAppendHandshakeNumber(ss, 1 /* status_type ocsp */, 1); - if (rv != SECSuccess) - return -1; - /* A zero length responder_id_list means that the responders are - * implicitly known to the server. */ - rv = ssl3_ExtAppendHandshakeNumber(ss, 0, 2); - if (rv != SECSuccess) - return -1; - /* A zero length request_extensions means that there are no extensions. - * Specifically, we don't set the id-pkix-ocsp-nonce extension. This - * means that the server can replay a cached OCSP response to us. */ - rv = ssl3_ExtAppendHandshakeNumber(ss, 0, 2); - if (rv != SECSuccess) - return -1; - - xtnData->advertised[xtnData->numAdvertised++] = ssl_cert_status_xtn; + rv = sslBuffer_AppendNumber(buf, 1 /* status_type ocsp */, 1); + if (rv != SECSuccess) { + return SECFailure; + } + /* A zero length responder_id_list means that the responders are + * implicitly known to the server. */ + rv = sslBuffer_AppendNumber(buf, 0, 2); + if (rv != SECSuccess) { + return SECFailure; } - return extension_length; + /* A zero length request_extensions means that there are no extensions. + * Specifically, we don't set the id-pkix-ocsp-nonce extension. This + * means that the server can replay a cached OCSP response to us. */ + rv = sslBuffer_AppendNumber(buf, 0, 2); + if (rv != SECSuccess) { + return SECFailure; + } + + *added = PR_TRUE; + return SECSuccess; } SECStatus -ssl3_ClientHandleStatusRequestXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, +ssl3_ClientHandleStatusRequestXtn(const sslSocket *ss, TLSExtensionData *xtnData, SECItem *data) { /* In TLS 1.3, the extension carries the OCSP response. */ @@ -797,36 +649,32 @@ ssl3_ClientHandleStatusRequestXtn(const sslSocket *ss, TLSExtensionData *xtnData } /* Keep track of negotiated extensions. */ - xtnData->negotiated[xtnData->numNegotiated++] = ex_type; + xtnData->negotiated[xtnData->numNegotiated++] = ssl_cert_status_xtn; return SECSuccess; } PRUint32 ssl_ticket_lifetime = 2 * 24 * 60 * 60; /* 2 days in seconds */ -#define TLS_EX_SESS_TICKET_VERSION (0x0105) +#define TLS_EX_SESS_TICKET_VERSION (0x010a) /* * Called from ssl3_SendNewSessionTicket, tls13_SendNewSessionTicket */ SECStatus -ssl3_EncodeSessionTicket(sslSocket *ss, - const NewSessionTicket *ticket, - SECItem *ticket_data) +ssl3_EncodeSessionTicket(sslSocket *ss, const NewSessionTicket *ticket, + const PRUint8 *appToken, unsigned int appTokenLen, + PK11SymKey *secret, SECItem *ticket_data) { SECStatus rv; - SECItem plaintext; - SECItem plaintext_item = { 0, NULL, 0 }; - PRUint32 plaintext_length; + sslBuffer plaintext = SSL_BUFFER_EMPTY; SECItem ticket_buf = { 0, NULL, 0 }; - PRBool ms_is_wrapped; + sslSessionID sid; unsigned char wrapped_ms[SSL3_MASTER_SECRET_LENGTH]; SECItem ms_item = { 0, NULL, 0 }; - PRUint32 cert_length = 0; - PRUint32 now; + PRTime now; SECItem *srvName = NULL; - CK_MECHANISM_TYPE msWrapMech = 0; /* dummy default value, - * must be >= 0 */ - ssl3CipherSpec *spec; + CK_MECHANISM_TYPE msWrapMech; SECItem *alpnSelection = NULL; + PRUint32 ticketAgeBaseline; SSL_TRC(3, ("%d: SSL3[%d]: send session_ticket handshake", SSL_GETPID(), ss->fd)); @@ -834,107 +682,69 @@ ssl3_EncodeSessionTicket(sslSocket *ss, PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); - if (ss->opt.requestCertificate && ss->sec.ci.sid->peerCert) { - cert_length = 2 + ss->sec.ci.sid->peerCert->derCert.len; - } + /* Extract the master secret wrapped. */ - if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) { - spec = ss->ssl3.cwSpec; - } else { - spec = ss->ssl3.pwSpec; - } - if (spec->msItem.len && spec->msItem.data) { - /* The master secret is available unwrapped. */ - ms_item.data = spec->msItem.data; - ms_item.len = spec->msItem.len; - ms_is_wrapped = PR_FALSE; - } else { - /* Extract the master secret wrapped. */ - sslSessionID sid; - PORT_Memset(&sid, 0, sizeof(sslSessionID)); + PORT_Memset(&sid, 0, sizeof(sslSessionID)); - rv = ssl3_CacheWrappedMasterSecret(ss, &sid, spec); - if (rv == SECSuccess) { - if (sid.u.ssl3.keys.wrapped_master_secret_len > sizeof(wrapped_ms)) - goto loser; - memcpy(wrapped_ms, sid.u.ssl3.keys.wrapped_master_secret, - sid.u.ssl3.keys.wrapped_master_secret_len); - ms_item.data = wrapped_ms; - ms_item.len = sid.u.ssl3.keys.wrapped_master_secret_len; - msWrapMech = sid.u.ssl3.masterWrapMech; - } else { - /* TODO: else send an empty ticket. */ + PORT_Assert(secret); + rv = ssl3_CacheWrappedSecret(ss, &sid, secret); + if (rv == SECSuccess) { + if (sid.u.ssl3.keys.wrapped_master_secret_len > sizeof(wrapped_ms)) goto loser; - } - ms_is_wrapped = PR_TRUE; + memcpy(wrapped_ms, sid.u.ssl3.keys.wrapped_master_secret, + sid.u.ssl3.keys.wrapped_master_secret_len); + ms_item.data = wrapped_ms; + ms_item.len = sid.u.ssl3.keys.wrapped_master_secret_len; + msWrapMech = sid.u.ssl3.masterWrapMech; + } else { + /* TODO: else send an empty ticket. */ + goto loser; } /* Prep to send negotiated name */ srvName = &ss->sec.ci.sid->u.ssl3.srvName; - PORT_Assert(ss->xtnData.nextProtoState == SSL_NEXT_PROTO_SELECTED || - ss->xtnData.nextProtoState == SSL_NEXT_PROTO_NEGOTIATED || - ss->xtnData.nextProto.len == 0); - alpnSelection = &ss->xtnData.nextProto; - - plaintext_length = - sizeof(PRUint16) /* ticket version */ - + sizeof(SSL3ProtocolVersion) /* ssl_version */ - + sizeof(ssl3CipherSuite) /* ciphersuite */ - + 1 /* compression */ - + 10 /* cipher spec parameters */ - + 1 /* certType arguments */ - + 1 /* SessionTicket.ms_is_wrapped */ - + 4 /* msWrapMech */ - + 2 /* master_secret.length */ - + ms_item.len /* master_secret */ - + 1 /* client_auth_type */ - + cert_length /* cert */ - + 2 + srvName->len /* name len + length field */ - + 1 /* extendedMasterSecretUsed */ - + sizeof(ticket->ticket_lifetime_hint) /* ticket lifetime hint */ - + sizeof(ticket->flags) /* ticket flags */ - + 1 + alpnSelection->len /* alpn value + length field */ - + 4; /* maxEarlyData */ - - if (SECITEM_AllocItem(NULL, &plaintext_item, plaintext_length) == NULL) - goto loser; - - plaintext = plaintext_item; - /* ticket version */ - rv = ssl3_AppendNumberToItem(&plaintext, TLS_EX_SESS_TICKET_VERSION, - sizeof(PRUint16)); + rv = sslBuffer_AppendNumber(&plaintext, TLS_EX_SESS_TICKET_VERSION, + sizeof(PRUint16)); if (rv != SECSuccess) goto loser; /* ssl_version */ - rv = ssl3_AppendNumberToItem(&plaintext, ss->version, - sizeof(SSL3ProtocolVersion)); + rv = sslBuffer_AppendNumber(&plaintext, ss->version, + sizeof(SSL3ProtocolVersion)); if (rv != SECSuccess) goto loser; /* ciphersuite */ - rv = ssl3_AppendNumberToItem(&plaintext, ss->ssl3.hs.cipher_suite, - sizeof(ssl3CipherSuite)); + rv = sslBuffer_AppendNumber(&plaintext, ss->ssl3.hs.cipher_suite, + sizeof(ssl3CipherSuite)); if (rv != SECSuccess) goto loser; - /* compression */ - rv = ssl3_AppendNumberToItem(&plaintext, ss->ssl3.hs.compression, 1); + /* cipher spec parameters */ + rv = sslBuffer_AppendNumber(&plaintext, ss->sec.authType, 1); if (rv != SECSuccess) goto loser; - - /* cipher spec parameters */ - rv = ssl3_AppendNumberToItem(&plaintext, ss->sec.authType, 1); + rv = sslBuffer_AppendNumber(&plaintext, ss->sec.authKeyBits, 4); if (rv != SECSuccess) goto loser; - rv = ssl3_AppendNumberToItem(&plaintext, ss->sec.authKeyBits, 4); + rv = sslBuffer_AppendNumber(&plaintext, ss->sec.keaType, 1); if (rv != SECSuccess) goto loser; - rv = ssl3_AppendNumberToItem(&plaintext, ss->sec.keaType, 1); + rv = sslBuffer_AppendNumber(&plaintext, ss->sec.keaKeyBits, 4); if (rv != SECSuccess) goto loser; - rv = ssl3_AppendNumberToItem(&plaintext, ss->sec.keaKeyBits, 4); + if (ss->sec.keaGroup) { + rv = sslBuffer_AppendNumber(&plaintext, ss->sec.keaGroup->name, 4); + if (rv != SECSuccess) + goto loser; + } else { + /* No kea group. Write 0 as invalid value. */ + rv = sslBuffer_AppendNumber(&plaintext, 0, 4); + if (rv != SECSuccess) + goto loser; + } + rv = sslBuffer_AppendNumber(&plaintext, ss->sec.signatureScheme, 4); if (rv != SECSuccess) goto loser; @@ -945,102 +755,120 @@ ssl3_EncodeSessionTicket(sslSocket *ss, PORT_Assert(cert->namedCurve); /* EC curves only use the second of the two bytes. */ PORT_Assert(cert->namedCurve->name < 256); - rv = ssl3_AppendNumberToItem(&plaintext, cert->namedCurve->name, 1); + rv = sslBuffer_AppendNumber(&plaintext, cert->namedCurve->name, 1); } else { - rv = ssl3_AppendNumberToItem(&plaintext, 0, 1); + rv = sslBuffer_AppendNumber(&plaintext, 0, 1); } if (rv != SECSuccess) goto loser; /* master_secret */ - rv = ssl3_AppendNumberToItem(&plaintext, ms_is_wrapped, 1); + rv = sslBuffer_AppendNumber(&plaintext, msWrapMech, 4); if (rv != SECSuccess) goto loser; - rv = ssl3_AppendNumberToItem(&plaintext, msWrapMech, 4); - if (rv != SECSuccess) - goto loser; - rv = ssl3_AppendNumberToItem(&plaintext, ms_item.len, 2); - if (rv != SECSuccess) - goto loser; - rv = ssl3_AppendToItem(&plaintext, ms_item.data, ms_item.len); + rv = sslBuffer_AppendVariable(&plaintext, ms_item.data, ms_item.len, 2); if (rv != SECSuccess) goto loser; /* client identity */ if (ss->opt.requestCertificate && ss->sec.ci.sid->peerCert) { - rv = ssl3_AppendNumberToItem(&plaintext, CLIENT_AUTH_CERTIFICATE, 1); + rv = sslBuffer_AppendNumber(&plaintext, CLIENT_AUTH_CERTIFICATE, 1); if (rv != SECSuccess) goto loser; - rv = ssl3_AppendNumberToItem(&plaintext, - ss->sec.ci.sid->peerCert->derCert.len, 2); - if (rv != SECSuccess) - goto loser; - rv = ssl3_AppendToItem(&plaintext, - ss->sec.ci.sid->peerCert->derCert.data, - ss->sec.ci.sid->peerCert->derCert.len); + rv = sslBuffer_AppendVariable(&plaintext, + ss->sec.ci.sid->peerCert->derCert.data, + ss->sec.ci.sid->peerCert->derCert.len, 2); if (rv != SECSuccess) goto loser; } else { - rv = ssl3_AppendNumberToItem(&plaintext, 0, 1); + rv = sslBuffer_AppendNumber(&plaintext, 0, 1); if (rv != SECSuccess) goto loser; } /* timestamp */ - now = ssl_Time(); - rv = ssl3_AppendNumberToItem(&plaintext, now, - sizeof(ticket->ticket_lifetime_hint)); + now = ssl_TimeUsec(); + PORT_Assert(sizeof(now) == 8); + rv = sslBuffer_AppendNumber(&plaintext, now, 8); if (rv != SECSuccess) goto loser; /* HostName (length and value) */ - rv = ssl3_AppendNumberToItem(&plaintext, srvName->len, 2); + rv = sslBuffer_AppendVariable(&plaintext, srvName->data, srvName->len, 2); if (rv != SECSuccess) goto loser; - if (srvName->len) { - rv = ssl3_AppendToItem(&plaintext, srvName->data, srvName->len); - if (rv != SECSuccess) - goto loser; - } /* extendedMasterSecretUsed */ - rv = ssl3_AppendNumberToItem( + rv = sslBuffer_AppendNumber( &plaintext, ss->sec.ci.sid->u.ssl3.keys.extendedMasterSecretUsed, 1); if (rv != SECSuccess) goto loser; /* Flags */ - rv = ssl3_AppendNumberToItem(&plaintext, ticket->flags, - sizeof(ticket->flags)); + rv = sslBuffer_AppendNumber(&plaintext, ticket->flags, + sizeof(ticket->flags)); if (rv != SECSuccess) goto loser; /* ALPN value. */ + PORT_Assert(ss->xtnData.nextProtoState == SSL_NEXT_PROTO_SELECTED || + ss->xtnData.nextProtoState == SSL_NEXT_PROTO_NEGOTIATED || + ss->xtnData.nextProto.len == 0); + alpnSelection = &ss->xtnData.nextProto; PORT_Assert(alpnSelection->len < 256); - rv = ssl3_AppendNumberToItem(&plaintext, alpnSelection->len, 1); + rv = sslBuffer_AppendVariable(&plaintext, alpnSelection->data, + alpnSelection->len, 1); if (rv != SECSuccess) goto loser; - if (alpnSelection->len) { - rv = ssl3_AppendToItem(&plaintext, alpnSelection->data, - alpnSelection->len); - if (rv != SECSuccess) - goto loser; - } - rv = ssl3_AppendNumberToItem(&plaintext, ssl_max_early_data_size, 4); + rv = sslBuffer_AppendNumber(&plaintext, ss->opt.maxEarlyDataSize, 4); if (rv != SECSuccess) goto loser; - /* Check that we are totally full. */ - PORT_Assert(plaintext.len == 0); + /* + * We store this in the ticket: + * ticket_age_baseline = 1rtt - ticket_age_add + * + * When the client resumes, it will provide: + * obfuscated_age = ticket_age_client + ticket_age_add + * + * We expect to receive the ticket at: + * ticket_create + 1rtt + ticket_age_server + * + * We calculate the client's estimate of this as: + * ticket_create + ticket_age_baseline + obfuscated_age + * = ticket_create + 1rtt + ticket_age_client + * + * This is compared to the expected time, which should differ only as a + * result of clock errors or errors in the RTT estimate. + */ + ticketAgeBaseline = (ssl_TimeUsec() - ss->ssl3.hs.serverHelloTime) / PR_USEC_PER_MSEC; + ticketAgeBaseline -= ticket->ticket_age_add; + rv = sslBuffer_AppendNumber(&plaintext, ticketAgeBaseline, 4); + if (rv != SECSuccess) + goto loser; - /* 128 just gives us enough room for overhead. */ - if (SECITEM_AllocItem(NULL, &ticket_buf, plaintext_length + 128) == NULL) { + /* Application token */ + rv = sslBuffer_AppendVariable(&plaintext, appToken, appTokenLen, 2); + if (rv != SECSuccess) + goto loser; + + /* This really only happens if appTokenLen is too much, and that always + * comes from the using application. */ + if (SSL_BUFFER_LEN(&plaintext) > 0xffff) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + goto loser; + } + + ticket_buf.len = ssl_SelfEncryptGetProtectedSize(SSL_BUFFER_LEN(&plaintext)); + PORT_Assert(ticket_buf.len > 0); + if (SECITEM_AllocItem(NULL, &ticket_buf, ticket_buf.len) == NULL) { goto loser; } /* Finally, encrypt the ticket. */ - rv = ssl_SelfEncryptProtect(ss, plaintext_item.data, plaintext_item.len, + rv = ssl_SelfEncryptProtect(ss, SSL_BUFFER_BASE(&plaintext), + SSL_BUFFER_LEN(&plaintext), ticket_buf.data, &ticket_buf.len, ticket_buf.len); if (rv != SECSuccess) { goto loser; @@ -1049,13 +877,11 @@ ssl3_EncodeSessionTicket(sslSocket *ss, /* Give ownership of memory to caller. */ *ticket_data = ticket_buf; - SECITEM_FreeItem(&plaintext_item, PR_FALSE); + sslBuffer_Clear(&plaintext); return SECSuccess; loser: - if (plaintext_item.data) { - SECITEM_FreeItem(&plaintext_item, PR_FALSE); - } + sslBuffer_Clear(&plaintext); if (ticket_buf.data) { SECITEM_FreeItem(&ticket_buf, PR_FALSE); } @@ -1067,18 +893,22 @@ loser: * message is expected during the handshake. */ SECStatus -ssl3_ClientHandleSessionTicketXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, +ssl3_ClientHandleSessionTicketXtn(const sslSocket *ss, TLSExtensionData *xtnData, SECItem *data) { + PORT_Assert(ss->version < SSL_LIBRARY_VERSION_TLS_1_3); + if (data->len != 0) { return SECSuccess; /* Ignore the extension. */ } /* Keep track of negotiated extensions. */ - xtnData->negotiated[xtnData->numNegotiated++] = ex_type; + xtnData->negotiated[xtnData->numNegotiated++] = ssl_session_ticket_xtn; return SECSuccess; } +PR_STATIC_ASSERT((TLS_EX_SESS_TICKET_VERSION >> 8) == 1); + static SECStatus ssl_ParseSessionTicket(sslSocket *ss, const SECItem *decryptedTicket, SessionTicket *parsedTicket) @@ -1105,6 +935,12 @@ ssl_ParseSessionTicket(sslSocket *ss, const SECItem *decryptedTicket, return SECFailure; } + /* All ticket versions start with 0x01, so check to see if this + * is a ticket or some other self-encrypted thing. */ + if ((temp >> 8) != 1) { + PORT_SetError(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO); + return SECFailure; + } /* Skip the ticket if the version is wrong. This won't result in a * handshake failure, just a failure to resume. */ if (temp != TLS_EX_SESS_TICKET_VERSION) { @@ -1132,14 +968,6 @@ ssl_ParseSessionTicket(sslSocket *ss, const SECItem *decryptedTicket, } parsedTicket->cipher_suite = (ssl3CipherSuite)temp; - /* Read compression_method. */ - rv = ssl3_ExtConsumeHandshakeNumber(ss, &temp, 1, &buffer, &len); - if (rv != SECSuccess) { - PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); - return SECFailure; - } - parsedTicket->compression_method = (SSLCompressionMethod)temp; - /* Read cipher spec parameters. */ rv = ssl3_ExtConsumeHandshakeNumber(ss, &temp, 1, &buffer, &len); if (rv != SECSuccess) { @@ -1165,6 +993,18 @@ ssl_ParseSessionTicket(sslSocket *ss, const SECItem *decryptedTicket, return SECFailure; } parsedTicket->keaKeyBits = temp; + rv = ssl3_ExtConsumeHandshakeNumber(ss, &temp, 4, &buffer, &len); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + parsedTicket->originalKeaGroup = temp; + rv = ssl3_ExtConsumeHandshakeNumber(ss, &temp, 4, &buffer, &len); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + parsedTicket->signatureScheme = (SSLSignatureScheme)temp; /* Read the optional named curve. */ rv = ssl3_ExtConsumeHandshakeNumber(ss, &temp, 1, &buffer, &len); @@ -1185,14 +1025,6 @@ ssl_ParseSessionTicket(sslSocket *ss, const SECItem *decryptedTicket, } /* Read the master secret (and how it is wrapped). */ - rv = ssl3_ExtConsumeHandshakeNumber(ss, &temp, 1, &buffer, &len); - if (rv != SECSuccess) { - PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); - return SECFailure; - } - PORT_Assert(temp == PR_TRUE || temp == PR_FALSE); - parsedTicket->ms_is_wrapped = (PRBool)temp; - rv = ssl3_ExtConsumeHandshakeNumber(ss, &temp, 4, &buffer, &len); if (rv != SECSuccess) { PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); @@ -1240,13 +1072,21 @@ ssl_ParseSessionTicket(sslSocket *ss, const SECItem *decryptedTicket, PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); return SECFailure; } - /* Read timestamp. */ + + /* Read timestamp. This is a 64-bit value and + * ssl3_ExtConsumeHandshakeNumber only reads 32-bits at a time. */ rv = ssl3_ExtConsumeHandshakeNumber(ss, &temp, 4, &buffer, &len); if (rv != SECSuccess) { PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); return SECFailure; } - parsedTicket->timestamp = temp; + parsedTicket->timestamp = (PRTime)temp << 32; + rv = ssl3_ExtConsumeHandshakeNumber(ss, &temp, 4, &buffer, &len); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + parsedTicket->timestamp |= (PRTime)temp; /* Read server name */ rv = ssl3_ExtConsumeHandshakeVariable(ss, &parsedTicket->srvName, 2, @@ -1287,6 +1127,20 @@ ssl_ParseSessionTicket(sslSocket *ss, const SECItem *decryptedTicket, } parsedTicket->maxEarlyData = temp; + rv = ssl3_ExtConsumeHandshakeNumber(ss, &temp, 4, &buffer, &len); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + parsedTicket->ticketAgeBaseline = temp; + + rv = ssl3_ExtConsumeHandshakeVariable(ss, &parsedTicket->applicationToken, + 2, &buffer, &len); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + #ifndef UNSAFE_FUZZER_MODE /* Done parsing. Check that all bytes have been consumed. */ if (len != 0) { @@ -1313,13 +1167,15 @@ ssl_CreateSIDFromTicket(sslSocket *ss, const SECItem *rawTicket, /* Copy over parameters. */ sid->version = parsedTicket->ssl_version; + sid->creationTime = parsedTicket->timestamp; sid->u.ssl3.cipherSuite = parsedTicket->cipher_suite; - sid->u.ssl3.compression = parsedTicket->compression_method; sid->authType = parsedTicket->authType; sid->authKeyBits = parsedTicket->authKeyBits; sid->keaType = parsedTicket->keaType; sid->keaKeyBits = parsedTicket->keaKeyBits; + sid->keaGroup = parsedTicket->originalKeaGroup; sid->namedCurve = parsedTicket->namedCurve; + sid->sigScheme = parsedTicket->signatureScheme; rv = SECITEM_CopyItem(NULL, &sid->u.ssl3.locked.sessionTicket.ticket, rawTicket); @@ -1338,7 +1194,6 @@ ssl_CreateSIDFromTicket(sslSocket *ss, const SECItem *rawTicket, parsedTicket->master_secret, parsedTicket->ms_length); sid->u.ssl3.keys.wrapped_master_secret_len = parsedTicket->ms_length; sid->u.ssl3.masterWrapMech = parsedTicket->msWrapMech; - sid->u.ssl3.keys.msIsWrapped = parsedTicket->ms_is_wrapped; sid->u.ssl3.masterValid = PR_TRUE; sid->u.ssl3.keys.resumable = PR_TRUE; sid->u.ssl3.keys.extendedMasterSecretUsed = parsedTicket->extendedMasterSecretUsed; @@ -1364,6 +1219,7 @@ ssl_CreateSIDFromTicket(sslSocket *ss, const SECItem *rawTicket, } } if (parsedTicket->alpnSelection.data != NULL) { + SECITEM_FreeItem(&sid->u.ssl3.alpnSelection, PR_FALSE); rv = SECITEM_CopyItem(NULL, &sid->u.ssl3.alpnSelection, &parsedTicket->alpnSelection); if (rv != SECSuccess) { @@ -1381,24 +1237,26 @@ loser: /* Generic ticket processing code, common to all TLS versions. */ SECStatus -ssl3_ProcessSessionTicketCommon(sslSocket *ss, SECItem *data) +ssl3_ProcessSessionTicketCommon(sslSocket *ss, const SECItem *ticket, + SECItem *appToken) { SECItem decryptedTicket = { siBuffer, NULL, 0 }; SessionTicket parsedTicket; + sslSessionID *sid = NULL; SECStatus rv; if (ss->sec.ci.sid != NULL) { - ss->sec.uncache(ss->sec.ci.sid); + ssl_UncacheSessionID(ss); ssl_FreeSID(ss->sec.ci.sid); ss->sec.ci.sid = NULL; } - if (!SECITEM_AllocItem(NULL, &decryptedTicket, data->len)) { + if (!SECITEM_AllocItem(NULL, &decryptedTicket, ticket->len)) { return SECFailure; } /* Decrypt the ticket. */ - rv = ssl_SelfEncryptUnprotect(ss, data->data, data->len, + rv = ssl_SelfEncryptUnprotect(ss, ticket->data, ticket->len, decryptedTicket.data, &decryptedTicket.len, decryptedTicket.len); @@ -1428,16 +1286,28 @@ ssl3_ProcessSessionTicketCommon(sslSocket *ss, SECItem *data) } /* Use the ticket if it is valid and unexpired. */ - if (parsedTicket.valid && - parsedTicket.timestamp + ssl_ticket_lifetime > ssl_Time()) { - sslSessionID *sid; + if (parsedTicket.timestamp + ssl_ticket_lifetime * PR_USEC_PER_SEC > + ssl_TimeUsec()) { - rv = ssl_CreateSIDFromTicket(ss, data, &parsedTicket, &sid); + rv = ssl_CreateSIDFromTicket(ss, ticket, &parsedTicket, &sid); if (rv != SECSuccess) { goto loser; /* code already set */ } + if (appToken && parsedTicket.applicationToken.len) { + rv = SECITEM_CopyItem(NULL, appToken, + &parsedTicket.applicationToken); + if (rv != SECSuccess) { + goto loser; /* code already set */ + } + } + ss->statelessResume = PR_TRUE; ss->sec.ci.sid = sid; + + /* We have the baseline value for the obfuscated ticket age here. Save + * that in xtnData temporarily. This value is updated in + * tls13_ServerHandlePreSharedKeyXtn with the final estimate. */ + ss->xtnData.ticketAge = parsedTicket.ticketAgeBaseline; } SECITEM_ZfreeItem(&decryptedTicket, PR_FALSE); @@ -1445,15 +1315,19 @@ ssl3_ProcessSessionTicketCommon(sslSocket *ss, SECItem *data) return SECSuccess; loser: + if (sid) { + ssl_FreeSID(sid); + } SECITEM_ZfreeItem(&decryptedTicket, PR_FALSE); PORT_Memset(&parsedTicket, 0, sizeof(parsedTicket)); return SECFailure; } SECStatus -ssl3_ServerHandleSessionTicketXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, +ssl3_ServerHandleSessionTicketXtn(const sslSocket *ss, TLSExtensionData *xtnData, SECItem *data) { + PORT_Assert(ss->version < SSL_LIBRARY_VERSION_TLS_1_3); /* Ignore the SessionTicket extension if processing is disabled. */ if (!ss->opt.enableSessionTickets) { @@ -1466,7 +1340,7 @@ ssl3_ServerHandleSessionTicketXtn(const sslSocket *ss, TLSExtensionData *xtnData } /* Keep track of negotiated extensions. */ - xtnData->negotiated[xtnData->numNegotiated++] = ex_type; + xtnData->negotiated[xtnData->numNegotiated++] = ssl_session_ticket_xtn; /* Parse the received ticket sent in by the client. We are * lenient about some parse errors, falling back to a fullshake @@ -1477,7 +1351,8 @@ ssl3_ServerHandleSessionTicketXtn(const sslSocket *ss, TLSExtensionData *xtnData return SECSuccess; } - return ssl3_ProcessSessionTicketCommon(CONST_CAST(sslSocket, ss), data); + return ssl3_ProcessSessionTicketCommon(CONST_CAST(sslSocket, ss), data, + NULL); } /* Extension format: @@ -1487,60 +1362,45 @@ ssl3_ServerHandleSessionTicketXtn(const sslSocket *ss, TLSExtensionData *xtnData * Verify Data (TLS): 12 bytes (client) or 24 bytes (server) * Verify Data (SSL): 36 bytes (client) or 72 bytes (server) */ -PRInt32 -ssl3_SendRenegotiationInfoXtn( - const sslSocket *ss, - TLSExtensionData *xtnData, - PRBool append, - PRUint32 maxBytes) +SECStatus +ssl3_SendRenegotiationInfoXtn(const sslSocket *ss, TLSExtensionData *xtnData, + sslBuffer *buf, PRBool *added) { PRInt32 len = 0; - PRInt32 needed; + SECStatus rv; - /* In draft-ietf-tls-renegotiation-03, it is NOT RECOMMENDED to send - * both the SCSV and the empty RI, so when we send SCSV in - * the initial handshake, we don't also send RI. + /* In RFC 5746, it is NOT RECOMMENDED to send both the SCSV and the empty + * RI, so when we send SCSV in the initial handshake, we don't also send RI. */ - if (!ss || ss->ssl3.hs.sendingSCSV) + if (ss->ssl3.hs.sendingSCSV) { return 0; + } if (ss->firstHsDone) { len = ss->sec.isServer ? ss->ssl3.hs.finishedBytes * 2 : ss->ssl3.hs.finishedBytes; } - needed = 5 + len; - if (maxBytes < (PRUint32)needed) { - return 0; - } - if (append) { - SECStatus rv; - /* extension_type */ - rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_renegotiation_info_xtn, 2); - if (rv != SECSuccess) - return -1; - /* length of extension_data */ - rv = ssl3_ExtAppendHandshakeNumber(ss, len + 1, 2); - if (rv != SECSuccess) - return -1; - /* verify_Data from previous Finished message(s) */ - rv = ssl3_ExtAppendHandshakeVariable(ss, - ss->ssl3.hs.finishedMsgs.data, len, 1); - if (rv != SECSuccess) - return -1; - if (!ss->sec.isServer) { - xtnData->advertised[xtnData->numAdvertised++] = - ssl_renegotiation_info_xtn; - } + + /* verify_Data from previous Finished message(s) */ + rv = sslBuffer_AppendVariable(buf, + ss->ssl3.hs.finishedMsgs.data, len, 1); + if (rv != SECSuccess) { + return SECFailure; } - return needed; + + *added = PR_TRUE; + return SECSuccess; } /* This function runs in both the client and server. */ SECStatus -ssl3_HandleRenegotiationInfoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data) +ssl3_HandleRenegotiationInfoXtn(const sslSocket *ss, TLSExtensionData *xtnData, + SECItem *data) { SECStatus rv = SECSuccess; PRUint32 len = 0; + PORT_Assert(ss->version < SSL_LIBRARY_VERSION_TLS_1_3); + if (ss->firstHsDone) { len = ss->sec.isServer ? ss->ssl3.hs.finishedBytes : ss->ssl3.hs.finishedBytes * 2; @@ -1558,97 +1418,78 @@ ssl3_HandleRenegotiationInfoXtn(const sslSocket *ss, TLSExtensionData *xtnData, /* remember that we got this extension and it was correct. */ CONST_CAST(sslSocket, ss) ->peerRequestedProtection = 1; - xtnData->negotiated[xtnData->numNegotiated++] = ex_type; + xtnData->negotiated[xtnData->numNegotiated++] = ssl_renegotiation_info_xtn; if (ss->sec.isServer) { /* prepare to send back the appropriate response */ - rv = ssl3_RegisterExtensionSender(ss, xtnData, ex_type, + rv = ssl3_RegisterExtensionSender(ss, xtnData, + ssl_renegotiation_info_xtn, ssl3_SendRenegotiationInfoXtn); } return rv; } -PRInt32 -ssl3_ClientSendUseSRTPXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes) +SECStatus +ssl3_ClientSendUseSRTPXtn(const sslSocket *ss, TLSExtensionData *xtnData, + sslBuffer *buf, PRBool *added) { - PRUint32 ext_data_len; - PRInt16 i; + unsigned int i; SECStatus rv; - if (!ss) - return 0; - - if (!IS_DTLS(ss) || !ss->ssl3.dtlsSRTPCipherCount) - return 0; /* Not relevant */ - - ext_data_len = 2 + 2 * ss->ssl3.dtlsSRTPCipherCount + 1; + if (!IS_DTLS(ss) || !ss->ssl3.dtlsSRTPCipherCount) { + return SECSuccess; /* Not relevant */ + } - if (append && maxBytes >= 4 + ext_data_len) { - /* Extension type */ - rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_use_srtp_xtn, 2); - if (rv != SECSuccess) - return -1; - /* Length of extension data */ - rv = ssl3_ExtAppendHandshakeNumber(ss, ext_data_len, 2); - if (rv != SECSuccess) - return -1; - /* Length of the SRTP cipher list */ - rv = ssl3_ExtAppendHandshakeNumber(ss, - 2 * ss->ssl3.dtlsSRTPCipherCount, - 2); - if (rv != SECSuccess) - return -1; - /* The SRTP ciphers */ - for (i = 0; i < ss->ssl3.dtlsSRTPCipherCount; i++) { - rv = ssl3_ExtAppendHandshakeNumber(ss, - ss->ssl3.dtlsSRTPCiphers[i], - 2); - if (rv != SECSuccess) - return -1; + /* Length of the SRTP cipher list */ + rv = sslBuffer_AppendNumber(buf, 2 * ss->ssl3.dtlsSRTPCipherCount, 2); + if (rv != SECSuccess) { + return SECFailure; + } + /* The SRTP ciphers */ + for (i = 0; i < ss->ssl3.dtlsSRTPCipherCount; i++) { + rv = sslBuffer_AppendNumber(buf, ss->ssl3.dtlsSRTPCiphers[i], 2); + if (rv != SECSuccess) { + return SECFailure; } - /* Empty MKI value */ - ssl3_ExtAppendHandshakeVariable(ss, NULL, 0, 1); - - xtnData->advertised[xtnData->numAdvertised++] = - ssl_use_srtp_xtn; + } + /* Empty MKI value */ + rv = sslBuffer_AppendNumber(buf, 0, 1); + if (rv != SECSuccess) { + return SECFailure; } - return 4 + ext_data_len; + *added = PR_TRUE; + return SECSuccess; } -PRInt32 -ssl3_ServerSendUseSRTPXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes) +SECStatus +ssl3_ServerSendUseSRTPXtn(const sslSocket *ss, TLSExtensionData *xtnData, + sslBuffer *buf, PRBool *added) { SECStatus rv; - /* Server side */ - if (!append || maxBytes < 9) { - return 9; - } - - /* Extension type */ - rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_use_srtp_xtn, 2); - if (rv != SECSuccess) - return -1; - /* Length of extension data */ - rv = ssl3_ExtAppendHandshakeNumber(ss, 5, 2); - if (rv != SECSuccess) - return -1; /* Length of the SRTP cipher list */ - rv = ssl3_ExtAppendHandshakeNumber(ss, 2, 2); - if (rv != SECSuccess) - return -1; + rv = sslBuffer_AppendNumber(buf, 2, 2); + if (rv != SECSuccess) { + return SECFailure; + } /* The selected cipher */ - rv = ssl3_ExtAppendHandshakeNumber(ss, xtnData->dtlsSRTPCipherSuite, 2); - if (rv != SECSuccess) - return -1; + rv = sslBuffer_AppendNumber(buf, xtnData->dtlsSRTPCipherSuite, 2); + if (rv != SECSuccess) { + return SECFailure; + } /* Empty MKI value */ - ssl3_ExtAppendHandshakeVariable(ss, NULL, 0, 1); + rv = sslBuffer_AppendNumber(buf, 0, 1); + if (rv != SECSuccess) { + return SECFailure; + } - return 9; + *added = PR_TRUE; + return SECSuccess; } SECStatus -ssl3_ClientHandleUseSRTPXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data) +ssl3_ClientHandleUseSRTPXtn(const sslSocket *ss, TLSExtensionData *xtnData, + SECItem *data) { SECStatus rv; SECItem ciphers = { siBuffer, NULL, 0 }; @@ -1718,7 +1559,8 @@ ssl3_ClientHandleUseSRTPXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUi } SECStatus -ssl3_ServerHandleUseSRTPXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data) +ssl3_ServerHandleUseSRTPXtn(const sslSocket *ss, TLSExtensionData *xtnData, + SECItem *data) { SECStatus rv; SECItem ciphers = { siBuffer, NULL, 0 }; @@ -1789,11 +1631,12 @@ ssl3_ServerHandleUseSRTPXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUi ssl3_ServerSendUseSRTPXtn); } -/* ssl3_ServerHandleSigAlgsXtn handles the signature_algorithms extension - * from a client. - * See https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */ +/* ssl3_HandleSigAlgsXtn handles the signature_algorithms extension from a + * client. In TLS 1.3, the client uses this to parse CertificateRequest + * extensions. See https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */ SECStatus -ssl3_ServerHandleSigAlgsXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data) +ssl3_HandleSigAlgsXtn(const sslSocket *ss, TLSExtensionData *xtnData, + SECItem *data) { SECStatus rv; @@ -1802,19 +1645,24 @@ ssl3_ServerHandleSigAlgsXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUi return SECSuccess; } - if (xtnData->clientSigSchemes) { - PORT_Free(xtnData->clientSigSchemes); - xtnData->clientSigSchemes = NULL; + if (xtnData->sigSchemes) { + PORT_Free(xtnData->sigSchemes); + xtnData->sigSchemes = NULL; } rv = ssl_ParseSignatureSchemes(ss, NULL, - &xtnData->clientSigSchemes, - &xtnData->numClientSigScheme, + &xtnData->sigSchemes, + &xtnData->numSigSchemes, &data->data, &data->len); - if (rv != SECSuccess || xtnData->numClientSigScheme == 0) { + if (rv != SECSuccess) { ssl3_ExtSendAlert(ss, alert_fatal, decode_error); PORT_SetError(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO); return SECFailure; } + if (xtnData->numSigSchemes == 0) { + ssl3_ExtSendAlert(ss, alert_fatal, handshake_failure); + PORT_SetError(SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM); + return SECFailure; + } /* Check for trailing data. */ if (data->len != 0) { ssl3_ExtSendAlert(ss, alert_fatal, decode_error); @@ -1823,177 +1671,52 @@ ssl3_ServerHandleSigAlgsXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUi } /* Keep track of negotiated extensions. */ - xtnData->negotiated[xtnData->numNegotiated++] = ex_type; + xtnData->negotiated[xtnData->numNegotiated++] = ssl_signature_algorithms_xtn; return SECSuccess; } /* ssl3_ClientSendSigAlgsXtn sends the signature_algorithm extension for TLS * 1.2 ClientHellos. */ -PRInt32 -ssl3_ClientSendSigAlgsXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes) +SECStatus +ssl3_SendSigAlgsXtn(const sslSocket *ss, TLSExtensionData *xtnData, + sslBuffer *buf, PRBool *added) { - PRInt32 extension_length; - PRUint8 buf[MAX_SIGNATURE_SCHEMES * 2]; - PRUint32 len; SECStatus rv; if (ss->vrange.max < SSL_LIBRARY_VERSION_TLS_1_2) { - return 0; - } - - rv = ssl3_EncodeSigAlgs(ss, buf, sizeof(buf), &len); - if (rv != SECSuccess) { - return -1; - } - - extension_length = - 2 /* extension type */ + - 2 /* extension length */ + - 2 /* supported_signature_algorithms length */ + - len; - - if (maxBytes < extension_length) { - PORT_Assert(0); - return 0; - } - - if (append) { - SECStatus rv; - rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_signature_algorithms_xtn, 2); - if (rv != SECSuccess) { - return -1; - } - rv = ssl3_ExtAppendHandshakeNumber(ss, len + 2, 2); - if (rv != SECSuccess) { - return -1; - } - - rv = ssl3_ExtAppendHandshakeVariable(ss, buf, len, 2); - if (rv != SECSuccess) { - return -1; - } - - xtnData->advertised[xtnData->numAdvertised++] = - ssl_signature_algorithms_xtn; - } - - return extension_length; -} - -/* Takes the size of the ClientHello, less the record header, and determines how - * much padding is required. */ -void -ssl3_CalculatePaddingExtLen(sslSocket *ss, - unsigned int clientHelloLength) -{ - unsigned int recordLength = 1 /* handshake message type */ + - 3 /* handshake message length */ + - clientHelloLength; - unsigned int extensionLen; - - /* Don't pad for DTLS, for SSLv3, or for renegotiation. */ - if (IS_DTLS(ss) || - ss->vrange.max < SSL_LIBRARY_VERSION_TLS_1_0 || - ss->firstHsDone) { - return; - } - - /* A padding extension may be included to ensure that the record containing - * the ClientHello doesn't have a length between 256 and 511 bytes - * (inclusive). Initial ClientHello records with such lengths trigger bugs - * in F5 devices. */ - if (recordLength < 256 || recordLength >= 512) { - return; - } - - extensionLen = 512 - recordLength; - /* Extensions take at least four bytes to encode. Always include at least - * one byte of data if we are padding. Some servers will time out or - * terminate the connection if the last ClientHello extension is empty. */ - if (extensionLen < 4 + 1) { - extensionLen = 4 + 1; - } - - ss->xtnData.paddingLen = extensionLen - 4; -} - -/* ssl3_SendPaddingExtension possibly adds an extension which ensures that a - * ClientHello record is either < 256 bytes or is >= 512 bytes. This ensures - * that we don't trigger bugs in F5 products. */ -PRInt32 -ssl3_ClientSendPaddingExtension(const sslSocket *ss, TLSExtensionData *xtnData, - PRBool append, PRUint32 maxBytes) -{ - static unsigned char padding[252] = { 0 }; - unsigned int extensionLen; - SECStatus rv; - - /* On the length-calculation pass, report zero total length. The record - * will be larger on the second pass if needed. */ - if (!append || !xtnData->paddingLen) { - return 0; - } - - extensionLen = xtnData->paddingLen + 4; - if (extensionLen > maxBytes || - xtnData->paddingLen > sizeof(padding)) { - PORT_Assert(0); - return -1; + return SECSuccess; } - rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_padding_xtn, 2); - if (rv != SECSuccess) { - return -1; - } - rv = ssl3_ExtAppendHandshakeVariable(ss, padding, xtnData->paddingLen, 2); + rv = ssl3_EncodeSigAlgs(ss, buf); if (rv != SECSuccess) { - return -1; + return SECFailure; } - return extensionLen; + *added = PR_TRUE; + return SECSuccess; } -PRInt32 -ssl3_SendExtendedMasterSecretXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, - PRUint32 maxBytes) +SECStatus +ssl3_SendExtendedMasterSecretXtn(const sslSocket *ss, TLSExtensionData *xtnData, + sslBuffer *buf, PRBool *added) { - PRInt32 extension_length; - if (!ss->opt.enableExtendedMS) { - return 0; + return SECSuccess; } /* Always send the extension in this function, since the * client always sends it and this function is only called on * the server if we negotiated the extension. */ - extension_length = 4; /* Type + length (0) */ - if (maxBytes < extension_length) { - PORT_Assert(0); - return 0; - } - - if (append) { - SECStatus rv; - rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_extended_master_secret_xtn, 2); - if (rv != SECSuccess) - goto loser; - rv = ssl3_ExtAppendHandshakeNumber(ss, 0, 2); - if (rv != SECSuccess) - goto loser; - xtnData->advertised[xtnData->numAdvertised++] = - ssl_extended_master_secret_xtn; - } - - return extension_length; - -loser: - return -1; + *added = PR_TRUE; + return SECSuccess; } SECStatus -ssl3_HandleExtendedMasterSecretXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, +ssl3_HandleExtendedMasterSecretXtn(const sslSocket *ss, TLSExtensionData *xtnData, SECItem *data) { + PORT_Assert(ss->version < SSL_LIBRARY_VERSION_TLS_1_3); + if (ss->version < SSL_LIBRARY_VERSION_TLS_1_0) { return SECSuccess; } @@ -2013,54 +1736,34 @@ ssl3_HandleExtendedMasterSecretXtn(const sslSocket *ss, TLSExtensionData *xtnDat SSL_GETPID(), ss->fd)); /* Keep track of negotiated extensions. */ - xtnData->negotiated[xtnData->numNegotiated++] = ex_type; + xtnData->negotiated[xtnData->numNegotiated++] = ssl_extended_master_secret_xtn; if (ss->sec.isServer) { - return ssl3_RegisterExtensionSender( - ss, xtnData, ex_type, ssl3_SendExtendedMasterSecretXtn); + return ssl3_RegisterExtensionSender(ss, xtnData, + ssl_extended_master_secret_xtn, + ssl_SendEmptyExtension); } return SECSuccess; } /* ssl3_ClientSendSignedCertTimestampXtn sends the signed_certificate_timestamp * extension for TLS ClientHellos. */ -PRInt32 -ssl3_ClientSendSignedCertTimestampXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, - PRUint32 maxBytes) +SECStatus +ssl3_ClientSendSignedCertTimestampXtn(const sslSocket *ss, + TLSExtensionData *xtnData, + sslBuffer *buf, PRBool *added) { - PRInt32 extension_length = 2 /* extension_type */ + - 2 /* length(extension_data) */; - /* Only send the extension if processing is enabled. */ - if (!ss->opt.enableSignedCertTimestamps) - return 0; - - if (append && maxBytes >= extension_length) { - SECStatus rv; - /* extension_type */ - rv = ssl3_ExtAppendHandshakeNumber(ss, - ssl_signed_cert_timestamp_xtn, - 2); - if (rv != SECSuccess) - goto loser; - /* zero length */ - rv = ssl3_ExtAppendHandshakeNumber(ss, 0, 2); - if (rv != SECSuccess) - goto loser; - xtnData->advertised[xtnData->numAdvertised++] = - ssl_signed_cert_timestamp_xtn; - } else if (maxBytes < extension_length) { - PORT_Assert(0); - return 0; + if (!ss->opt.enableSignedCertTimestamps) { + return SECSuccess; } - return extension_length; -loser: - return -1; + *added = PR_TRUE; + return SECSuccess; } SECStatus -ssl3_ClientHandleSignedCertTimestampXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, +ssl3_ClientHandleSignedCertTimestampXtn(const sslSocket *ss, TLSExtensionData *xtnData, SECItem *data) { /* We do not yet know whether we'll be resuming a session or creating @@ -2080,54 +1783,34 @@ ssl3_ClientHandleSignedCertTimestampXtn(const sslSocket *ss, TLSExtensionData *x } *scts = *data; /* Keep track of negotiated extensions. */ - xtnData->negotiated[xtnData->numNegotiated++] = ex_type; + xtnData->negotiated[xtnData->numNegotiated++] = ssl_signed_cert_timestamp_xtn; return SECSuccess; } -PRInt32 +SECStatus ssl3_ServerSendSignedCertTimestampXtn(const sslSocket *ss, TLSExtensionData *xtnData, - PRBool append, - PRUint32 maxBytes) + sslBuffer *buf, PRBool *added) { - PRInt32 extension_length; const SECItem *scts = &ss->sec.serverCert->signedCertTimestamps; + SECStatus rv; if (!scts->len) { /* No timestamps to send */ - return 0; + return SECSuccess; } - extension_length = 2 /* extension_type */ + - 2 /* length(extension_data) */ + - scts->len; - - if (maxBytes < extension_length) { - PORT_Assert(0); - return 0; - } - if (append) { - SECStatus rv; - /* extension_type */ - rv = ssl3_ExtAppendHandshakeNumber(ss, - ssl_signed_cert_timestamp_xtn, - 2); - if (rv != SECSuccess) { - return -1; - } - /* extension_data */ - rv = ssl3_ExtAppendHandshakeVariable(ss, scts->data, scts->len, 2); - if (rv != SECSuccess) { - return -1; - } + rv = sslBuffer_Append(buf, scts->data, scts->len); + if (rv != SECSuccess) { + return SECFailure; } - return extension_length; + *added = PR_TRUE; + return SECSuccess; } SECStatus ssl3_ServerHandleSignedCertTimestampXtn(const sslSocket *ss, TLSExtensionData *xtnData, - PRUint16 ex_type, SECItem *data) { if (data->len != 0) { @@ -2136,22 +1819,25 @@ ssl3_ServerHandleSignedCertTimestampXtn(const sslSocket *ss, return SECFailure; } - xtnData->negotiated[xtnData->numNegotiated++] = ex_type; + xtnData->negotiated[xtnData->numNegotiated++] = ssl_signed_cert_timestamp_xtn; PORT_Assert(ss->sec.isServer); - return ssl3_RegisterExtensionSender( - ss, xtnData, ex_type, ssl3_ServerSendSignedCertTimestampXtn); + return ssl3_RegisterExtensionSender(ss, xtnData, + ssl_signed_cert_timestamp_xtn, + ssl3_ServerSendSignedCertTimestampXtn); } /* Just make sure that the remote client supports uncompressed points, * Since that is all we support. Disable ECC cipher suites if it doesn't. */ SECStatus -ssl3_HandleSupportedPointFormatsXtn(const sslSocket *ss, TLSExtensionData *xtnData, - PRUint16 ex_type, +ssl3_HandleSupportedPointFormatsXtn(const sslSocket *ss, + TLSExtensionData *xtnData, SECItem *data) { int i; + PORT_Assert(ss->version < SSL_LIBRARY_VERSION_TLS_1_3); + if (data->len < 2 || data->len > 255 || !data->data || data->len != (unsigned int)data->data[0] + 1) { ssl3_ExtDecodeError(ss); @@ -2160,10 +1846,9 @@ ssl3_HandleSupportedPointFormatsXtn(const sslSocket *ss, TLSExtensionData *xtnDa for (i = data->len; --i > 0;) { if (data->data[i] == 0) { /* indicate that we should send a reply */ - SECStatus rv; - rv = ssl3_RegisterExtensionSender(ss, xtnData, ex_type, - &ssl3_SendSupportedPointFormatsXtn); - return rv; + return ssl3_RegisterExtensionSender( + ss, xtnData, ssl_ec_point_formats_xtn, + &ssl3_SendSupportedPointFormatsXtn); } } @@ -2248,7 +1933,7 @@ ssl_UpdateSupportedGroups(sslSocket *ss, SECItem *data) */ SECStatus ssl_HandleSupportedGroupsXtn(const sslSocket *ss, TLSExtensionData *xtnData, - PRUint16 ex_type, SECItem *data) + SECItem *data) { SECStatus rv; @@ -2258,7 +1943,7 @@ ssl_HandleSupportedGroupsXtn(const sslSocket *ss, TLSExtensionData *xtnData, /* TLS 1.3 permits the server to send this extension so make it so. */ if (ss->sec.isServer && ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) { - rv = ssl3_RegisterExtensionSender(ss, xtnData, ex_type, + rv = ssl3_RegisterExtensionSender(ss, xtnData, ssl_supported_groups_xtn, &ssl_SendSupportedGroupsXtn); if (rv != SECSuccess) { return SECFailure; /* error already set. */ @@ -2266,7 +1951,7 @@ ssl_HandleSupportedGroupsXtn(const sslSocket *ss, TLSExtensionData *xtnData, } /* Remember that we negotiated this extension. */ - xtnData->negotiated[xtnData->numNegotiated++] = ex_type; + xtnData->negotiated[xtnData->numNegotiated++] = ssl_supported_groups_xtn; return SECSuccess; } diff --git a/security/nss/lib/ssl/ssl3exthandle.h b/security/nss/lib/ssl/ssl3exthandle.h index 5fdbe9053..b84bd074c 100644 --- a/security/nss/lib/ssl/ssl3exthandle.h +++ b/security/nss/lib/ssl/ssl3exthandle.h @@ -9,90 +9,114 @@ #ifndef __ssl3exthandle_h_ #define __ssl3exthandle_h_ -PRInt32 ssl3_SendRenegotiationInfoXtn(const sslSocket *ss, TLSExtensionData *xtnData, - PRBool append, PRUint32 maxBytes); -SECStatus ssl3_HandleRenegotiationInfoXtn(const sslSocket *ss, TLSExtensionData *xtnData, - PRUint16 ex_type, SECItem *data); -SECStatus ssl3_ClientHandleNextProtoNegoXtn(const sslSocket *ss, TLSExtensionData *xtnData, - PRUint16 ex_type, SECItem *data); -SECStatus ssl3_ClientHandleAppProtoXtn(const sslSocket *ss, TLSExtensionData *xtnData, - PRUint16 ex_type, SECItem *data); -SECStatus ssl3_ServerHandleNextProtoNegoXtn(const sslSocket *ss, TLSExtensionData *xtnData, - PRUint16 ex_type, SECItem *data); -SECStatus ssl3_ServerHandleAppProtoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, +#include "sslencode.h" + +SECStatus ssl3_SendRenegotiationInfoXtn(const sslSocket *ss, + TLSExtensionData *xtnData, + sslBuffer *buf, PRBool *added); +SECStatus ssl3_HandleRenegotiationInfoXtn(const sslSocket *ss, + TLSExtensionData *xtnData, + SECItem *data); +SECStatus ssl3_ClientHandleNextProtoNegoXtn(const sslSocket *ss, + TLSExtensionData *xtnData, + SECItem *data); +SECStatus ssl3_ClientHandleAppProtoXtn(const sslSocket *ss, + TLSExtensionData *xtnData, + SECItem *data); +SECStatus ssl3_ServerHandleNextProtoNegoXtn(const sslSocket *ss, + TLSExtensionData *xtnData, + SECItem *data); +SECStatus ssl3_ServerHandleAppProtoXtn(const sslSocket *ss, + TLSExtensionData *xtnData, SECItem *data); -PRInt32 ssl3_ClientSendNextProtoNegoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, - PRUint32 maxBytes); -PRInt32 ssl3_ClientSendAppProtoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, - PRUint32 maxBytes); -PRInt32 ssl3_ServerSendAppProtoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, - PRUint32 maxBytes); -PRInt32 ssl3_ClientSendUseSRTPXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, - PRUint32 maxBytes); -PRInt32 ssl3_ServerSendUseSRTPXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, - PRUint32 maxBytes); -SECStatus ssl3_ClientHandleUseSRTPXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, +SECStatus ssl3_ClientSendNextProtoNegoXtn(const sslSocket *ss, + TLSExtensionData *xtnData, + sslBuffer *buf, PRBool *added); +SECStatus ssl3_ClientSendAppProtoXtn(const sslSocket *ss, + TLSExtensionData *xtnData, + sslBuffer *buf, PRBool *added); +SECStatus ssl3_ServerSendAppProtoXtn(const sslSocket *ss, + TLSExtensionData *xtnData, + sslBuffer *buf, PRBool *added); +SECStatus ssl3_ClientSendUseSRTPXtn(const sslSocket *ss, + TLSExtensionData *xtnData, + sslBuffer *buf, PRBool *added); +SECStatus ssl3_ServerSendUseSRTPXtn(const sslSocket *ss, + TLSExtensionData *xtnData, + sslBuffer *buf, PRBool *added); +SECStatus ssl3_ClientHandleUseSRTPXtn(const sslSocket *ss, + TLSExtensionData *xtnData, SECItem *data); -SECStatus ssl3_ServerHandleUseSRTPXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, +SECStatus ssl3_ServerHandleUseSRTPXtn(const sslSocket *ss, + TLSExtensionData *xtnData, SECItem *data); -PRInt32 ssl3_ServerSendStatusRequestXtn(const sslSocket *ss, TLSExtensionData *xtnData, - PRBool append, PRUint32 maxBytes); -SECStatus ssl3_ServerHandleStatusRequestXtn(const sslSocket *ss, TLSExtensionData *xtnData, - PRUint16 ex_type, SECItem *data); -SECStatus ssl3_ClientHandleStatusRequestXtn(const sslSocket *ss, TLSExtensionData *xtnData, - PRUint16 ex_type, +SECStatus ssl3_ServerSendStatusRequestXtn(const sslSocket *ss, + TLSExtensionData *xtnData, + sslBuffer *buf, PRBool *added); +SECStatus ssl3_ServerHandleStatusRequestXtn(const sslSocket *ss, + TLSExtensionData *xtnData, SECItem *data); -PRInt32 ssl3_ClientSendStatusRequestXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, - PRUint32 maxBytes); -PRInt32 ssl3_ClientSendSigAlgsXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, - PRUint32 maxBytes); -SECStatus ssl3_ServerHandleSigAlgsXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, - SECItem *data); +SECStatus ssl3_ClientHandleStatusRequestXtn(const sslSocket *ss, + TLSExtensionData *xtnData, + SECItem *data); +SECStatus ssl3_ClientSendStatusRequestXtn(const sslSocket *ss, + TLSExtensionData *xtnData, + sslBuffer *buf, PRBool *added); +SECStatus ssl3_SendSigAlgsXtn(const sslSocket *ss, TLSExtensionData *xtnData, + sslBuffer *buf, PRBool *added); +SECStatus ssl3_HandleSigAlgsXtn(const sslSocket *ss, TLSExtensionData *xtnData, + SECItem *data); -PRInt32 ssl3_ClientSendPaddingExtension(const sslSocket *ss, TLSExtensionData *xtnData, - PRBool append, PRUint32 maxBytes); +SECStatus ssl3_ClientSendPaddingExtension(const sslSocket *ss, + TLSExtensionData *xtnData, + sslBuffer *buf, PRBool *added); -PRInt32 ssl3_ClientSendSignedCertTimestampXtn(const sslSocket *ss, TLSExtensionData *xtnData, - PRBool append, - PRUint32 maxBytes); -SECStatus ssl3_ClientHandleSignedCertTimestampXtn(const sslSocket *ss, TLSExtensionData *xtnData, - PRUint16 ex_type, +SECStatus ssl3_ClientSendSignedCertTimestampXtn(const sslSocket *ss, + TLSExtensionData *xtnData, + sslBuffer *buf, PRBool *added); +SECStatus ssl3_ClientHandleSignedCertTimestampXtn(const sslSocket *ss, + TLSExtensionData *xtnData, SECItem *data); -PRInt32 ssl3_ServerSendSignedCertTimestampXtn(const sslSocket *ss, TLSExtensionData *xtnData, - PRBool append, - PRUint32 maxBytes); -SECStatus ssl3_ServerHandleSignedCertTimestampXtn(const sslSocket *ss, TLSExtensionData *xtnData, - PRUint16 ex_type, +SECStatus ssl3_ServerSendSignedCertTimestampXtn(const sslSocket *ss, + TLSExtensionData *xtnData, + sslBuffer *buf, PRBool *added); +SECStatus ssl3_ServerHandleSignedCertTimestampXtn(const sslSocket *ss, + TLSExtensionData *xtnData, SECItem *data); -PRInt32 ssl3_SendExtendedMasterSecretXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, - PRUint32 maxBytes); -SECStatus ssl3_HandleExtendedMasterSecretXtn(const sslSocket *ss, TLSExtensionData *xtnData, - PRUint16 ex_type, +SECStatus ssl3_SendExtendedMasterSecretXtn(const sslSocket *ss, + TLSExtensionData *xtnData, + sslBuffer *buf, PRBool *added); +SECStatus ssl3_HandleExtendedMasterSecretXtn(const sslSocket *ss, + TLSExtensionData *xtnData, SECItem *data); -SECStatus ssl3_ProcessSessionTicketCommon(sslSocket *ss, SECItem *data); -PRInt32 ssl3_SendServerNameXtn(const sslSocket *ss, - TLSExtensionData *xtnData, - PRBool append, - PRUint32 maxBytes); -SECStatus ssl3_HandleServerNameXtn(const sslSocket *ss, TLSExtensionData *xtnData, - PRUint16 ex_type, SECItem *data); -SECStatus ssl_HandleSupportedGroupsXtn(const sslSocket *ss, TLSExtensionData *xtnData, - PRUint16 ex_type, SECItem *data); -SECStatus ssl3_HandleSupportedPointFormatsXtn(const sslSocket *ss, TLSExtensionData *xtnData, - PRUint16 ex_type, SECItem *data); -SECStatus ssl3_ClientHandleSessionTicketXtn(const sslSocket *ss, TLSExtensionData *xtnData, - PRUint16 ex_type, SECItem *data); -SECStatus ssl3_ServerHandleSessionTicketXtn(const sslSocket *ss, TLSExtensionData *xtnData, - PRUint16 ex_type, SECItem *data); -PRInt32 ssl3_SendSessionTicketXtn(const sslSocket *ss, - TLSExtensionData *xtnData, - PRBool append, - PRUint32 maxBytes); - -PRInt32 ssl_SendSupportedGroupsXtn(const sslSocket *ss, +SECStatus ssl3_ProcessSessionTicketCommon(sslSocket *ss, const SECItem *ticket, + /* out */ SECItem *appToken); +SECStatus ssl3_ClientSendServerNameXtn(const sslSocket *ss, + TLSExtensionData *xtnData, + sslBuffer *buf, PRBool *added); +SECStatus ssl3_HandleServerNameXtn(const sslSocket *ss, TLSExtensionData *xtnData, - PRBool append, PRUint32 maxBytes); -PRInt32 ssl3_SendSupportedPointFormatsXtn(const sslSocket *ss, + SECItem *data); +SECStatus ssl_HandleSupportedGroupsXtn(const sslSocket *ss, + TLSExtensionData *xtnData, + SECItem *data); +SECStatus ssl3_HandleSupportedPointFormatsXtn(const sslSocket *ss, + TLSExtensionData *xtnData, + SECItem *data); +SECStatus ssl3_ClientHandleSessionTicketXtn(const sslSocket *ss, + TLSExtensionData *xtnData, + SECItem *data); +SECStatus ssl3_ServerHandleSessionTicketXtn(const sslSocket *ss, + TLSExtensionData *xtnData, + SECItem *data); +SECStatus ssl3_ClientSendSessionTicketXtn(const sslSocket *ss, TLSExtensionData *xtnData, - PRBool append, PRUint32 maxBytes); + sslBuffer *buf, PRBool *added); + +SECStatus ssl_SendSupportedGroupsXtn(const sslSocket *ss, + TLSExtensionData *xtnData, + sslBuffer *buf, PRBool *added); +SECStatus ssl3_SendSupportedPointFormatsXtn(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 cf6f4cb33..8b323bb05 100644 --- a/security/nss/lib/ssl/ssl3gthr.c +++ b/security/nss/lib/ssl/ssl3gthr.c @@ -1,3 +1,4 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * Gather (Read) entire SSL3 records from socket into buffer. * @@ -98,7 +99,7 @@ ssl3_GatherData(sslSocket *ss, sslGather *gs, int flags, ssl2Gather *ssl2gs) PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss)); if (gs->state == GS_INIT) { gs->state = GS_HEADER; - gs->remainder = ss->ssl3.hs.shortHeaders ? 2 : 5; + gs->remainder = 5; gs->offset = 0; gs->writeOffset = 0; gs->readOffset = 0; @@ -156,19 +157,7 @@ ssl3_GatherData(sslSocket *ss, sslGather *gs, int flags, ssl2Gather *ssl2gs) /* Should have a non-SSLv2 record header in gs->hdr. Extract * the length of the following encrypted data, and then * read in the rest of the record into gs->inbuf. */ - if (ss->ssl3.hs.shortHeaders) { - PRUint16 len = (gs->hdr[0] << 8) | gs->hdr[1]; - if (!(len & 0x8000)) { - SSL_DBG(("%d: SSL3[%d]: incorrectly formatted header")); - SSL3_SendAlert(ss, alert_fatal, illegal_parameter); - gs->state = GS_INIT; - PORT_SetError(SSL_ERROR_BAD_MAC_READ); - return SECFailure; - } - gs->remainder = len & ~0x8000; - } else { - gs->remainder = (gs->hdr[3] << 8) | gs->hdr[4]; - } + gs->remainder = (gs->hdr[3] << 8) | gs->hdr[4]; } else { /* Probably an SSLv2 record header. No need to handle any * security escapes (gs->hdr[0] & 0x40) as we wouldn't get @@ -361,6 +350,9 @@ dtls_GatherData(sslSocket *ss, sslGather *gs, int flags) } } + 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; @@ -394,7 +386,15 @@ ssl3_GatherCompleteHandshake(sslSocket *ss, int flags) SSL3Ciphertext cText; PRBool keepGoing = PR_TRUE; - SSL_TRC(30, ("ssl3_GatherCompleteHandshake")); + if (ss->ssl3.fatalAlertSent) { + SSL_TRC(3, ("%d: SSL3[%d] Cannot gather data; fatal alert already sent", + SSL_GETPID(), ss->fd)); + PORT_SetError(SSL_ERROR_HANDSHAKE_FAILED); + return SECFailure; + } + + SSL_TRC(30, ("%d: SSL3[%d]: ssl3_GatherCompleteHandshake", + SSL_GETPID(), ss->fd)); /* ssl3_HandleRecord may end up eventually calling ssl_FinishHandshake, * which requires the 1stHandshakeLock, which must be acquired before the @@ -405,9 +405,12 @@ ssl3_GatherCompleteHandshake(sslSocket *ss, int flags) do { PRBool handleRecordNow = PR_FALSE; + PRBool processingEarlyData; ssl_GetSSL3HandshakeLock(ss); + processingEarlyData = ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted; + /* Without this, we may end up wrongly reporting * SSL_ERROR_RX_UNEXPECTED_* errors if we receive any records from the * peer while we are waiting to be restarted. @@ -493,18 +496,12 @@ ssl3_GatherCompleteHandshake(sslSocket *ss, int flags) * If it's a change cipher spec, alert, or handshake message, * ss->gs.buf.len will be 0 when ssl3_HandleRecord returns SECSuccess. */ - if (ss->ssl3.hs.shortHeaders) { - cText.type = content_application_data; - cText.version = SSL_LIBRARY_VERSION_TLS_1_0; - } else { - cText.type = (SSL3ContentType)ss->gs.hdr[0]; - cText.version = (ss->gs.hdr[1] << 8) | ss->gs.hdr[2]; - } + 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; - cText.version = dtls_DTLSVersionToTLSVersion(cText.version); /* DTLS sequence number */ PORT_Memcpy(&seq_num, &ss->gs.hdr[3], sizeof(seq_num)); cText.seq_num = PR_ntohll(seq_num); @@ -555,12 +552,22 @@ ssl3_GatherCompleteHandshake(sslSocket *ss, int flags) } else { ss->ssl3.hs.canFalseStart = PR_FALSE; } + } else if (processingEarlyData && + ss->ssl3.hs.zeroRttState == ssl_0rtt_done && + !PR_CLIST_IS_EMPTY(&ss->ssl3.hs.bufferedEarlyData)) { + /* If we were processing early data and we are no longer, then force + * the handshake to block. This ensures that early data is + * delivered to the application before the handshake completes. */ + ssl_ReleaseSSL3HandshakeLock(ss); + PORT_SetError(PR_WOULD_BLOCK_ERROR); + return SECWouldBlock; } ssl_ReleaseSSL3HandshakeLock(ss); } while (keepGoing); - /* Service the DTLS timer so that the holddown timer eventually fires. */ - if (IS_DTLS(ss)) { + /* Service the DTLS timer so that the post-handshake timers + * fire. */ + if (IS_DTLS(ss) && (ss->ssl3.hs.ws == idle_handshake)) { dtls_CheckTimer(ss); } ss->gs.readOffset = 0; diff --git a/security/nss/lib/ssl/ssl3prot.h b/security/nss/lib/ssl/ssl3prot.h index ac31cf263..d1f46db97 100644 --- a/security/nss/lib/ssl/ssl3prot.h +++ b/security/nss/lib/ssl/ssl3prot.h @@ -16,13 +16,12 @@ 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 18 +#define TLS_1_3_DRAFT_VERSION 23 typedef PRUint16 ssl3CipherSuite; /* The cipher suites are defined in sslproto.h */ #define MAX_CERT_TYPES 10 -#define MAX_COMPRESSION_METHODS 10 #define MAX_MAC_LENGTH 64 #define MAX_PADDING_LENGTH 64 #define MAX_KEY_LENGTH 64 @@ -30,7 +29,6 @@ typedef PRUint16 ssl3CipherSuite; #define SSL3_RANDOM_LENGTH 32 #define SSL3_RECORD_HEADER_LENGTH 5 -#define TLS13_RECORD_HEADER_LENGTH_SHORT 2 /* SSL3_RECORD_HEADER_LENGTH + epoch/sequence_number */ #define DTLS_RECORD_HEADER_LENGTH 13 @@ -41,47 +39,18 @@ typedef enum { content_change_cipher_spec = 20, content_alert = 21, content_handshake = 22, - content_application_data = 23 + content_application_data = 23, + content_alt_handshake = 24, + content_ack = 25 } SSL3ContentType; -typedef struct { - SSL3ContentType type; - SSL3ProtocolVersion version; - PRUint16 length; - SECItem fragment; -} SSL3Plaintext; - -typedef struct { - SSL3ContentType type; - SSL3ProtocolVersion version; - PRUint16 length; - SECItem fragment; -} SSL3Compressed; - -typedef struct { - SECItem content; - PRUint8 MAC[MAX_MAC_LENGTH]; -} SSL3GenericStreamCipher; - -typedef struct { - SECItem content; - PRUint8 MAC[MAX_MAC_LENGTH]; - PRUint8 padding[MAX_PADDING_LENGTH]; - PRUint8 padding_length; -} SSL3GenericBlockCipher; - typedef enum { change_cipher_spec_choice = 1 } SSL3ChangeCipherSpecChoice; -typedef struct { - SSL3ChangeCipherSpecChoice choice; -} SSL3ChangeCipherSpec; - typedef enum { alert_warning = 1, alert_fatal = 2 } SSL3AlertLevel; typedef enum { close_notify = 0, - end_of_early_data = 1, /* TLS 1.3 */ unexpected_message = 10, bad_record_mac = 20, decryption_failed_RESERVED = 21, /* do not send; see RFC 5246 */ @@ -122,64 +91,13 @@ typedef enum { no_alert = 256 } SSL3AlertDescription; -typedef struct { - SSL3AlertLevel level; - SSL3AlertDescription description; -} SSL3Alert; - -typedef enum { - hello_request = 0, - client_hello = 1, - server_hello = 2, - hello_verify_request = 3, - new_session_ticket = 4, - hello_retry_request = 6, - encrypted_extensions = 8, - certificate = 11, - server_key_exchange = 12, - certificate_request = 13, - server_hello_done = 14, - certificate_verify = 15, - client_key_exchange = 16, - finished = 20, - certificate_status = 22, - next_proto = 67 -} SSL3HandshakeType; - -typedef struct { - PRUint8 empty; -} SSL3HelloRequest; - -typedef struct { - PRUint8 rand[SSL3_RANDOM_LENGTH]; -} SSL3Random; +typedef PRUint8 SSL3Random[SSL3_RANDOM_LENGTH]; typedef struct { PRUint8 id[32]; PRUint8 length; } SSL3SessionID; -typedef struct { - SSL3ProtocolVersion client_version; - SSL3Random random; - SSL3SessionID session_id; - SECItem cipher_suites; - PRUint8 cm_count; - SSLCompressionMethod compression_methods[MAX_COMPRESSION_METHODS]; -} SSL3ClientHello; - -typedef struct { - SSL3ProtocolVersion server_version; - SSL3Random random; - SSL3SessionID session_id; - ssl3CipherSuite cipher_suite; - SSLCompressionMethod compression_method; -} SSL3ServerHello; - -typedef struct { - SECItem list; -} SSL3Certificate; - /* SSL3SignType moved to ssl.h */ /* The SSL key exchange method used */ @@ -201,24 +119,6 @@ typedef enum { kea_tls13_any, } SSL3KeyExchangeAlgorithm; -typedef struct { - SECItem modulus; - SECItem exponent; -} SSL3ServerRSAParams; - -typedef struct { - SECItem p; - SECItem g; - SECItem Ys; -} SSL3ServerDHParams; - -typedef struct { - union { - SSL3ServerDHParams dh; - SSL3ServerRSAParams rsa; - } u; -} SSL3ServerParams; - /* SSL3HashesIndividually contains a combination MD5/SHA1 hash, as used in TLS * prior to 1.2. */ typedef struct { @@ -235,17 +135,9 @@ typedef struct { union { PRUint8 raw[64]; SSL3HashesIndividually s; - unsigned int transcriptLen; } u; } SSL3Hashes; -typedef struct { - union { - PRUint8 anonymous; - SSL3Hashes certified; - } u; -} SSL3ServerKeyExchange; - typedef enum { ct_RSA_sign = 1, ct_DSS_sign = 2, @@ -256,16 +148,8 @@ typedef enum { ct_ECDSA_sign = 64, ct_RSA_fixed_ECDH = 65, ct_ECDSA_fixed_ECDH = 66 - } SSL3ClientCertificateType; -typedef struct { - PRUint8 client_version[2]; - PRUint8 random[46]; -} SSL3RSAPreMasterSecret; - -typedef PRUint8 SSL3MasterSecret[48]; - typedef enum { sender_client = 0x434c4e54, sender_server = 0x53525652 diff --git a/security/nss/lib/ssl/sslbloom.c b/security/nss/lib/ssl/sslbloom.c new file mode 100644 index 000000000..3d5f9d1f1 --- /dev/null +++ b/security/nss/lib/ssl/sslbloom.c @@ -0,0 +1,94 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * A bloom filter. + * + * 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 "sslbloom.h" +#include "prnetdb.h" +#include "secport.h" + +static inline unsigned int +sslBloom_Size(unsigned int bits) +{ + return (bits >= 3) ? (1 << (bits - 3)) : 1; +} + +SECStatus +sslBloom_Init(sslBloomFilter *filter, unsigned int k, unsigned int bits) +{ + PORT_Assert(filter); + PORT_Assert(bits > 0); + PORT_Assert(bits <= sizeof(PRUint32) * 8); + PORT_Assert(k > 0); + + filter->filter = PORT_ZNewArray(PRUint8, sslBloom_Size(bits)); + if (!filter->filter) { + return SECFailure; /* Error code already set. */ + } + + filter->k = k; + filter->bits = bits; + return SECSuccess; +} + +void +sslBloom_Zero(sslBloomFilter *filter) +{ + PORT_Memset(filter->filter, 0, sslBloom_Size(filter->bits)); +} + +void +sslBloom_Fill(sslBloomFilter *filter) +{ + PORT_Memset(filter->filter, 0xff, sslBloom_Size(filter->bits)); +} + +static PRBool +sslBloom_AddOrCheck(sslBloomFilter *filter, const PRUint8 *hashes, PRBool add) +{ + unsigned int iteration; + unsigned int bitIndex; + PRUint32 tmp = 0; + PRUint8 mask; + unsigned int bytes = (filter->bits + 7) / 8; + unsigned int shift = (bytes * 8) - filter->bits; + PRBool found = PR_TRUE; + + PORT_Assert(bytes <= sizeof(unsigned int)); + + for (iteration = 0; iteration < filter->k; ++iteration) { + PORT_Memcpy(((PRUint8 *)&tmp) + (sizeof(tmp) - bytes), + hashes, bytes); + hashes += bytes; + bitIndex = PR_ntohl(tmp) >> shift; + + mask = 1 << (bitIndex % 8); + found = found && filter->filter[bitIndex / 8] & mask; + if (add) { + filter->filter[bitIndex / 8] |= mask; + } + } + return found; +} + +PRBool +sslBloom_Add(sslBloomFilter *filter, const PRUint8 *hashes) +{ + return sslBloom_AddOrCheck(filter, hashes, PR_TRUE); +} + +PRBool +sslBloom_Check(sslBloomFilter *filter, const PRUint8 *hashes) +{ + return sslBloom_AddOrCheck(filter, hashes, PR_FALSE); +} + +void +sslBloom_Destroy(sslBloomFilter *filter) +{ + PORT_Free(filter->filter); + PORT_Memset(filter, 0, sizeof(*filter)); +} diff --git a/security/nss/lib/ssl/sslbloom.h b/security/nss/lib/ssl/sslbloom.h new file mode 100644 index 000000000..032c94b0f --- /dev/null +++ b/security/nss/lib/ssl/sslbloom.h @@ -0,0 +1,32 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * A bloom filter. + * + * 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 __sslbloom_h_ +#define __sslbloom_h_ + +#include "prtypes.h" +#include "seccomon.h" + +typedef struct sslBloomFilterStr { + unsigned int k; /* The number of hashes. */ + unsigned int bits; /* The number of bits in each hash: bits = log2(m) */ + PRUint8 *filter; /* The filter itself. */ +} sslBloomFilter; + +SECStatus sslBloom_Init(sslBloomFilter *filter, unsigned int k, unsigned int bits); +void sslBloom_Zero(sslBloomFilter *filter); +void sslBloom_Fill(sslBloomFilter *filter); +/* Add the given hashes to the filter. It's the caller's responsibility to + * ensure that there is at least |ceil(k*bits/8)| bytes of data available in + * |hashes|. Returns PR_TRUE if the entry was already present or it was likely + * to be present. */ +PRBool sslBloom_Add(sslBloomFilter *filter, const PRUint8 *hashes); +PRBool sslBloom_Check(sslBloomFilter *filter, const PRUint8 *hashes); +void sslBloom_Destroy(sslBloomFilter *filter); + +#endif /* __sslbloom_h_ */ diff --git a/security/nss/lib/ssl/sslcert.c b/security/nss/lib/ssl/sslcert.c index cc1d3c683..6cd02e402 100644 --- a/security/nss/lib/ssl/sslcert.c +++ b/security/nss/lib/ssl/sslcert.c @@ -46,7 +46,7 @@ ssl_SetupCAListOnce(void *arg) } SECStatus -ssl_SetupCAList(sslSocket *ss) +ssl_SetupCAList(const sslSocket *ss) { if (PR_SUCCESS != PR_CallOnceWithArg(&ssl_server_ca_list.setup, &ssl_SetupCAListOnce, @@ -58,11 +58,11 @@ ssl_SetupCAList(sslSocket *ss) } SECStatus -ssl_GetCertificateRequestCAs(sslSocket *ss, unsigned int *calen, - SECItem **names, unsigned int *nnames) +ssl_GetCertificateRequestCAs(const sslSocket *ss, unsigned int *calen, + const SECItem **names, unsigned int *nnames) { - SECItem *name; - CERTDistNames *ca_list; + const SECItem *name; + const CERTDistNames *ca_list; unsigned int i; *calen = 0; diff --git a/security/nss/lib/ssl/sslcon.c b/security/nss/lib/ssl/sslcon.c index 448170640..bc63e1537 100644 --- a/security/nss/lib/ssl/sslcon.c +++ b/security/nss/lib/ssl/sslcon.c @@ -119,13 +119,12 @@ ssl_CheckConfigSanity(sslSocket *ss) SECStatus ssl_BeginClientHandshake(sslSocket *ss) { - sslSessionID *sid; + sslSessionID *sid = NULL; SECStatus rv; PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss)); ss->sec.isServer = PR_FALSE; - ssl_ChooseSessionIDProcs(&ss->sec); rv = ssl_CheckConfigSanity(ss); if (rv != SECSuccess) @@ -156,19 +155,22 @@ ssl_BeginClientHandshake(sslSocket *ss) SSL_TRC(3, ("%d: SSL[%d]: sending client-hello", SSL_GETPID(), ss->fd)); - /* Try to find server in our session-id cache */ - if (ss->opt.noCache) { - sid = NULL; - } else { + /* If there's an sid set from an external cache, use it. */ + if (ss->sec.ci.sid && ss->sec.ci.sid->cached == in_external_cache) { + sid = ss->sec.ci.sid; + SSL_TRC(3, ("%d: SSL[%d]: using external token", SSL_GETPID(), ss->fd)); + } else if (!ss->opt.noCache) { + /* Try to find server in our session-id cache */ sid = ssl_LookupSID(&ss->sec.ci.peer, ss->sec.ci.port, ss->peerID, ss->url); } + if (sid) { if (sid->version >= ss->vrange.min && sid->version <= ss->vrange.max) { PORT_Assert(!ss->sec.localCert); ss->sec.localCert = CERT_DupCertificate(sid->localCert); } else { - ss->sec.uncache(sid); + ssl_UncacheSessionID(ss); ssl_FreeSID(sid); sid = NULL; } @@ -218,7 +220,6 @@ ssl_BeginServerHandshake(sslSocket *ss) ss->sec.isServer = PR_TRUE; ss->ssl3.hs.ws = wait_client_hello; - ssl_ChooseSessionIDProcs(&ss->sec); rv = ssl_CheckConfigSanity(ss); if (rv != SECSuccess) diff --git a/security/nss/lib/ssl/sslencode.c b/security/nss/lib/ssl/sslencode.c new file mode 100644 index 000000000..e50880451 --- /dev/null +++ b/security/nss/lib/ssl/sslencode.c @@ -0,0 +1,328 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is PRIVATE to SSL. + * + * 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 "nss.h" +#include "prnetdb.h" +#include "ssl.h" +#include "sslimpl.h" + +/* Helper function to encode an unsigned integer into a buffer. */ +static void +ssl_EncodeUintX(PRUint8 *to, PRUint64 value, unsigned int bytes) +{ + PRUint64 encoded; + + PORT_Assert(bytes > 0 && bytes <= sizeof(encoded)); + + encoded = PR_htonll(value); + PORT_Memcpy(to, ((unsigned char *)(&encoded)) + (sizeof(encoded) - bytes), + bytes); +} + +/* Grow a buffer to hold newLen bytes of data. When used for recv/xmit buffers, + * the caller must hold xmitBufLock or recvBufLock, as appropriate. */ +SECStatus +sslBuffer_Grow(sslBuffer *b, unsigned int newLen) +{ + PORT_Assert(b); + if (b->fixed) { + PORT_Assert(newLen <= b->space); + if (newLen > b->space) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + return SECSuccess; + } + + newLen = PR_MAX(newLen, b->len + 1024); + if (newLen > b->space) { + unsigned char *newBuf; + if (b->buf) { + newBuf = (unsigned char *)PORT_Realloc(b->buf, newLen); + } else { + newBuf = (unsigned char *)PORT_Alloc(newLen); + } + if (!newBuf) { + return SECFailure; + } + b->buf = newBuf; + b->space = newLen; + } + return SECSuccess; +} + +SECStatus +sslBuffer_Append(sslBuffer *b, const void *data, unsigned int len) +{ + SECStatus rv = sslBuffer_Grow(b, b->len + len); + if (rv != SECSuccess) { + return SECFailure; /* Code already set. */ + } + PORT_Memcpy(SSL_BUFFER_NEXT(b), data, len); + b->len += len; + return SECSuccess; +} + +SECStatus +sslBuffer_AppendNumber(sslBuffer *b, PRUint64 v, unsigned int size) +{ + SECStatus rv = sslBuffer_Grow(b, b->len + size); + if (rv != SECSuccess) { + return SECFailure; + } + ssl_EncodeUintX(SSL_BUFFER_NEXT(b), v, size); + b->len += size; + return SECSuccess; +} + +SECStatus +sslBuffer_AppendVariable(sslBuffer *b, const PRUint8 *data, unsigned int len, + unsigned int size) +{ + PORT_Assert(size <= 4 && size > 0); + PORT_Assert(b); + if (len >= (1ULL << (8 * size))) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + + if (sslBuffer_Grow(b, b->len + len + size) != SECSuccess) { + return SECFailure; + } + + ssl_EncodeUintX(SSL_BUFFER_NEXT(b), len, size); + b->len += size; + if (len != 0) { + PORT_Assert(data); + /* We sometimes pass NULL, 0 and memcpy() doesn't want NULL. */ + PORT_Memcpy(SSL_BUFFER_NEXT(b), data, len); + } + b->len += len; + return SECSuccess; +} + +SECStatus +sslBuffer_AppendBuffer(sslBuffer *b, const sslBuffer *append) +{ + return sslBuffer_Append(b, append->buf, append->len); +} + +SECStatus +sslBuffer_AppendBufferVariable(sslBuffer *b, const sslBuffer *append, + unsigned int size) +{ + return sslBuffer_AppendVariable(b, append->buf, append->len, size); +} + +SECStatus +sslBuffer_Skip(sslBuffer *b, unsigned int size, unsigned int *savedOffset) +{ + if (sslBuffer_Grow(b, b->len + size) != SECSuccess) { + return SECFailure; + } + + if (savedOffset) { + *savedOffset = b->len; + } + b->len += size; + return SECSuccess; +} + +/* A common problem is that a buffer is used to construct a variable length + * structure of unknown length. The length field for that structure is then + * populated afterwards. This function makes this process a little easier. + * + * To use this, before encoding the variable length structure, skip the spot + * where the length would be using sslBuffer_Skip(). After encoding the + * structure, and before encoding anything else, call this function passing the + * value returned from sslBuffer_Skip() as |at| to have the length inserted. + */ +SECStatus +sslBuffer_InsertLength(sslBuffer *b, unsigned int at, unsigned int size) +{ + unsigned int len; + + PORT_Assert(b->len >= at + size); + PORT_Assert(b->space >= at + size); + len = b->len - (at + size); + + PORT_Assert(size <= 4 && size > 0); + if (len >= (1ULL << (8 * size))) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + + ssl_EncodeUintX(SSL_BUFFER_BASE(b) + at, len, size); + return SECSuccess; +} + +void +sslBuffer_Clear(sslBuffer *b) +{ + if (!b->fixed) { + if (b->buf) { + PORT_Free(b->buf); + b->buf = NULL; + } + b->space = 0; + } + b->len = 0; +} + +SECStatus +sslRead_Read(sslReader *reader, unsigned int count, sslReadBuffer *out) +{ + if (!reader || !out) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + if (reader->buf.len < reader->offset || + count > SSL_READER_REMAINING(reader)) { + PORT_SetError(SEC_ERROR_BAD_DATA); + return SECFailure; + } + + out->buf = SSL_READER_CURRENT(reader); + out->len = count; + reader->offset += count; + + return SECSuccess; +} + +SECStatus +sslRead_ReadVariable(sslReader *reader, unsigned int sizeLen, sslReadBuffer *out) +{ + PRUint64 variableLen = 0; + SECStatus rv = sslRead_ReadNumber(reader, sizeLen, &variableLen); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_BAD_DATA); + return SECFailure; + } + if (!variableLen) { + // It is ok to have an empty variable. + out->len = variableLen; + return SECSuccess; + } + return sslRead_Read(reader, variableLen, out); +} + +SECStatus +sslRead_ReadNumber(sslReader *reader, unsigned int bytes, PRUint64 *num) +{ + if (!reader || !num) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + if (reader->buf.len < reader->offset || + bytes > SSL_READER_REMAINING(reader) || + bytes > 8) { + PORT_SetError(SEC_ERROR_BAD_DATA); + return SECFailure; + } + unsigned int i; + PRUint64 number = 0; + for (i = 0; i < bytes; i++) { + number = (number << 8) + reader->buf.buf[i + reader->offset]; + } + + reader->offset = reader->offset + bytes; + *num = number; + return SECSuccess; +} + +/************************************************************************** + * Append Handshake functions. + * All these functions set appropriate error codes. + * Most rely on ssl3_AppendHandshake to set the error code. + **************************************************************************/ +#define MAX_SEND_BUF_LENGTH 32000 /* watch for 16-bit integer overflow */ +#define MIN_SEND_BUF_LENGTH 4000 + +SECStatus +ssl3_AppendHandshake(sslSocket *ss, const void *void_src, unsigned int bytes) +{ + unsigned char *src = (unsigned char *)void_src; + int room = ss->sec.ci.sendBuf.space - ss->sec.ci.sendBuf.len; + SECStatus rv; + + PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); /* protects sendBuf. */ + + if (!bytes) + return SECSuccess; + if (ss->sec.ci.sendBuf.space < MAX_SEND_BUF_LENGTH && room < bytes) { + rv = sslBuffer_Grow(&ss->sec.ci.sendBuf, PR_MAX(MIN_SEND_BUF_LENGTH, + PR_MIN(MAX_SEND_BUF_LENGTH, ss->sec.ci.sendBuf.len + bytes))); + if (rv != SECSuccess) + return SECFailure; /* sslBuffer_Grow sets a memory error code. */ + room = ss->sec.ci.sendBuf.space - ss->sec.ci.sendBuf.len; + } + + PRINT_BUF(60, (ss, "Append to Handshake", (unsigned char *)void_src, bytes)); + rv = ssl3_UpdateHandshakeHashes(ss, src, bytes); + if (rv != SECSuccess) + return SECFailure; /* error code set by ssl3_UpdateHandshakeHashes */ + + while (bytes > room) { + if (room > 0) + PORT_Memcpy(ss->sec.ci.sendBuf.buf + ss->sec.ci.sendBuf.len, src, + room); + ss->sec.ci.sendBuf.len += room; + rv = ssl3_FlushHandshake(ss, ssl_SEND_FLAG_FORCE_INTO_BUFFER); + if (rv != SECSuccess) { + return SECFailure; /* error code set by ssl3_FlushHandshake */ + } + bytes -= room; + src += room; + room = ss->sec.ci.sendBuf.space; + PORT_Assert(ss->sec.ci.sendBuf.len == 0); + } + PORT_Memcpy(ss->sec.ci.sendBuf.buf + ss->sec.ci.sendBuf.len, src, bytes); + ss->sec.ci.sendBuf.len += bytes; + return SECSuccess; +} + +SECStatus +ssl3_AppendHandshakeNumber(sslSocket *ss, PRUint64 num, unsigned int lenSize) +{ + PRUint8 b[sizeof(num)]; + SSL_TRC(60, ("%d: number:", SSL_GETPID())); + ssl_EncodeUintX(b, num, lenSize); + return ssl3_AppendHandshake(ss, b, lenSize); +} + +SECStatus +ssl3_AppendHandshakeVariable(sslSocket *ss, const PRUint8 *src, + unsigned int bytes, unsigned int lenSize) +{ + SECStatus rv; + + PORT_Assert((bytes < (1 << 8) && lenSize == 1) || + (bytes < (1L << 16) && lenSize == 2) || + (bytes < (1L << 24) && lenSize == 3)); + + SSL_TRC(60, ("%d: append variable:", SSL_GETPID())); + rv = ssl3_AppendHandshakeNumber(ss, bytes, lenSize); + if (rv != SECSuccess) { + return SECFailure; /* error code set by AppendHandshake. */ + } + SSL_TRC(60, ("data:")); + return ssl3_AppendHandshake(ss, src, bytes); +} + +SECStatus +ssl3_AppendBufferToHandshake(sslSocket *ss, sslBuffer *buf) +{ + return ssl3_AppendHandshake(ss, buf->buf, buf->len); +} + +SECStatus +ssl3_AppendBufferToHandshakeVariable(sslSocket *ss, sslBuffer *buf, + unsigned int lenSize) +{ + return ssl3_AppendHandshakeVariable(ss, buf->buf, buf->len, lenSize); +} diff --git a/security/nss/lib/ssl/sslencode.h b/security/nss/lib/ssl/sslencode.h new file mode 100644 index 000000000..f43e1c54b --- /dev/null +++ b/security/nss/lib/ssl/sslencode.h @@ -0,0 +1,85 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is PRIVATE to SSL. + * + * 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 __sslencode_h_ +#define __sslencode_h_ + +/* A buffer object, used for assembling messages. */ +typedef struct sslBufferStr { + PRUint8 *buf; + unsigned int len; + unsigned int space; + /* Set to true if the storage for the buffer is fixed, such as a stack + * variable or a view on another buffer. Growing a fixed buffer fails. */ + PRBool fixed; +} sslBuffer; + +#define SSL_BUFFER_EMPTY \ + { \ + NULL, 0, 0, PR_FALSE \ + } +#define SSL_BUFFER_FIXED(b, maxlen) \ + { \ + b, 0, maxlen, PR_TRUE \ + } +#define SSL_BUFFER(b) SSL_BUFFER_FIXED(b, sizeof(b)) +#define SSL_BUFFER_BASE(b) ((b)->buf) +#define SSL_BUFFER_LEN(b) ((b)->len) +#define SSL_BUFFER_NEXT(b) ((b)->buf + (b)->len) +#define SSL_BUFFER_SPACE(b) ((b)->space - (b)->len) + +SECStatus sslBuffer_Grow(sslBuffer *b, unsigned int newLen); +SECStatus sslBuffer_Append(sslBuffer *b, const void *data, unsigned int len); +SECStatus sslBuffer_AppendNumber(sslBuffer *b, PRUint64 v, unsigned int size); +SECStatus sslBuffer_AppendVariable(sslBuffer *b, const PRUint8 *data, + unsigned int len, unsigned int size); +SECStatus sslBuffer_AppendBuffer(sslBuffer *b, const sslBuffer *append); +SECStatus sslBuffer_AppendBufferVariable(sslBuffer *b, const sslBuffer *append, + unsigned int size); +SECStatus sslBuffer_Skip(sslBuffer *b, unsigned int size, + unsigned int *savedOffset); +SECStatus sslBuffer_InsertLength(sslBuffer *b, unsigned int at, + unsigned int size); +void sslBuffer_Clear(sslBuffer *b); + +SECStatus ssl3_AppendHandshake(sslSocket *ss, const void *void_src, + unsigned int bytes); +SECStatus ssl3_AppendHandshakeHeader(sslSocket *ss, + SSLHandshakeType t, unsigned int length); +SECStatus ssl3_AppendHandshakeNumber(sslSocket *ss, PRUint64 num, + unsigned int lenSize); +SECStatus ssl3_AppendHandshakeVariable(sslSocket *ss, const PRUint8 *src, + unsigned int bytes, unsigned int lenSize); +SECStatus ssl3_AppendBufferToHandshake(sslSocket *ss, sslBuffer *buf); +SECStatus ssl3_AppendBufferToHandshakeVariable(sslSocket *ss, sslBuffer *buf, + unsigned int lenSize); + +typedef struct { + const PRUint8 *buf; + unsigned int len; +} sslReadBuffer; +typedef struct { + sslReadBuffer buf; + unsigned int offset; +} sslReader; +#define SSL_READER(b, l) \ + { \ + { b, l }, 0 \ + } +#define SSL_READER_CURRENT(r) \ + ((r)->buf.buf + (r)->offset) +#define SSL_READER_REMAINING(r) \ + ((r)->buf.len - (r)->offset) +SECStatus sslRead_Read(sslReader *reader, unsigned int count, + sslReadBuffer *out); +SECStatus sslRead_ReadVariable(sslReader *reader, unsigned int sizeLen, + sslReadBuffer *out); +SECStatus sslRead_ReadNumber(sslReader *reader, unsigned int bytes, + PRUint64 *val); + +#endif /* __sslencode_h_ */ diff --git a/security/nss/lib/ssl/sslerr.h b/security/nss/lib/ssl/sslerr.h index 865077cda..b94d0cc62 100644 --- a/security/nss/lib/ssl/sslerr.h +++ b/security/nss/lib/ssl/sslerr.h @@ -234,6 +234,7 @@ typedef enum { SSL_ERROR_MALFORMED_PRE_SHARED_KEY = (SSL_ERROR_BASE + 147), SSL_ERROR_MALFORMED_EARLY_DATA = (SSL_ERROR_BASE + 148), SSL_ERROR_END_OF_EARLY_DATA_ALERT = (SSL_ERROR_BASE + 149), + /* error 149 is obsolete */ SSL_ERROR_MISSING_ALPN_EXTENSION = (SSL_ERROR_BASE + 150), SSL_ERROR_RX_UNEXPECTED_EXTENSION = (SSL_ERROR_BASE + 151), SSL_ERROR_MISSING_SUPPORTED_GROUPS_EXTENSION = (SSL_ERROR_BASE + 152), @@ -246,6 +247,21 @@ typedef enum { SSL_ERROR_MISSING_PSK_KEY_EXCHANGE_MODES = (SSL_ERROR_BASE + 159), SSL_ERROR_DOWNGRADE_WITH_EARLY_DATA = (SSL_ERROR_BASE + 160), SSL_ERROR_TOO_MUCH_EARLY_DATA = (SSL_ERROR_BASE + 161), + SSL_ERROR_RX_UNEXPECTED_END_OF_EARLY_DATA = (SSL_ERROR_BASE + 162), + SSL_ERROR_RX_MALFORMED_END_OF_EARLY_DATA = (SSL_ERROR_BASE + 163), + + SSL_ERROR_UNSUPPORTED_EXPERIMENTAL_API = (SSL_ERROR_BASE + 164), + + SSL_ERROR_APPLICATION_ABORT = (SSL_ERROR_BASE + 165), + SSL_ERROR_APP_CALLBACK_ERROR = (SSL_ERROR_BASE + 166), + SSL_ERROR_NO_TIMERS_FOUND = (SSL_ERROR_BASE + 167), + SSL_ERROR_MISSING_COOKIE_EXTENSION = (SSL_ERROR_BASE + 168), + + SSL_ERROR_RX_UNEXPECTED_KEY_UPDATE = (SSL_ERROR_BASE + 169), + SSL_ERROR_RX_MALFORMED_KEY_UPDATE = (SSL_ERROR_BASE + 170), + 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_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/sslexp.h b/security/nss/lib/ssl/sslexp.h new file mode 100644 index 000000000..08654f885 --- /dev/null +++ b/security/nss/lib/ssl/sslexp.h @@ -0,0 +1,461 @@ +/* + * This file contains prototypes for experimental SSL functions. + * + * 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 __sslexp_h_ +#define __sslexp_h_ + +#include "ssl.h" +#include "sslerr.h" + +SEC_BEGIN_PROTOS + +/* The functions in this header file are not guaranteed to remain available in + * future NSS versions. Code that uses these functions needs to safeguard + * against the function not being available. */ + +#define SSL_EXPERIMENTAL_API(name, arglist, args) \ + (SSL_GetExperimentalAPI(name) \ + ? ((SECStatus(*) arglist)SSL_GetExperimentalAPI(name))args \ + : SECFailure) +#define SSL_DEPRECATED_EXPERIMENTAL_API \ + (PR_SetError(SSL_ERROR_UNSUPPORTED_EXPERIMENTAL_API, 0), SECFailure) + +/* + * SSL_GetExtensionSupport() returns whether NSS supports a particular TLS + * extension. + * + * - ssl_ext_none indicates that NSS does not support the extension and + * extension hooks can be installed. + * + * - ssl_ext_native indicates that NSS supports the extension natively, but + * allows an application to override that support and install its own + * extension hooks. + * + * - ssl_ext_native_only indicates that NSS supports the extension natively + * and does not permit custom extension hooks to be installed. These + * extensions are critical to the functioning of NSS. + */ +typedef enum { + ssl_ext_none, + ssl_ext_native, + ssl_ext_native_only +} SSLExtensionSupport; + +#define SSL_GetExtensionSupport(extension, support) \ + SSL_EXPERIMENTAL_API("SSL_GetExtensionSupport", \ + (PRUint16 _extension, \ + SSLExtensionSupport * _support), \ + (extension, support)) + +/* + * Custom extension hooks. + * + * The SSL_InstallExtensionHooks() registers two callback functions for use + * with the identified extension type. + * + * Installing extension hooks disables the checks in TLS 1.3 that ensure that + * extensions are only added to the correct messages. The application is + * responsible for ensuring that extensions are only sent with the right message + * or messages. + * + * Installing an extension handler does not disable checks for whether an + * extension can be used in a message that is a response to an extension in + * another message. Extensions in ServerHello, EncryptedExtensions and the + * server Certificate messages are rejected unless the client sends an extension + * in the ClientHello. Similarly, a client Certificate message cannot contain + * extensions that don't appear in a CertificateRequest (in TLS 1.3). + * + * Setting both |writer| and |handler| to NULL removes any existing hooks for + * that extension. + * + * == SSLExtensionWriter + * + * An SSLExtensionWriter function is responsible for constructing the contents + * of an extension. This function is called during the construction of all + * handshake messages where an extension might be included. + * + * - The |fd| argument is the socket file descriptor. + * + * - The |message| argument is the TLS handshake message type. The writer will + * be called for every handshake message that NSS sends. Most extensions + * should only be sent in a subset of messages. NSS doesn’t check that + * extension writers don’t violate protocol rules regarding which message an + * extension can be sent in. + * + * - The |data| argument is a pointer to a buffer that should be written to with + * any data for the extension. + * + * - The |len| argument is an outparam indicating how many bytes were written to + * |data|. The value referenced by |len| is initialized to zero, so an + * extension that is empty does not need to write to this value. + * + * - The |maxLen| indicates the maximum number of bytes that can be written to + * |data|. + * + * - The |arg| argument is the value of the writerArg that was passed during + * installation. + * + * An SSLExtensionWriter function returns PR_TRUE if an extension should be + * written, and PR_FALSE otherwise. + * + * If there is an error, return PR_FALSE; if the error is truly fatal, the + * application can mark the connection as failed. However, recursively calling + * functions that alter the file descriptor in the callback - such as PR_Close() + * - should be avoided. + * + * Note: The ClientHello message can be sent twice in TLS 1.3. An + * SSLExtensionWriter will be called twice with the same arguments in that case; + * NSS does not distinguish between a first and second ClientHello. It is up to + * the application to track this if it needs to act differently each time. In + * most cases the correct behaviour is to provide an identical extension on each + * invocation. + * + * == SSLExtensionHandler + * + * An SSLExtensionHandler function consumes a handshake message. This function + * is called when an extension is present. + * + * - The |fd| argument is the socket file descriptor. + * + * - The |message| argument is the TLS handshake message type. This can be used + * to validate that the extension was included in the correct handshake + * message. + * + * - The |data| argument points to the contents of the extension. + * + * - The |len| argument contains the length of the extension. + * + * - The |alert| argument is an outparam that allows an application to choose + * which alert is sent in the case of a fatal error. + * + * - The |arg| argument is the value of the handlerArg that was passed during + * installation. + * + * An SSLExtensionHandler function returns SECSuccess when the extension is + * process successfully. It can return SECFailure to cause the handshake to + * fail. If the value of alert is written to, NSS will generate a fatal alert + * using the provided alert code. The value of |alert| is otherwise not used. + */ +typedef PRBool(PR_CALLBACK *SSLExtensionWriter)( + PRFileDesc *fd, SSLHandshakeType message, + PRUint8 *data, unsigned int *len, unsigned int maxLen, void *arg); + +typedef SECStatus(PR_CALLBACK *SSLExtensionHandler)( + PRFileDesc *fd, SSLHandshakeType message, + const PRUint8 *data, unsigned int len, + SSLAlertDescription *alert, void *arg); + +#define SSL_InstallExtensionHooks(fd, extension, writer, writerArg, \ + handler, handlerArg) \ + SSL_EXPERIMENTAL_API("SSL_InstallExtensionHooks", \ + (PRFileDesc * _fd, PRUint16 _extension, \ + SSLExtensionWriter _writer, void *_writerArg, \ + SSLExtensionHandler _handler, void *_handlerArg), \ + (fd, extension, writer, writerArg, \ + handler, handlerArg)) + +/* + * Setup the anti-replay buffer for supporting 0-RTT in TLS 1.3 on servers. + * + * To use 0-RTT on a server, you must call this function. Failing to call this + * function will result in all 0-RTT being rejected. Connections will complete, + * but early data will be rejected. + * + * NSS uses a Bloom filter to track the ClientHello messages that it receives + * (specifically, it uses the PSK binder). This function initializes a pair of + * Bloom filters. The two filters are alternated over time, with new + * ClientHello messages recorded in the current filter and, if they are not + * already present, being checked against the previous filter. If the + * ClientHello is found, then early data is rejected, but the handshake is + * allowed to proceed. + * + * The false-positive probability of Bloom filters means that some valid + * handshakes will be marked as potential replays. Early data will be rejected + * for a false positive. To minimize this and to allow a trade-off of space + * against accuracy, the size of the Bloom filter can be set by this function. + * + * The first tuning parameter to consider is |window|, which determines the + * window over which ClientHello messages will be tracked. This also causes + * early data to be rejected if a ClientHello contains a ticket age parameter + * that is outside of this window (see Section 4.2.10.4 of + * draft-ietf-tls-tls13-20 for details). Set |window| to account for any + * potential sources of clock error. |window| is the entire width of the + * window, which is symmetrical. Therefore to allow 5 seconds of clock error in + * both directions, set the value to 10 seconds (i.e., 10 * PR_USEC_PER_SEC). + * + * After calling this function, early data will be rejected until |window| + * elapses. This prevents replay across crashes and restarts. Only call this + * function once to avoid inadvertently disabling 0-RTT (use PR_CallOnce() to + * avoid this problem). + * + * The primary tuning parameter is |bits| which determines the amount of memory + * allocated to each Bloom filter. NSS will allocate two Bloom filters, each + * |2^(bits - 3)| octets in size. The value of |bits| is primarily driven by + * the number of connections that are expected in any time window. Note that + * this needs to account for there being two filters both of which have + * (presumably) independent false positive rates. The following formulae can be + * used to find a value of |bits| and |k| given a chosen false positive + * probability |p| and the number of requests expected in a given window |n|: + * + * bits = log2(n) + log2(-ln(1 - sqrt(1 - p))) + 1.0575327458897952 + * k = -log2(p) + * + * ... where log2 and ln are base 2 and e logarithms respectively. For a target + * false positive rate of 1% and 1000 handshake attempts, this produces bits=14 + * and k=7. This results in two Bloom filters that are 2kB each in size. Note + * that rounding |k| and |bits| up causes the false positive probability for + * these values to be a much lower 0.123%. + * + * IMPORTANT: This anti-replay scheme has several weaknesses. See the TLS 1.3 + * specification for the details of the generic problems with this technique. + * + * In addition to the generic anti-replay weaknesses, the state that the server + * maintains is in local memory only. Servers that operate in a cluster, even + * those that use shared memory for tickets, will not share anti-replay state. + * Early data can be replayed at least once with every server instance that will + * accept tickets that are encrypted with the same key. + */ +#define SSL_SetupAntiReplay(window, k, bits) \ + SSL_EXPERIMENTAL_API("SSL_SetupAntiReplay", \ + (PRTime _window, unsigned int _k, unsigned int _bits), \ + (window, k, bits)) + +/* + * This function allows a server application to generate a session ticket that + * will embed the provided token. + * + * This function will cause a NewSessionTicket message to be sent by a server. + * This happens even if SSL_ENABLE_SESSION_TICKETS is disabled. This allows a + * server to suppress the usually automatic generation of a session ticket at + * the completion of the handshake - which do not include any token - and to + * control when session tickets are transmitted. + * + * This function will fail unless the socket has an active TLS 1.3 session. + * Earlier versions of TLS do not support the spontaneous sending of the + * NewSessionTicket message. + */ +#define SSL_SendSessionTicket(fd, appToken, appTokenLen) \ + SSL_EXPERIMENTAL_API("SSL_SendSessionTicket", \ + (PRFileDesc * _fd, const PRUint8 *_appToken, \ + unsigned int _appTokenLen), \ + (fd, appToken, appTokenLen)) + +/* + * A stateless retry handler gives an application some control over NSS handling + * of ClientHello messages. + * + * SSL_HelloRetryRequestCallback() installs a callback that allows an + * application to control how NSS sends HelloRetryRequest messages. This + * handler is only used on servers and will only be called if the server selects + * TLS 1.3. Support for older TLS versions could be added in other releases. + * + * The SSLHelloRetryRequestCallback is invoked during the processing of a + * TLS 1.3 ClientHello message. It takes the following arguments: + * + * - |firstHello| indicates if the NSS believes that this is an initial + * ClientHello. An initial ClientHello will never include a cookie extension, + * though it may contain a session ticket. + * + * - |clientToken| includes a token previously provided by the application. If + * |clientTokenLen| is 0, then |clientToken| may be NULL. + * + * - If |firstHello| is PR_FALSE, the value that was provided in the + * |retryToken| outparam of previous invocations of this callback will be + * present here. + * + * - If |firstHello| is PR_TRUE, and the handshake is resuming a session, then + * this will contain any value that was passed in the |token| parameter of + * SSL_SendNewSessionTicket() method (see below). If this is not resuming a + * session, then the token will be empty (and this value could be NULL). + * + * - |clientTokenLen| is the length of |clientToken|. + * + * - |retryToken| is an item that callback can write to. This provides NSS with + * a token. This token is encrypted and integrity protected and embedded in + * the cookie extension of a HelloRetryRequest. The value of this field is + * only used if the handler returns ssl_stateless_retry_check. NSS allocates + * space for this value. + * + * - |retryTokenLen| is an outparam for the length of the token. If this value + * is not set, or set to 0, an empty token will be sent. + * + * - |retryTokenMax| is the size of the space allocated for retryToken. An + * application cannot write more than this many bytes to retryToken. + * + * - |arg| is the same value that was passed to + * SSL_InstallStatelessRetryHandler(). + * + * The handler can validate any the value of |clientToken|, query the socket + * status (using SSL_GetPreliminaryChannelInfo() for example) and decide how to + * proceed: + * + * - Returning ssl_hello_retry_fail causes the handshake to fail. This might be + * used if the token is invalid or the application wishes to abort the + * handshake. + * + * - Returning ssl_hello_retry_accept causes the handshake to proceed. + * + * - Returning ssl_hello_retry_request causes NSS to send a HelloRetryRequest + * message and request a second ClientHello. NSS generates a cookie extension + * and embeds the value of |retryToken|. The value of |retryToken| value may + * be left empty if the application does not require any additional context to + * validate a second ClientHello attempt. This return code cannot be used to + * reject a second ClientHello (i.e., when firstHello is PR_FALSE); NSS will + * abort the handshake if this value is returned from a second call. + * + * An application that chooses to perform a stateless retry can discard the + * server socket. All necessary state to continue the TLS handshake will be + * included in the cookie extension. This makes it possible to use a new socket + * to handle the remainder of the handshake. The existing socket can be safely + * discarded. + * + * If the same socket is retained, the information in the cookie will be checked + * for consistency against the existing state of the socket. Any discrepancy + * will result in the connection being closed. + * + * Tokens should be kept as small as possible. NSS sets a limit on the size of + * tokens, which it passes in |retryTokenMax|. Depending on circumstances, + * observing a smaller limit might be desirable or even necessary. For + * instance, having HelloRetryRequest and ClientHello fit in a single packet has + * significant performance benefits. + */ +typedef enum { + ssl_hello_retry_fail, + ssl_hello_retry_accept, + ssl_hello_retry_request +} SSLHelloRetryRequestAction; + +typedef SSLHelloRetryRequestAction(PR_CALLBACK *SSLHelloRetryRequestCallback)( + PRBool firstHello, const PRUint8 *clientToken, unsigned int clientTokenLen, + PRUint8 *retryToken, unsigned int *retryTokenLen, unsigned int retryTokMax, + void *arg); + +#define SSL_HelloRetryRequestCallback(fd, cb, arg) \ + SSL_EXPERIMENTAL_API("SSL_HelloRetryRequestCallback", \ + (PRFileDesc * _fd, \ + SSLHelloRetryRequestCallback _cb, void *_arg), \ + (fd, cb, arg)) + +/* Update traffic keys (TLS 1.3 only). + * + * The |requestUpdate| flag determines whether to request an update from the + * remote peer. + */ +#define SSL_KeyUpdate(fd, requestUpdate) \ + SSL_EXPERIMENTAL_API("SSL_KeyUpdate", \ + (PRFileDesc * _fd, PRBool _requestUpdate), \ + (fd, requestUpdate)) + +/* + * Session cache API. + */ + +/* + * Information that can be retrieved about a resumption token. + * See SSL_GetResumptionTokenInfo for details about how to use this API. + * Note that peerCert points to a certificate in the NSS database and must be + * copied by the application if it should be used after NSS shutdown or after + * calling SSL_DestroyResumptionTokenInfo. + */ +typedef struct SSLResumptionTokenInfoStr { + PRUint16 length; + CERTCertificate *peerCert; + PRUint8 *alpnSelection; + PRUint32 alpnSelectionLen; + PRUint32 maxEarlyDataSize; +} SSLResumptionTokenInfo; + +/* + * Allows applications to retrieve information about a resumption token. + * This does not require a TLS session. + * + * - The |tokenData| argument is a pointer to the resumption token as byte array + * of length |tokenLen|. + * - The |token| argument is a pointer to a SSLResumptionTokenInfo struct of + * of |len|. The struct gets filled by this function. + * See SSL_DestroyResumptionTokenInfo for information about how to manage the + * |token| memory. + */ +#define SSL_GetResumptionTokenInfo(tokenData, tokenLen, token, len) \ + SSL_EXPERIMENTAL_API("SSL_GetResumptionTokenInfo", \ + (const PRUint8 *_tokenData, unsigned int _tokenLen, \ + SSLResumptionTokenInfo *_token, PRUintn _len), \ + (tokenData, tokenLen, token, len)) + +/* + * SSL_GetResumptionTokenInfo allocates memory in order to populate |tokenInfo|. + * Any SSLResumptionTokenInfo struct filled with SSL_GetResumptionTokenInfo + * has to be freed with SSL_DestroyResumptionTokenInfo. + */ +#define SSL_DestroyResumptionTokenInfo(tokenInfo) \ + SSL_EXPERIMENTAL_API( \ + "SSL_DestroyResumptionTokenInfo", \ + (SSLResumptionTokenInfo * _tokenInfo), \ + (tokenInfo)) + +/* + * This is the function signature for function pointers used as resumption + * token callback. The caller has to copy the memory at |resumptionToken| with + * length |len| before returning. + * + * - The |fd| argument is the socket file descriptor. + * - The |resumptionToken| is a pointer to the resumption token as byte array + * of length |len|. + * - The |ctx| is a void pointer to the context set by the application in + * SSL_SetResumptionTokenCallback. + */ +typedef SECStatus(PR_CALLBACK *SSLResumptionTokenCallback)( + PRFileDesc *fd, const PRUint8 *resumptionToken, unsigned int len, + void *ctx); + +/* + * This allows setting a callback for external session caches to store + * resumption tokens. + * + * - The |fd| argument is the socket file descriptor. + * - The |cb| is a function pointer to an implementation of + * SSLResumptionTokenCallback. + * - The |ctx| is a pointer to some application specific context, which is + * returned when |cb| is called. + */ +#define SSL_SetResumptionTokenCallback(fd, cb, ctx) \ + SSL_EXPERIMENTAL_API( \ + "SSL_SetResumptionTokenCallback", \ + (PRFileDesc * _fd, SSLResumptionTokenCallback _cb, void *_ctx), \ + (fd, cb, ctx)) + +/* + * This allows setting a resumption token for a session. + * The function returns SECSuccess iff the resumption token can be used, + * SECFailure in any other case. The caller should remove the |token| from its + * cache when the function returns SECFailure. + * + * - The |fd| argument is the socket file descriptor. + * - The |token| is a pointer to the resumption token as byte array + * of length |len|. + */ +#define SSL_SetResumptionToken(fd, token, len) \ + SSL_EXPERIMENTAL_API( \ + "SSL_SetResumptionToken", \ + (PRFileDesc * _fd, const PRUint8 *_token, const unsigned int _len), \ + (fd, token, len)) + +/* TLS 1.3 allows a server to set a limit on the number of bytes of early data + * that can be received. This allows that limit to be set. This function has no + * effect on a client. */ +#define SSL_SetMaxEarlyDataSize(fd, size) \ + SSL_EXPERIMENTAL_API("SSL_SetMaxEarlyDataSize", \ + (PRFileDesc * _fd, PRUint32 _size), \ + (fd, size)) + +/* Deprecated experimental APIs */ + +#define SSL_UseAltServerHelloType(fd, enable) SSL_DEPRECATED_EXPERIMENTAL_API + +SEC_END_PROTOS + +#endif /* __sslexp_h_ */ diff --git a/security/nss/lib/ssl/sslimpl.h b/security/nss/lib/ssl/sslimpl.h index 64694b0df..10d0333d9 100644 --- a/security/nss/lib/ssl/sslimpl.h +++ b/security/nss/lib/ssl/sslimpl.h @@ -19,6 +19,7 @@ #include "secport.h" #include "secerr.h" #include "sslerr.h" +#include "sslexp.h" #include "ssl3prot.h" #include "hasht.h" #include "nssilock.h" @@ -34,36 +35,11 @@ #include "sslt.h" /* for some formerly private types, now public */ typedef struct sslSocketStr sslSocket; -typedef struct ssl3CipherSpecStr ssl3CipherSpec; +typedef struct sslNamedGroupDefStr sslNamedGroupDef; +#include "sslencode.h" +#include "sslexp.h" #include "ssl3ext.h" - -/* to make some of these old enums public without namespace pollution, -** it was necessary to prepend ssl_ to the names. -** These #defines preserve compatibility with the old code here in libssl. -*/ -typedef SSLMACAlgorithm SSL3MACAlgorithm; - -#define calg_null ssl_calg_null -#define calg_rc4 ssl_calg_rc4 -#define calg_rc2 ssl_calg_rc2 -#define calg_des ssl_calg_des -#define calg_3des ssl_calg_3des -#define calg_idea ssl_calg_idea -#define calg_fortezza ssl_calg_fortezza /* deprecated, must preserve */ -#define calg_aes ssl_calg_aes -#define calg_camellia ssl_calg_camellia -#define calg_seed ssl_calg_seed -#define calg_aes_gcm ssl_calg_aes_gcm -#define calg_chacha20 ssl_calg_chacha20 - -#define mac_null ssl_mac_null -#define mac_md5 ssl_mac_md5 -#define mac_sha ssl_mac_sha -#define hmac_md5 ssl_hmac_md5 -#define hmac_sha ssl_hmac_sha -#define hmac_sha256 ssl_hmac_sha256 -#define hmac_sha384 ssl_hmac_sha384 -#define mac_aead ssl_mac_aead +#include "sslspec.h" #if defined(DEBUG) || defined(TRACE) #ifdef __cplusplus @@ -160,7 +136,7 @@ typedef enum { ticket_allow_psk_sign_auth = 16 } TLS13SessionTicketFlags; -typedef struct { +struct sslNamedGroupDefStr { /* The name is the value that is encoded on the wire in TLS. */ SSLNamedGroup name; /* The number of bits in the group. */ @@ -172,9 +148,8 @@ typedef struct { SECOidTag oidTag; /* Assume that the group is always supported. */ PRBool assumeSupported; -} sslNamedGroupDef; +}; -typedef struct sslBufferStr sslBuffer; typedef struct sslConnectInfoStr sslConnectInfo; typedef struct sslGatherStr sslGather; typedef struct sslSecurityInfoStr sslSecurityInfo; @@ -183,8 +158,6 @@ typedef struct sslSocketOpsStr sslSocketOps; typedef struct ssl3StateStr ssl3State; typedef struct ssl3CertNodeStr ssl3CertNode; -typedef struct ssl3BulkCipherDefStr ssl3BulkCipherDef; -typedef struct ssl3MACDefStr ssl3MACDef; typedef struct sslKeyPairStr sslKeyPair; typedef struct ssl3DHParamsStr ssl3DHParams; @@ -195,15 +168,15 @@ struct ssl3CertNodeStr { typedef SECStatus (*sslHandshakeFunc)(sslSocket *ss); -typedef void (*sslSessionIDCacheFunc)(sslSessionID *sid); -typedef void (*sslSessionIDUncacheFunc)(sslSessionID *sid); +void ssl_CacheSessionID(sslSocket *ss); +void ssl_UncacheSessionID(sslSocket *ss); +void ssl_ServerCacheSessionID(sslSessionID *sid); +void ssl_ServerUncacheSessionID(sslSessionID *sid); + typedef sslSessionID *(*sslSessionIDLookupFunc)(const PRIPv6Addr *addr, unsigned char *sid, unsigned int sidLen, CERTCertDBHandle *dbHandle); -typedef void (*sslCipherSpecChangedFunc)(void *arg, - PRBool sending, - ssl3CipherSpec *newSpec); /* Socket ops */ struct sslSocketOpsStr { @@ -229,20 +202,9 @@ struct sslSocketOpsStr { #define ssl_SEND_FLAG_FORCE_INTO_BUFFER 0x40000000 #define ssl_SEND_FLAG_NO_BUFFER 0x20000000 #define ssl_SEND_FLAG_NO_RETRANSMIT 0x08000000 /* DTLS only */ -#define ssl_SEND_FLAG_CAP_RECORD_VERSION \ - 0x04000000 /* TLS only */ #define ssl_SEND_FLAG_MASK 0x7f000000 /* -** A buffer object. -*/ -struct sslBufferStr { - unsigned char *buf; - unsigned int len; - unsigned int space; -}; - -/* ** SSL3 cipher suite policy and preference struct. */ typedef struct { @@ -271,6 +233,7 @@ typedef struct sslOptionsStr { * list of supported protocols. */ SECItem nextProtoNego; + PRUint32 maxEarlyDataSize; unsigned int useSecurity : 1; unsigned int useSocks : 1; unsigned int requestCertificate : 1; @@ -282,7 +245,7 @@ typedef struct sslOptionsStr { unsigned int detectRollBack : 1; unsigned int noLocks : 1; unsigned int enableSessionTickets : 1; - unsigned int enableDeflate : 1; + unsigned int enableDeflate : 1; /* Deprecated. */ unsigned int enableRenegotiation : 2; unsigned int requireSafeNegotiation : 1; unsigned int enableFalseStart : 1; @@ -297,7 +260,7 @@ typedef struct sslOptionsStr { unsigned int enableSignedCertTimestamps : 1; unsigned int requireDHENamedGroups : 1; unsigned int enable0RttData : 1; - unsigned int enableShortHeaders : 1; + unsigned int enableTls13CompatMode : 1; } sslOptions; typedef enum { sslHandshakingUndetermined = 0, @@ -382,140 +345,20 @@ struct sslGatherStr { #define GS_HEADER 1 #define GS_DATA 2 -/* -** ssl3State and CipherSpec structs -*/ - -/* The SSL bulk cipher definition */ -typedef enum { - cipher_null, - cipher_rc4, - cipher_des, - cipher_3des, - cipher_aes_128, - cipher_aes_256, - cipher_camellia_128, - cipher_camellia_256, - cipher_seed, - cipher_aes_128_gcm, - cipher_aes_256_gcm, - cipher_chacha20, - cipher_missing /* reserved for no such supported cipher */ - /* This enum must match ssl3_cipherName[] in ssl3con.c. */ -} SSL3BulkCipher; - -typedef enum { type_stream, - type_block, - type_aead } CipherType; - -#define MAX_IV_LENGTH 24 - -typedef PRUint64 sslSequenceNumber; -typedef PRUint16 DTLSEpoch; - -typedef void (*DTLSTimerCb)(sslSocket *); +#define WRAPPED_MASTER_SECRET_SIZE 48 typedef struct { - PRUint8 wrapped_master_secret[48]; - PRUint16 wrapped_master_secret_len; - PRUint8 msIsWrapped; + PRUint8 wrapped_master_secret[WRAPPED_MASTER_SECRET_SIZE]; + PRUint8 wrapped_master_secret_len; PRUint8 resumable; PRUint8 extendedMasterSecretUsed; } ssl3SidKeys; /* 52 bytes */ -typedef struct { - PK11SymKey *write_key; - PK11SymKey *write_mac_key; - PK11Context *write_mac_context; - SECItem write_key_item; - SECItem write_iv_item; - SECItem write_mac_key_item; - PRUint8 write_iv[MAX_IV_LENGTH]; -} ssl3KeyMaterial; - -typedef SECStatus (*SSLCipher)(void *context, - unsigned char *out, - int *outlen, - int maxout, - const unsigned char *in, - int inlen); -typedef SECStatus (*SSLAEADCipher)( - ssl3KeyMaterial *keys, - PRBool doDecrypt, - unsigned char *out, - int *outlen, - int maxout, - const unsigned char *in, - int inlen, - const unsigned char *additionalData, - int additionalDataLen); -typedef SECStatus (*SSLCompressor)(void *context, - unsigned char *out, - int *outlen, - int maxout, - const unsigned char *in, - int inlen); -typedef SECStatus (*SSLDestroy)(void *context, PRBool freeit); - -/* The DTLS anti-replay window in number of packets. Defined here because we - * need it in the cipher spec. Note that this is a ring buffer but left and - * right represent the true window, with modular arithmetic used to map them - * onto the buffer. - */ -#define DTLS_RECVD_RECORDS_WINDOW 1024 -#define RECORD_SEQ_MAX ((1ULL << 48) - 1) -PR_STATIC_ASSERT(DTLS_RECVD_RECORDS_WINDOW % 8 == 0); - -typedef struct DTLSRecvdRecordsStr { - unsigned char data[DTLS_RECVD_RECORDS_WINDOW / 8]; - sslSequenceNumber left; - sslSequenceNumber right; -} DTLSRecvdRecords; - -/* -** These are the "specs" in the "ssl3" struct. -** Access to the pointers to these specs, and all the specs' contents -** (direct and indirect) is protected by the reader/writer lock ss->specLock. -*/ -struct ssl3CipherSpecStr { - PRCList link; - const ssl3BulkCipherDef *cipher_def; - const ssl3MACDef *mac_def; - SSLCompressionMethod compression_method; - int mac_size; - SSLCipher encode; - SSLCipher decode; - SSLAEADCipher aead; - void *encodeContext; - void *decodeContext; - SSLCompressor compressor; /* Don't name these fields compress */ - SSLCompressor decompressor; /* and uncompress because zconf.h */ - /* may define them as macros. */ - SSLDestroy destroyCompressContext; - void *compressContext; - SSLDestroy destroyDecompressContext; - void *decompressContext; - PK11SymKey *master_secret; - sslSequenceNumber write_seq_num; - sslSequenceNumber read_seq_num; - SSL3ProtocolVersion version; - ssl3KeyMaterial client; - ssl3KeyMaterial server; - SECItem msItem; - DTLSEpoch epoch; - 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; - - PRUint8 refCt; - const char *phase; -}; - typedef enum { never_cached, in_client_cache, in_server_cache, - invalid_cache /* no longer in any cache. */ + invalid_cache, /* no longer in any cache. */ + in_external_cache } Cached; #include "sslcert.h" @@ -527,7 +370,7 @@ struct sslSessionIDStr { sslSessionID *next; /* chain used for client sockets, only */ Cached cached; int references; - PRUint32 lastAccessTime; /* seconds since Jan 1, 1970 */ + PRTime lastAccessTime; /* The rest of the members, except for the members of u.ssl3.locked, may * be modified only when the sid is not in any cache. @@ -545,13 +388,15 @@ struct sslSessionIDStr { SSL3ProtocolVersion version; - PRUint32 creationTime; /* seconds since Jan 1, 1970 */ - PRUint32 expirationTime; /* seconds since Jan 1, 1970 */ + PRTime creationTime; + PRTime expirationTime; SSLAuthType authType; PRUint32 authKeyBits; SSLKEAType keaType; PRUint32 keaKeyBits; + SSLNamedGroup keaGroup; + SSLSignatureScheme sigScheme; union { struct { @@ -560,18 +405,11 @@ struct sslSessionIDStr { PRUint8 sessionID[SSL3_SESSIONID_BYTES]; ssl3CipherSuite cipherSuite; - SSLCompressionMethod compression; - int policy; + PRUint8 policy; ssl3SidKeys keys; /* mechanism used to wrap master secret */ CK_MECHANISM_TYPE masterWrapMech; - /* The following values are NOT restored from the server's on-disk - * session cache, but are restored from the client's cache. - */ - PK11SymKey *clientWriteKey; - PK11SymKey *serverWriteKey; - /* The following values pertain to the slot that wrapped the ** master secret. (used only in client) */ @@ -627,13 +465,13 @@ struct sslSessionIDStr { } u; }; -typedef struct ssl3CipherSuiteDefStr { +struct ssl3CipherSuiteDefStr { ssl3CipherSuite cipher_suite; SSL3BulkCipher bulk_cipher_alg; SSL3MACAlgorithm mac_alg; SSL3KeyExchangeAlgorithm key_exchange_alg; SSLHashType prf_hash; -} ssl3CipherSuiteDef; +}; /* ** There are tables of these, all const. @@ -656,37 +494,6 @@ typedef struct { SECOidTag oid; } ssl3KEADef; -/* -** There are tables of these, all const. -*/ -struct ssl3BulkCipherDefStr { - SSL3BulkCipher cipher; - SSLCipherAlgorithm calg; - unsigned int key_size; - unsigned int secret_key_size; - CipherType type; - unsigned int iv_size; - unsigned int block_size; - unsigned int tag_size; /* for AEAD ciphers. */ - unsigned int explicit_nonce_size; /* for AEAD ciphers. */ - SECOidTag oid; - const char *short_name; - /* The maximum number of records that can be sent/received with the same - * symmetric key before the connection will be terminated. */ - PRUint64 max_records; -}; - -/* -** There are tables of these, all const. -*/ -struct ssl3MACDefStr { - SSL3MACAlgorithm mac; - CK_MECHANISM_TYPE mmech; - int pad_size; - int mac_size; - SECOidTag oid; -}; - typedef enum { ssl_0rtt_none, /* 0-RTT not present */ ssl_0rtt_sent, /* 0-RTT sent (no decision yet) */ @@ -704,6 +511,7 @@ typedef enum { typedef enum { idle_handshake, wait_client_hello, + wait_end_of_early_data, wait_client_cert, wait_client_key, wait_cert_verify, @@ -760,14 +568,15 @@ typedef enum { handshake_hash_record } SSL3HandshakeHashType; -/* This holds state for TLS 1.3 CertificateRequest handling. */ -typedef struct TLS13CertificateRequestStr { - PLArenaPool *arena; - SECItem context; - SSLSignatureScheme *signatureSchemes; - unsigned int signatureSchemeCount; - CERTDistNames ca_list; -} TLS13CertificateRequest; +// A DTLS Timer. +typedef void (*DTLSTimerCb)(sslSocket *); + +typedef struct { + const char *label; + DTLSTimerCb cb; + PRIntervalTime started; + PRUint32 timeout; +} dtlsTimer; /* ** This is the "hs" member of the "ssl3" struct. @@ -791,13 +600,12 @@ typedef struct SSL3HandshakeStateStr { const ssl3KEADef *kea_def; ssl3CipherSuite cipher_suite; const ssl3CipherSuiteDef *suite_def; - SSLCompressionMethod compression; sslBuffer msg_body; /* protected by recvBufLock */ /* partial handshake message from record layer */ unsigned int header_bytes; /* number of bytes consumed from handshake */ /* message for message type and header length */ - SSL3HandshakeType msg_type; + SSLHandshakeType msg_type; unsigned long msg_len; PRBool isResuming; /* we are resuming (not used in TLS 1.3) */ PRBool sendingSCSV; /* instead of empty RI */ @@ -834,25 +642,25 @@ typedef struct SSL3HandshakeStateStr { PRCList remoteExtensions; /* Parsed incoming extensions */ /* This group of values is used for DTLS */ - PRUint16 sendMessageSeq; /* The sending message sequence + PRUint16 sendMessageSeq; /* The sending message sequence * number */ - PRCList lastMessageFlight; /* The last message flight we + PRCList lastMessageFlight; /* The last message flight we * sent */ - PRUint16 maxMessageSent; /* The largest message we sent */ - PRUint16 recvMessageSeq; /* The receiving message sequence + PRUint16 maxMessageSent; /* The largest message we sent */ + PRUint16 recvMessageSeq; /* The receiving message sequence * number */ - sslBuffer recvdFragments; /* The fragments we have received in + sslBuffer recvdFragments; /* The fragments we have received in * a bitmask */ - PRInt32 recvdHighWater; /* The high water mark for fragments + PRInt32 recvdHighWater; /* The high water mark for fragments * received. -1 means no reassembly * in progress. */ - SECItem cookie; /* The Hello(Retry|Verify)Request cookie. */ - PRIntervalTime rtTimerStarted; /* When the timer was started */ - DTLSTimerCb rtTimerCb; /* The function to call on expiry */ - PRUint32 rtTimeoutMs; /* The length of the current timeout - * used for backoff (in ms) */ - PRUint32 rtRetries; /* The retry counter */ - SECItem srvVirtName; /* for server: name that was negotiated + SECItem cookie; /* The Hello(Retry|Verify)Request cookie. */ + dtlsTimer timers[3]; /* Holder for timers. */ + dtlsTimer *rtTimer; /* Retransmit timer. */ + dtlsTimer *ackTimer; /* Ack timer (DTLS 1.3 only). */ + dtlsTimer *hdTimer; /* Read cipher holddown timer (DLTS 1.3 only) */ + PRUint32 rtRetries; /* The retry counter */ + SECItem srvVirtName; /* for server: name that was negotiated * with a client. For client - is * always set to NULL.*/ @@ -869,22 +677,37 @@ typedef struct SSL3HandshakeStateStr { PK11SymKey *serverTrafficSecret; /* traffic keys */ PK11SymKey *earlyExporterSecret; /* for 0-RTT exporters */ PK11SymKey *exporterSecret; /* for exporters */ - /* The certificate request from the server. */ - TLS13CertificateRequest *certificateRequest; - PRCList cipherSpecs; /* The cipher specs in the sequence they - * will be applied. */ - sslZeroRttState zeroRttState; /* Are we doing a 0-RTT handshake? */ - sslZeroRttIgnore zeroRttIgnore; /* Are we ignoring 0-RTT? */ - ssl3CipherSuite zeroRttSuite; /* The cipher suite we used for 0-RTT. */ - PRCList bufferedEarlyData; /* Buffered TLS 1.3 early data - * on server.*/ - PRBool helloRetry; /* True if HelloRetryRequest has been sent - * or received. */ - ssl3KEADef kea_def_mutable; /* Used to hold the writable kea_def - * we use for TLS 1.3 */ - PRBool shortHeaders; /* Assigned if we are doing short headers. */ + PRCList cipherSpecs; /* The cipher specs in the sequence they + * will be applied. */ + sslZeroRttState zeroRttState; /* Are we doing a 0-RTT handshake? */ + sslZeroRttIgnore zeroRttIgnore; /* Are we ignoring 0-RTT? */ + ssl3CipherSuite zeroRttSuite; /* The cipher suite we used for 0-RTT. */ + PRCList bufferedEarlyData; /* Buffered TLS 1.3 early data + * on server.*/ + PRBool helloRetry; /* True if HelloRetryRequest has been sent + * or received. */ + PRBool receivedCcs; /* A server received ChangeCipherSpec + * before the handshake started. */ + PRBool clientCertRequested; /* True if CertificateRequest received. */ + ssl3KEADef kea_def_mutable; /* Used to hold the writable kea_def + * we use for TLS 1.3 */ + PRTime serverHelloTime; /* Time the ServerHello flight was sent. */ + PRUint16 ticketNonce; /* A counter we use for tickets. */ + SECItem fakeSid; /* ... (server) the SID the client used. */ + PRBool endOfFlight; /* Processed a full flight (DTLS 1.3). */ + + /* The following lists contain DTLSHandshakeRecordEntry */ + PRCList dtlsSentHandshake; /* Used to map records to handshake fragments. */ + PRCList dtlsRcvdHandshake; /* Handshake records we have received + * used to generate ACKs. */ } SSL3HandshakeState; +#define SSL_ASSERT_HASHES_EMPTY(ss) \ + do { \ + PORT_Assert(ss->ssl3.hs.hashType == handshake_hash_unknown); \ + PORT_Assert(ss->ssl3.hs.messages.len == 0); \ + } while (0) + /* ** This is the "ssl3" struct, as in "ss->ssl3". ** note: @@ -904,6 +727,10 @@ struct ssl3StateStr { ssl3CipherSpec *cwSpec; /* current write spec. */ ssl3CipherSpec *pwSpec; /* pending write spec. */ + /* This is true after the peer requests a key update; false after a key + * update is initiated locally. */ + PRBool peerRequestedKeyUpdate; + /* Internal callback for when we do a cipher suite change. Used for * debugging in TLS 1.3. This can only be set by non-public functions. */ sslCipherSpecChangedFunc changedCipherSpecFunc; @@ -914,7 +741,7 @@ struct ssl3StateStr { CERTCertificateList *clientCertChain; /* used by client */ PRBool sendEmptyCert; /* used by client */ - int policy; + PRUint8 policy; /* This says what cipher suites we can do, and should * be either SSL_ALLOWED or SSL_RESTRICTED */ @@ -924,9 +751,7 @@ struct ssl3StateStr { /* chain while we are trying to validate it. */ CERTDistNames *ca_list; /* used by server. trusted CAs for this socket. */ - PRBool initialized; SSL3HandshakeState hs; - ssl3CipherSpec specs[2]; /* one is current, one is pending. */ PRUint16 mtu; /* Our estimate of the MTU */ @@ -995,11 +820,12 @@ typedef struct SessionTicketStr { PRBool valid; SSL3ProtocolVersion ssl_version; ssl3CipherSuite cipher_suite; - SSLCompressionMethod compression_method; SSLAuthType authType; PRUint32 authKeyBits; SSLKEAType keaType; PRUint32 keaKeyBits; + SSLNamedGroup originalKeaGroup; + SSLSignatureScheme signatureScheme; const sslNamedGroupDef *namedCurve; /* For certificate lookup. */ /* @@ -1012,11 +838,13 @@ typedef struct SessionTicketStr { PRBool extendedMasterSecretUsed; ClientAuthenticationType client_auth_type; SECItem peer_cert; - PRUint32 timestamp; + PRTime timestamp; PRUint32 flags; SECItem srvName; /* negotiated server name */ SECItem alpnSelection; PRUint32 maxEarlyData; + PRUint32 ticketAgeBaseline; + SECItem applicationToken; } SessionTicket; /* @@ -1066,17 +894,10 @@ struct sslSecurityInfoStr { SSLKEAType keaType; PRUint32 keaKeyBits; const sslNamedGroupDef *keaGroup; + const sslNamedGroupDef *originalKeaGroup; /* The selected certificate (for servers only). */ const sslServerCert *serverCert; - /* - ** Procs used for SID cache (nonce) management. - ** Different implementations exist for clients/servers - ** The lookup proc is only used for servers. Baloney! - */ - sslSessionIDCacheFunc cache; - sslSessionIDUncacheFunc uncache; - /* These are used during a connection handshake */ sslConnectInfo ci; }; @@ -1151,6 +972,11 @@ struct sslSocketStr { void *pkcs11PinArg; SSLNextProtoCallback nextProtoCallback; void *nextProtoArg; + SSLHelloRetryRequestCallback hrrCallback; + void *hrrCallbackArg; + PRCList extensionHooks; + SSLResumptionTokenCallback resumptionTokenCallback; + void *resumptionTokenContext; PRIntervalTime rTimeout; /* timeout for NSPR I/O */ PRIntervalTime wTimeout; /* timeout for NSPR I/O */ @@ -1241,15 +1067,13 @@ extern char ssl_debug; extern char ssl_trace; extern FILE *ssl_trace_iob; extern FILE *ssl_keylog_iob; +extern PZLock *ssl_keylog_lock; extern PRUint32 ssl3_sid_timeout; extern PRUint32 ssl_ticket_lifetime; -extern PRUint32 ssl_max_early_data_size; extern const char *const ssl3_cipherName[]; extern sslSessionIDLookupFunc ssl_sid_lookup; -extern sslSessionIDCacheFunc ssl_sid_cache; -extern sslSessionIDUncacheFunc ssl_sid_uncache; extern const sslNamedGroupDef ssl_named_groups[]; @@ -1331,18 +1155,13 @@ extern SECStatus ssl_BeginClientHandshake(sslSocket *ss); extern SECStatus ssl_BeginServerHandshake(sslSocket *ss); extern int ssl_Do1stHandshake(sslSocket *ss); -extern SECStatus sslBuffer_Grow(sslBuffer *b, unsigned int newLen); -extern SECStatus sslBuffer_Append(sslBuffer *b, const void *data, - unsigned int len); -extern void sslBuffer_Clear(sslBuffer *b); - -extern void ssl_ChooseSessionIDProcs(sslSecurityInfo *sec); - -extern void ssl3_InitCipherSpec(ssl3CipherSpec *spec); +extern SECStatus ssl3_InitPendingCipherSpecs(sslSocket *ss, PK11SymKey *secret, + PRBool derive); extern sslSessionID *ssl3_NewSessionID(sslSocket *ss, PRBool is_server); extern sslSessionID *ssl_LookupSID(const PRIPv6Addr *addr, PRUint16 port, const char *peerID, const char *urlSvrName); extern void ssl_FreeSID(sslSessionID *sid); +extern void ssl_DestroySID(sslSessionID *sid, PRBool freeIt); extern int ssl3_SendApplicationData(sslSocket *ss, const PRUint8 *in, int len, int flags); @@ -1363,11 +1182,20 @@ extern SECStatus ssl_CipherPrefSetDefault(PRInt32 which, PRBool enabled); extern SECStatus ssl3_ConstrainRangeByPolicy(void); -extern void ssl3_InitState(sslSocket *ss); +extern SECStatus ssl3_InitState(sslSocket *ss); +extern SECStatus Null_Cipher(void *ctx, unsigned char *output, int *outputLen, + int maxOutputLen, const unsigned char *input, + int inputLen); extern void ssl3_RestartHandshakeHashes(sslSocket *ss); extern SECStatus ssl3_UpdateHandshakeHashes(sslSocket *ss, const unsigned char *b, unsigned int l); +SECStatus +ssl_HashHandshakeMessageInt(sslSocket *ss, SSLHandshakeType type, + PRUint32 dtlsSeq, + const PRUint8 *b, PRUint32 length); +SECStatus ssl_HashHandshakeMessage(sslSocket *ss, SSLHandshakeType type, + const PRUint8 *b, PRUint32 length); /* Returns PR_TRUE if we are still waiting for the server to complete its * response to our client second round. Once we've received the Finished from @@ -1380,21 +1208,14 @@ extern PRInt32 ssl3_SendRecord(sslSocket *ss, ssl3CipherSpec *cwSpec, const PRUint8 *pIn, PRInt32 nIn, PRInt32 flags); -#ifdef NSS_SSL_ENABLE_ZLIB -/* - * The DEFLATE algorithm can result in an expansion of 0.1% + 12 bytes. For a - * maximum TLS record payload of 2**14 bytes, that's 29 bytes. - */ -#define SSL3_COMPRESSION_MAX_EXPANSION 29 -#else /* !NSS_SSL_ENABLE_ZLIB */ -#define SSL3_COMPRESSION_MAX_EXPANSION 0 -#endif +/* Clear any PRCList, optionally calling f on the value. */ +void ssl_ClearPRCList(PRCList *list, void (*f)(void *)); /* - * make sure there is room in the write buffer for padding and - * other compression and cryptographic expansions. + * Make sure there is room in the write buffer for padding and + * cryptographic expansions. */ -#define SSL3_BUFFER_FUDGE 100 + SSL3_COMPRESSION_MAX_EXPANSION +#define SSL3_BUFFER_FUDGE 100 #define SSL_LOCK_READER(ss) \ if (ss->recvLock) \ @@ -1547,7 +1368,7 @@ extern SECStatus ssl3_AuthCertificateComplete(sslSocket *ss, PRErrorCode error); * for dealing with SSL 3.0 clients sending SSL 2.0 format hellos */ extern SECStatus ssl3_HandleV2ClientHello( - sslSocket *ss, unsigned char *buffer, int length, PRUint8 padding); + sslSocket *ss, unsigned char *buffer, unsigned int length, PRUint8 padding); SECStatus ssl3_SendClientHello(sslSocket *ss, sslClientHelloType type); @@ -1583,7 +1404,7 @@ extern PRBool ssl_HaveEphemeralKeyPair(const sslSocket *ss, const sslNamedGroupDef *groupDef); extern void ssl_FreeEphemeralKeyPairs(sslSocket *ss); -extern SECStatus ssl_AppendPaddedDHKeyShare(const sslSocket *ss, +extern SECStatus ssl_AppendPaddedDHKeyShare(sslBuffer *buf, const SECKEYPublicKey *pubKey, PRBool appendLength); extern const ssl3DHParams *ssl_GetDHEParams(const sslNamedGroupDef *groupDef); @@ -1645,6 +1466,10 @@ extern SECStatus ssl_ClientReadVersion(sslSocket *ss, PRUint8 **b, extern SECStatus ssl3_NegotiateVersion(sslSocket *ss, SSL3ProtocolVersion peerVersion, PRBool allowLargerPeerVersion); +extern SECStatus ssl_ClientSetCipherSuite(sslSocket *ss, + SSL3ProtocolVersion version, + ssl3CipherSuite suite, + PRBool initHashes); extern SECStatus ssl_GetPeerInfo(sslSocket *ss); @@ -1660,23 +1485,11 @@ extern SECStatus ssl3_SendECDHServerKeyExchange(sslSocket *ss); extern SECStatus ssl_ImportECDHKeyShare( sslSocket *ss, SECKEYPublicKey *peerKey, PRUint8 *b, PRUint32 length, const sslNamedGroupDef *curve); -SECStatus tls13_EncodeECDHEKeyShareKEX(const sslSocket *ss, - const SECKEYPublicKey *pubKey); extern SECStatus ssl3_ComputeCommonKeyHash(SSLHashType hashAlg, PRUint8 *hashBuf, unsigned int bufLen, SSL3Hashes *hashes); -extern void ssl3_DestroyCipherSpec(ssl3CipherSpec *spec, PRBool freeSrvName); -extern SECStatus ssl3_InitPendingCipherSpec(sslSocket *ss, PK11SymKey *pms); -extern SECStatus ssl3_AppendHandshake(sslSocket *ss, const void *void_src, - PRInt32 bytes); -extern SECStatus ssl3_AppendHandshakeHeader(sslSocket *ss, - SSL3HandshakeType t, PRUint32 length); -extern SECStatus ssl3_AppendHandshakeNumber(sslSocket *ss, PRInt32 num, - PRInt32 lenSize); -extern SECStatus ssl3_AppendHandshakeVariable(sslSocket *ss, - const PRUint8 *src, PRInt32 bytes, PRInt32 lenSize); extern SECStatus ssl3_AppendSignatureAndHashAlgorithm( sslSocket *ss, const SSLSignatureAndHashAlg *sigAndHash); extern SECStatus ssl3_ConsumeHandshake(sslSocket *ss, void *v, PRUint32 bytes, @@ -1684,11 +1497,12 @@ extern SECStatus ssl3_ConsumeHandshake(sslSocket *ss, void *v, PRUint32 bytes, extern SECStatus ssl3_ConsumeHandshakeNumber(sslSocket *ss, PRUint32 *num, PRUint32 bytes, PRUint8 **b, PRUint32 *length); +extern SECStatus ssl3_ConsumeHandshakeNumber64(sslSocket *ss, PRUint64 *num, + PRUint32 bytes, PRUint8 **b, + PRUint32 *length); extern SECStatus ssl3_ConsumeHandshakeVariable(sslSocket *ss, SECItem *i, PRUint32 bytes, PRUint8 **b, PRUint32 *length); -extern PRUint8 *ssl_EncodeUintX(PRUint64 value, unsigned int bytes, - PRUint8 *to); extern PRBool ssl_IsSupportedSignatureScheme(SSLSignatureScheme scheme); extern SECStatus ssl_CheckSignatureSchemeConsistency( sslSocket *ss, SSLSignatureScheme scheme, CERTCertificate *cert); @@ -1703,16 +1517,20 @@ extern SECStatus ssl3_SignHashes(sslSocket *ss, SSL3Hashes *hash, SECKEYPrivateKey *key, SECItem *buf); extern SECStatus ssl3_VerifySignedHashes(sslSocket *ss, SSLSignatureScheme scheme, SSL3Hashes *hash, SECItem *buf); -extern SECStatus ssl3_CacheWrappedMasterSecret( - sslSocket *ss, sslSessionID *sid, ssl3CipherSpec *spec); +extern SECStatus ssl3_CacheWrappedSecret(sslSocket *ss, sslSessionID *sid, + PK11SymKey *secret); extern void ssl3_FreeSniNameArray(TLSExtensionData *xtnData); /* Hello Extension related routines. */ extern void ssl3_SetSIDSessionTicket(sslSessionID *sid, /*in/out*/ NewSessionTicket *session_ticket); SECStatus ssl3_EncodeSessionTicket(sslSocket *ss, - const NewSessionTicket *ticket_input, - SECItem *ticket_data); + const NewSessionTicket *ticket, + const PRUint8 *appToken, + unsigned int appTokenLen, + PK11SymKey *secret, SECItem *ticket_data); +SECStatus SSLExp_SendSessionTicket(PRFileDesc *fd, const PRUint8 *token, + unsigned int tokenLen); SECStatus ssl_MaybeSetSelfEncryptKeyPair(const sslKeyPair *keyPair); SECStatus ssl_GetSelfEncryptKeys(sslSocket *ss, unsigned char *keyName, @@ -1728,7 +1546,7 @@ extern void ssl_FreePRSocket(PRFileDesc *fd); /* Internal config function so SSL3 can initialize the present state of * various ciphers */ -extern int ssl3_config_match_init(sslSocket *); +extern unsigned int ssl3_config_match_init(sslSocket *); /* calls for accessing wrapping keys across processes. */ extern SECStatus @@ -1758,44 +1576,11 @@ extern SECStatus ssl_InitSessionCacheLocks(PRBool lazyInit); extern SECStatus ssl_FreeSessionCacheLocks(void); -/**************** DTLS-specific functions **************/ -extern void dtls_FreeHandshakeMessage(DTLSQueuedMessage *msg); -extern void dtls_FreeHandshakeMessages(PRCList *lst); - -extern SECStatus dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf); -extern SECStatus dtls_HandleHelloVerifyRequest(sslSocket *ss, - PRUint8 *b, PRUint32 length); -extern SECStatus dtls_StageHandshakeMessage(sslSocket *ss); -extern SECStatus dtls_QueueMessage(sslSocket *ss, SSL3ContentType type, - const PRUint8 *pIn, PRInt32 nIn); -extern SECStatus dtls_FlushHandshakeMessages(sslSocket *ss, PRInt32 flags); -SECStatus ssl3_DisableNonDTLSSuites(sslSocket *ss); -extern SECStatus dtls_StartHolddownTimer(sslSocket *ss); -extern void dtls_CheckTimer(sslSocket *ss); -extern void dtls_CancelTimer(sslSocket *ss); -extern void dtls_SetMTU(sslSocket *ss, PRUint16 advertised); -extern void dtls_InitRecvdRecords(DTLSRecvdRecords *records); -extern int dtls_RecordGetRecvd(const DTLSRecvdRecords *records, - sslSequenceNumber seq); -extern void dtls_RecordSetRecvd(DTLSRecvdRecords *records, - sslSequenceNumber seq); -extern void dtls_RehandshakeCleanup(sslSocket *ss); -extern SSL3ProtocolVersion -dtls_TLSVersionToDTLSVersion(SSL3ProtocolVersion tlsv); -extern SSL3ProtocolVersion -dtls_DTLSVersionToTLSVersion(SSL3ProtocolVersion dtlsv); -extern PRBool dtls_IsRelevant(sslSocket *ss, const SSL3Ciphertext *cText, - PRBool *sameEpoch, PRUint64 *seqNum); -extern SECStatus dtls_MaybeRetransmitHandshake(sslSocket *ss, - const SSL3Ciphertext *cText, - PRBool sameEpoch); - CK_MECHANISM_TYPE ssl3_Alg2Mech(SSLCipherAlgorithm calg); SECStatus ssl3_NegotiateCipherSuite(sslSocket *ss, const SECItem *suites, PRBool initHashes); SECStatus ssl3_InitHandshakeHashes(sslSocket *ss); SECStatus ssl3_ServerCallSNICallback(sslSocket *ss); -SECStatus ssl3_SetupPendingCipherSpec(sslSocket *ss); SECStatus ssl3_FlushHandshake(sslSocket *ss, PRInt32 flags); SECStatus ssl3_CompleteHandleCertificate(sslSocket *ss, PRUint8 *b, PRUint32 length); @@ -1807,17 +1592,21 @@ SECStatus ssl3_SendCertificateStatus(sslSocket *ss); SECStatus ssl3_AuthCertificate(sslSocket *ss); SECStatus ssl_ReadCertificateStatus(sslSocket *ss, PRUint8 *b, PRUint32 length); -SECStatus ssl3_EncodeSigAlgs(const sslSocket *ss, PRUint8 *buf, - unsigned maxLen, PRUint32 *len); -SECStatus ssl_GetCertificateRequestCAs(sslSocket *ss, unsigned int *calenp, - SECItem **namesp, unsigned int *nnamesp); +SECStatus ssl3_EncodeSigAlgs(const sslSocket *ss, sslBuffer *buf); +SECStatus ssl_GetCertificateRequestCAs(const sslSocket *ss, + unsigned int *calenp, + const SECItem **namesp, + unsigned int *nnamesp); SECStatus ssl3_ParseCertificateRequestCAs(sslSocket *ss, PRUint8 **b, - PRUint32 *length, PLArenaPool *arena, - CERTDistNames *ca_list); + PRUint32 *length, CERTDistNames *ca_list); SECStatus ssl3_CompleteHandleCertificateRequest( sslSocket *ss, const SSLSignatureScheme *signatureSchemes, unsigned int signatureSchemeCount, CERTDistNames *ca_list); +SECStatus ssl_ConstructServerHello(sslSocket *ss, PRBool helloRetry, + const sslBuffer *extensionBuf, + sslBuffer *messageBuf); SECStatus ssl3_SendServerHello(sslSocket *ss); +SECStatus ssl3_SendChangeCipherSpecsInt(sslSocket *ss); SECStatus ssl3_ComputeHandshakeHashes(sslSocket *ss, ssl3CipherSpec *spec, SSL3Hashes *hashes, @@ -1832,10 +1621,9 @@ PK11SymKey *ssl3_GetWrappingKey(sslSocket *ss, PK11SlotInfo *masterSecretSlot, CK_MECHANISM_TYPE masterWrapMech, void *pwArg); -SECStatus ssl3_FillInCachedSID(sslSocket *ss, sslSessionID *sid); +SECStatus ssl3_FillInCachedSID(sslSocket *ss, sslSessionID *sid, + PK11SymKey *secret); const ssl3CipherSuiteDef *ssl_LookupCipherSuiteDef(ssl3CipherSuite suite); -const ssl3BulkCipherDef * -ssl_GetBulkCipherDef(const ssl3CipherSuiteDef *cipher_def); SECStatus ssl3_SelectServerCert(sslSocket *ss); SECStatus ssl_PickSignatureScheme(sslSocket *ss, SECKEYPublicKey *pubKey, @@ -1847,11 +1635,14 @@ SECOidTag ssl3_HashTypeToOID(SSLHashType hashType); SSLHashType ssl_SignatureSchemeToHashType(SSLSignatureScheme scheme); KeyType ssl_SignatureSchemeToKeyType(SSLSignatureScheme scheme); -SECStatus ssl3_SetCipherSuite(sslSocket *ss, ssl3CipherSuite chosenSuite, - PRBool initHashes); +SECStatus ssl3_SetupCipherSuite(sslSocket *ss, PRBool initHashes); + +/* Pull in DTLS functions */ +#include "dtlscon.h" /* Pull in TLS 1.3 functions */ #include "tls13con.h" +#include "dtls13con.h" /********************** misc calls *********************/ @@ -1861,22 +1652,27 @@ extern void ssl3_CheckCipherSuiteOrderConsistency(); extern int ssl_MapLowLevelError(int hiLevelError); -extern PRUint32 ssl_Time(void); +extern PRUint32 ssl_TimeSec(void); +#ifdef UNSAFE_FUZZER_MODE +#define ssl_TimeUsec() ((PRTime)12345678) +#else +#define ssl_TimeUsec() (PR_Now()) +#endif extern PRBool ssl_TicketTimeValid(const NewSessionTicket *ticket); extern void SSL_AtomicIncrementLong(long *x); SECStatus ssl3_ApplyNSSPolicy(void); -extern HASH_HashType -ssl3_GetTls12HashType(sslSocket *ss); - extern SECStatus ssl3_TLSPRFWithMasterSecret(sslSocket *ss, ssl3CipherSpec *spec, const char *label, unsigned int labelLen, const unsigned char *val, unsigned int valLen, unsigned char *out, unsigned int outLen); +extern void +ssl3_RecordKeyLog(sslSocket *ss, const char *label, PK11SymKey *secret); + PRBool ssl_AlpnTagAllowed(const sslSocket *ss, const SECItem *tag); #ifdef TRACE @@ -1887,6 +1683,26 @@ PRBool ssl_AlpnTagAllowed(const sslSocket *ss, const SECItem *tag); void ssl_Trace(const char *format, ...); +void ssl_CacheExternalToken(sslSocket *ss); +SECStatus ssl_DecodeResumptionToken(sslSessionID *sid, const PRUint8 *encodedTicket, + PRUint32 encodedTicketLen); +PRBool ssl_IsResumptionTokenValid(sslSocket *ss); + +/* Remove when stable. */ + +SECStatus SSLExp_SetResumptionTokenCallback(PRFileDesc *fd, + SSLResumptionTokenCallback cb, + void *ctx); +SECStatus SSLExp_SetResumptionToken(PRFileDesc *fd, const PRUint8 *token, + unsigned int len); + +SECStatus SSLExp_GetResumptionTokenInfo(const PRUint8 *tokenData, unsigned int tokenLen, + SSLResumptionTokenInfo *token, unsigned int version); + +SECStatus SSLExp_DestroyResumptionTokenInfo(SSLResumptionTokenInfo *token); + +#define SSLResumptionTokenVersion 2 + SEC_END_PROTOS #if defined(XP_UNIX) || defined(XP_OS2) || defined(XP_BEOS) diff --git a/security/nss/lib/ssl/sslinfo.c b/security/nss/lib/ssl/sslinfo.c index 88162d814..4e58c5ae7 100644 --- a/security/nss/lib/ssl/sslinfo.c +++ b/security/nss/lib/ssl/sslinfo.c @@ -2,26 +2,12 @@ /* 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 "pk11pub.h" #include "ssl.h" #include "sslimpl.h" #include "sslproto.h" #include "tls13hkdf.h" -static const char * -ssl_GetCompressionMethodName(SSLCompressionMethod compression) -{ - switch (compression) { - case ssl_compression_null: - return "NULL"; -#ifdef NSS_ENABLE_ZLIB - case ssl_compression_deflate: - return "DEFLATE"; -#endif - default: - return "???"; - } -} - SECStatus SSL_GetChannelInfo(PRFileDesc *fd, SSLChannelInfo *info, PRUintn len) { @@ -48,48 +34,58 @@ SSL_GetChannelInfo(PRFileDesc *fd, SSLChannelInfo *info, PRUintn len) inf.length = PR_MIN(sizeof inf, len); if (ss->opt.useSecurity && ss->enoughFirstHsDone) { + SSLCipherSuiteInfo cinfo; + SECStatus rv; + sid = ss->sec.ci.sid; inf.protocolVersion = ss->version; inf.authKeyBits = ss->sec.authKeyBits; inf.keaKeyBits = ss->sec.keaKeyBits; - if (ss->ssl3.initialized) { - SSLCipherSuiteInfo cinfo; - SECStatus rv; - - ssl_GetSpecReadLock(ss); - /* XXX The cipher suite should be in the specs and this - * function should get it from cwSpec rather than from the "hs". - * See bug 275744 comment 69 and bug 766137. - */ - inf.cipherSuite = ss->ssl3.hs.cipher_suite; - inf.compressionMethod = ss->ssl3.cwSpec->compression_method; - ssl_ReleaseSpecReadLock(ss); - inf.compressionMethodName = - ssl_GetCompressionMethodName(inf.compressionMethod); - - /* Fill in the cipher details from the cipher suite. */ - rv = SSL_GetCipherSuiteInfo(inf.cipherSuite, - &cinfo, sizeof(cinfo)); - if (rv != SECSuccess) { - return SECFailure; /* Error code already set. */ - } - inf.symCipher = cinfo.symCipher; - inf.macAlgorithm = cinfo.macAlgorithm; - /* Get these fromm |ss->sec| because that is accurate - * even with TLS 1.3 disaggregated cipher suites. */ - inf.keaType = ss->sec.keaType; - inf.keaGroup = ss->sec.keaGroup ? ss->sec.keaGroup->name : ssl_grp_none; - inf.keaKeyBits = ss->sec.keaKeyBits; - inf.authType = ss->sec.authType; - inf.authKeyBits = ss->sec.authKeyBits; - inf.signatureScheme = ss->sec.signatureScheme; + + ssl_GetSpecReadLock(ss); + /* XXX The cipher suite should be in the specs and this + * function should get it from cwSpec rather than from the "hs". + * See bug 275744 comment 69 and bug 766137. + */ + inf.cipherSuite = ss->ssl3.hs.cipher_suite; + ssl_ReleaseSpecReadLock(ss); + inf.compressionMethod = ssl_compression_null; + inf.compressionMethodName = "NULL"; + + /* Fill in the cipher details from the cipher suite. */ + rv = SSL_GetCipherSuiteInfo(inf.cipherSuite, + &cinfo, sizeof(cinfo)); + if (rv != SECSuccess) { + return SECFailure; /* Error code already set. */ + } + inf.symCipher = cinfo.symCipher; + inf.macAlgorithm = cinfo.macAlgorithm; + /* Get these fromm |ss->sec| because that is accurate + * even with TLS 1.3 disaggregated cipher suites. */ + inf.keaType = ss->sec.keaType; + inf.originalKeaGroup = ss->sec.originalKeaGroup + ? ss->sec.originalKeaGroup->name + : ssl_grp_none; + inf.keaGroup = ss->sec.keaGroup + ? ss->sec.keaGroup->name + : ssl_grp_none; + inf.keaKeyBits = ss->sec.keaKeyBits; + inf.authType = ss->sec.authType; + inf.authKeyBits = ss->sec.authKeyBits; + inf.signatureScheme = ss->sec.signatureScheme; + /* If this is a resumed session, signatureScheme isn't set in ss->sec. + * Use the signature scheme from the previous handshake. */ + if (inf.signatureScheme == ssl_sig_none && sid->sigScheme) { + inf.signatureScheme = sid->sigScheme; } + inf.resumed = ss->statelessResume || ss->ssl3.hs.isResuming; + if (sid) { unsigned int sidLen; - inf.creationTime = sid->creationTime; - inf.lastAccessTime = sid->lastAccessTime; - inf.expirationTime = sid->expirationTime; + inf.creationTime = sid->creationTime / PR_USEC_PER_SEC; + inf.lastAccessTime = sid->lastAccessTime / PR_USEC_PER_SEC; + inf.expirationTime = sid->expirationTime / PR_USEC_PER_SEC; inf.extendedMasterSecretUsed = (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3 || sid->u.ssl3.keys.extendedMasterSecretUsed) @@ -196,17 +192,17 @@ SSL_GetPreliminaryChannelInfo(PRFileDesc *fd, #define K_ANY "TLS 1.3", ssl_kea_tls13_any /* record protection cipher */ -#define C_SEED "SEED", calg_seed -#define C_CAMELLIA "CAMELLIA", calg_camellia -#define C_AES "AES", calg_aes -#define C_RC4 "RC4", calg_rc4 -#define C_RC2 "RC2", calg_rc2 -#define C_DES "DES", calg_des -#define C_3DES "3DES", calg_3des -#define C_NULL "NULL", calg_null -#define C_SJ "SKIPJACK", calg_sj -#define C_AESGCM "AES-GCM", calg_aes_gcm -#define C_CHACHA20 "CHACHA20POLY1305", calg_chacha20 +#define C_SEED "SEED", ssl_calg_seed +#define C_CAMELLIA "CAMELLIA", ssl_calg_camellia +#define C_AES "AES", ssl_calg_aes +#define C_RC4 "RC4", ssl_calg_rc4 +#define C_RC2 "RC2", ssl_calg_rc2 +#define C_DES "DES", ssl_calg_des +#define C_3DES "3DES", ssl_calg_3des +#define C_NULL "NULL", ssl_calg_null +#define C_SJ "SKIPJACK", ssl_calg_sj +#define C_AESGCM "AES-GCM", ssl_calg_aes_gcm +#define C_CHACHA20 "CHACHA20POLY1305", ssl_calg_chacha20 /* "block cipher" sizes */ #define B_256 256, 256, 256 @@ -367,8 +363,7 @@ SSL_GetNegotiatedHostInfo(PRFileDesc *fd) } if (ss->sec.isServer) { - if (ss->version > SSL_LIBRARY_VERSION_3_0 && - ss->ssl3.initialized) { /* TLS */ + if (ss->version > SSL_LIBRARY_VERSION_3_0) { /* TLS */ SECItem *crsName; ssl_GetSpecReadLock(ss); /*********************************/ crsName = &ss->ssl3.hs.srvVirtName; @@ -392,22 +387,47 @@ SSL_GetNegotiatedHostInfo(PRFileDesc *fd) return sniName; } +/* + * HKDF-Expand-Label(Derive-Secret(Secret, label, ""), + * "exporter", Hash(context_value), key_length) + */ static SECStatus tls13_Exporter(sslSocket *ss, PK11SymKey *secret, const char *label, unsigned int labelLen, const unsigned char *context, unsigned int contextLen, unsigned char *out, unsigned int outLen) { + SSL3Hashes contextHash; + PK11SymKey *innerSecret = NULL; + SECStatus rv; + + static const char *kExporterInnerLabel = "exporter"; + if (!secret) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } - return tls13_HkdfExpandLabelRaw(secret, - tls13_GetHash(ss), - context, contextLen, - label, labelLen, - out, outLen); + /* Pre-hash the context. */ + rv = tls13_ComputeHash(ss, &contextHash, context, contextLen); + if (rv != SECSuccess) { + return rv; + } + + rv = tls13_DeriveSecretNullHash(ss, secret, label, labelLen, + &innerSecret); + if (rv != SECSuccess) { + return rv; + } + + rv = tls13_HkdfExpandLabelRaw(innerSecret, + tls13_GetHash(ss), + contextHash.u.raw, contextHash.len, + kExporterInnerLabel, + strlen(kExporterInnerLabel), + out, outLen); + PK11_FreeSymKey(innerSecret); + return rv; } SECStatus @@ -457,9 +477,9 @@ SSL_ExportKeyingMaterial(PRFileDesc *fd, return SECFailure; } i = 0; - PORT_Memcpy(val + i, &ss->ssl3.hs.client_random.rand, SSL3_RANDOM_LENGTH); + PORT_Memcpy(val + i, ss->ssl3.hs.client_random, SSL3_RANDOM_LENGTH); i += SSL3_RANDOM_LENGTH; - PORT_Memcpy(val + i, &ss->ssl3.hs.server_random.rand, SSL3_RANDOM_LENGTH); + PORT_Memcpy(val + i, ss->ssl3.hs.server_random, SSL3_RANDOM_LENGTH); i += SSL3_RANDOM_LENGTH; if (hasContext) { val[i++] = contextLen >> 8; @@ -473,7 +493,7 @@ SSL_ExportKeyingMaterial(PRFileDesc *fd, * secret is available and we have sent ChangeCipherSpec. */ ssl_GetSpecReadLock(ss); - if (!ss->ssl3.cwSpec->master_secret && !ss->ssl3.cwSpec->msItem.len) { + if (!ss->ssl3.cwSpec->masterSecret) { PORT_SetError(SSL_ERROR_HANDSHAKE_NOT_COMPLETED); rv = SECFailure; } else { diff --git a/security/nss/lib/ssl/sslinit.c b/security/nss/lib/ssl/sslinit.c index 0f38c0b57..07d57ce6e 100644 --- a/security/nss/lib/ssl/sslinit.c +++ b/security/nss/lib/ssl/sslinit.c @@ -15,6 +15,7 @@ static int ssl_isInited = 0; static PRCallOnceType ssl_init = { 0 }; +PR_STATIC_ASSERT(sizeof(unsigned long) <= sizeof(PRUint64)); PRStatus ssl_InitCallOnce(void *arg) diff --git a/security/nss/lib/ssl/sslnonce.c b/security/nss/lib/ssl/sslnonce.c index 7ad1c6bc7..f79c23fc7 100644 --- a/security/nss/lib/ssl/sslnonce.c +++ b/security/nss/lib/ssl/sslnonce.c @@ -15,6 +15,7 @@ #include "sslimpl.h" #include "sslproto.h" #include "nssilock.h" +#include "sslencode.h" #if defined(XP_UNIX) || defined(XP_WIN) || defined(_WINDOWS) || defined(XP_BEOS) #include <time.h> #endif @@ -24,12 +25,13 @@ PRUint32 ssl3_sid_timeout = 86400L; /* 24 hours */ static sslSessionID *cache = NULL; static PZLock *cacheLock = NULL; -/* sids can be in one of 4 states: +/* sids can be in one of 5 states: * * never_cached, created, but not yet put into cache. * in_client_cache, in the client cache's linked list. * in_server_cache, entry came from the server's cache file. * invalid_cache has been removed from the cache. + * in_external_cache sid comes from an external cache. */ #define LOCK_CACHE lock_cache() @@ -164,8 +166,8 @@ lock_cache(void) /* BEWARE: This function gets called for both client and server SIDs !! * If the unreferenced sid is not in the cache, Free sid and its contents. */ -static void -ssl_DestroySID(sslSessionID *sid) +void +ssl_DestroySID(sslSessionID *sid, PRBool freeIt) { SSL_TRC(8, ("SSL: destroy sid: sid=0x%x cached=%d", sid, sid->cached)); PORT_Assert(sid->references == 0); @@ -186,11 +188,8 @@ ssl_DestroySID(sslSessionID *sid) PR_DestroyRWLock(sid->u.ssl3.lock); } - if (sid->peerID != NULL) - PORT_Free((void *)sid->peerID); /* CONST */ - - if (sid->urlSvrName != NULL) - PORT_Free((void *)sid->urlSvrName); /* CONST */ + PORT_Free((void *)sid->peerID); + PORT_Free((void *)sid->urlSvrName); if (sid->peerCert) { CERT_DestroyCertificate(sid->peerCert); @@ -205,7 +204,9 @@ ssl_DestroySID(sslSessionID *sid) SECITEM_FreeItem(&sid->u.ssl3.alpnSelection, PR_FALSE); - PORT_ZFree(sid, sizeof(sslSessionID)); + if (freeIt) { + PORT_ZFree(sid, sizeof(sslSessionID)); + } } /* BEWARE: This function gets called for both client and server SIDs !! @@ -220,7 +221,7 @@ ssl_FreeLockedSID(sslSessionID *sid) { PORT_Assert(sid->references >= 1); if (--sid->references == 0) { - ssl_DestroySID(sid); + ssl_DestroySID(sid, PR_TRUE); } } @@ -256,7 +257,7 @@ ssl_LookupSID(const PRIPv6Addr *addr, PRUint16 port, const char *peerID, if (!urlSvrName) return NULL; - now = ssl_Time(); + now = ssl_TimeSec(); LOCK_CACHE; sidp = &cache; while ((sid = *sidp) != 0) { @@ -306,8 +307,7 @@ ssl_LookupSID(const PRIPv6Addr *addr, PRUint16 port, const char *peerID, static void CacheSID(sslSessionID *sid) { - PRUint32 expirationPeriod; - + PORT_Assert(sid); PORT_Assert(sid->cached == never_cached); SSL_TRC(8, ("SSL: Cache: sid=0x%x cached=%d addr=0x%08x%08x%08x%08x port=0x%04x " @@ -335,7 +335,6 @@ CacheSID(sslSessionID *sid) return; sid->u.ssl3.sessionIDLength = SSL3_SESSIONID_BYTES; } - expirationPeriod = ssl3_sid_timeout; PRINT_BUF(8, (0, "sessionID:", sid->u.ssl3.sessionID, sid->u.ssl3.sessionIDLength)); @@ -345,9 +344,9 @@ CacheSID(sslSessionID *sid) } PORT_Assert(sid->creationTime != 0 && sid->expirationTime != 0); if (!sid->creationTime) - sid->lastAccessTime = sid->creationTime = ssl_Time(); + sid->lastAccessTime = sid->creationTime = ssl_TimeUsec(); if (!sid->expirationTime) - sid->expirationTime = sid->creationTime + expirationPeriod; + sid->expirationTime = sid->creationTime + ssl3_sid_timeout * PR_USEC_PER_SEC; /* * Put sid into the cache. Bump reference count to indicate that @@ -403,7 +402,7 @@ UncacheSID(sslSessionID *zap) /* If sid "zap" is in the cache, * removes sid from cache, and decrements reference count. * Although this function is static, it is called externally via - * ss->sec.uncache(). + * ssl_UncacheSessionID. */ static void LockAndUncacheSID(sslSessionID *zap) @@ -413,16 +412,734 @@ LockAndUncacheSID(sslSessionID *zap) UNLOCK_CACHE; } -/* choose client or server cache functions for this sslsocket. */ +SECStatus +ReadVariableFromBuffer(sslReader *reader, sslReadBuffer *readerBuffer, + uint8_t lenBytes, SECItem *dest) +{ + if (sslRead_ReadVariable(reader, lenBytes, readerBuffer) != SECSuccess) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + if (readerBuffer->len) { + SECItem tempItem = { siBuffer, (unsigned char *)readerBuffer->buf, + readerBuffer->len }; + SECStatus rv = SECITEM_CopyItem(NULL, dest, &tempItem); + if (rv != SECSuccess) { + return rv; + } + } + return SECSuccess; +} + +/* Fill sid with the values from the encoded resumption token. + * sid has to be allocated. + * We don't care about locks here as this cache entry is externally stored. + */ +SECStatus +ssl_DecodeResumptionToken(sslSessionID *sid, const PRUint8 *encodedToken, + PRUint32 encodedTokenLen) +{ + PORT_Assert(encodedTokenLen); + PORT_Assert(encodedToken); + PORT_Assert(sid); + if (!sid || !encodedToken || !encodedTokenLen) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + + if (encodedToken[0] != SSLResumptionTokenVersion) { + /* Unknown token format version. */ + PORT_SetError(SSL_ERROR_BAD_RESUMPTION_TOKEN_ERROR); + return SECFailure; + } + + /* These variables are used across macros. Don't use them outside. */ + sslReader reader = SSL_READER(encodedToken, encodedTokenLen); + reader.offset += 1; // We read the version already. Skip the first byte. + sslReadBuffer readerBuffer = { 0 }; + PRUint64 tmpInt = 0; + + if (sslRead_ReadNumber(&reader, 8, &tmpInt) != SECSuccess) { + return SECFailure; + } + sid->lastAccessTime = (PRTime)tmpInt; + if (sslRead_ReadNumber(&reader, 8, &tmpInt) != SECSuccess) { + return SECFailure; + } + sid->expirationTime = (PRTime)tmpInt; + if (sslRead_ReadNumber(&reader, 8, &tmpInt) != SECSuccess) { + return SECFailure; + } + sid->u.ssl3.locked.sessionTicket.received_timestamp = (PRTime)tmpInt; + + if (sslRead_ReadNumber(&reader, 4, &tmpInt) != SECSuccess) { + return SECFailure; + } + sid->u.ssl3.locked.sessionTicket.ticket_lifetime_hint = (PRUint32)tmpInt; + if (sslRead_ReadNumber(&reader, 4, &tmpInt) != SECSuccess) { + return SECFailure; + } + sid->u.ssl3.locked.sessionTicket.flags = (PRUint32)tmpInt; + if (sslRead_ReadNumber(&reader, 4, &tmpInt) != SECSuccess) { + return SECFailure; + } + sid->u.ssl3.locked.sessionTicket.ticket_age_add = (PRUint32)tmpInt; + if (sslRead_ReadNumber(&reader, 4, &tmpInt) != SECSuccess) { + return SECFailure; + } + sid->u.ssl3.locked.sessionTicket.max_early_data_size = (PRUint32)tmpInt; + + if (sslRead_ReadVariable(&reader, 3, &readerBuffer) != SECSuccess) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + if (readerBuffer.len) { + PORT_Assert(!sid->peerCert); + SECItem tempItem = { siBuffer, (unsigned char *)readerBuffer.buf, + readerBuffer.len }; + sid->peerCert = CERT_NewTempCertificate(NULL, /* dbHandle */ + &tempItem, + NULL, PR_FALSE, PR_TRUE); + if (!sid->peerCert) { + return SECFailure; + } + } + + if (sslRead_ReadVariable(&reader, 2, &readerBuffer) != SECSuccess) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + if (readerBuffer.len) { + SECITEM_AllocArray(NULL, &sid->peerCertStatus, 1); + if (!sid->peerCertStatus.items) { + return SECFailure; + } + SECItem tempItem = { siBuffer, (unsigned char *)readerBuffer.buf, + readerBuffer.len }; + SECITEM_CopyItem(NULL, &sid->peerCertStatus.items[0], &tempItem); + } + + if (sslRead_ReadVariable(&reader, 1, &readerBuffer) != SECSuccess) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + if (readerBuffer.len) { + PORT_Assert(readerBuffer.buf); + sid->peerID = PORT_Strdup((const char *)readerBuffer.buf); + } + + if (sslRead_ReadVariable(&reader, 1, &readerBuffer) != SECSuccess) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + if (readerBuffer.len) { + if (sid->urlSvrName) { + PORT_Free((void *)sid->urlSvrName); + } + PORT_Assert(readerBuffer.buf); + sid->urlSvrName = PORT_Strdup((const char *)readerBuffer.buf); + } + + if (sslRead_ReadVariable(&reader, 3, &readerBuffer) != SECSuccess) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + if (readerBuffer.len) { + PORT_Assert(!sid->localCert); + SECItem tempItem = { siBuffer, (unsigned char *)readerBuffer.buf, + readerBuffer.len }; + sid->localCert = CERT_NewTempCertificate(NULL, /* dbHandle */ + &tempItem, + NULL, PR_FALSE, PR_TRUE); + } + + if (sslRead_ReadNumber(&reader, 8, &sid->addr.pr_s6_addr64[0]) != SECSuccess) { + return SECFailure; + } + if (sslRead_ReadNumber(&reader, 8, &sid->addr.pr_s6_addr64[1]) != SECSuccess) { + return SECFailure; + } + + if (sslRead_ReadNumber(&reader, 2, &tmpInt) != SECSuccess) { + return SECFailure; + } + sid->port = (PRUint16)tmpInt; + if (sslRead_ReadNumber(&reader, 2, &tmpInt) != SECSuccess) { + return SECFailure; + } + sid->version = (PRUint16)tmpInt; + + if (sslRead_ReadNumber(&reader, 8, &tmpInt) != SECSuccess) { + return SECFailure; + } + sid->creationTime = (PRTime)tmpInt; + + if (sslRead_ReadNumber(&reader, 2, &tmpInt) != SECSuccess) { + return SECFailure; + } + sid->authType = (SSLAuthType)tmpInt; + if (sslRead_ReadNumber(&reader, 4, &tmpInt) != SECSuccess) { + return SECFailure; + } + sid->authKeyBits = (PRUint32)tmpInt; + if (sslRead_ReadNumber(&reader, 2, &tmpInt) != SECSuccess) { + return SECFailure; + } + sid->keaType = (SSLKEAType)tmpInt; + if (sslRead_ReadNumber(&reader, 4, &tmpInt) != SECSuccess) { + return SECFailure; + } + sid->keaKeyBits = (PRUint32)tmpInt; + if (sslRead_ReadNumber(&reader, 3, &tmpInt) != SECSuccess) { + return SECFailure; + } + sid->keaGroup = (SSLNamedGroup)tmpInt; + + if (sslRead_ReadNumber(&reader, 3, &tmpInt) != SECSuccess) { + return SECFailure; + } + sid->sigScheme = (SSLSignatureScheme)tmpInt; + + if (sslRead_ReadNumber(&reader, 1, &tmpInt) != SECSuccess) { + return SECFailure; + } + sid->u.ssl3.sessionIDLength = (PRUint8)tmpInt; + + if (sslRead_ReadVariable(&reader, 1, &readerBuffer) != SECSuccess) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + if (readerBuffer.len) { + PORT_Assert(readerBuffer.buf); + PORT_Memcpy(sid->u.ssl3.sessionID, readerBuffer.buf, readerBuffer.len); + } + + if (sslRead_ReadNumber(&reader, 2, &tmpInt) != SECSuccess) { + return SECFailure; + } + sid->u.ssl3.cipherSuite = (PRUint16)tmpInt; + if (sslRead_ReadNumber(&reader, 1, &tmpInt) != SECSuccess) { + return SECFailure; + } + sid->u.ssl3.policy = (PRUint8)tmpInt; + + if (sslRead_ReadVariable(&reader, 1, &readerBuffer) != SECSuccess) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + PORT_Assert(readerBuffer.len == WRAPPED_MASTER_SECRET_SIZE); + if (readerBuffer.len != WRAPPED_MASTER_SECRET_SIZE) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + PORT_Assert(readerBuffer.buf); + PORT_Memcpy(sid->u.ssl3.keys.wrapped_master_secret, readerBuffer.buf, + readerBuffer.len); + + if (sslRead_ReadNumber(&reader, 1, &tmpInt) != SECSuccess) { + return SECFailure; + } + sid->u.ssl3.keys.wrapped_master_secret_len = (PRUint8)tmpInt; + if (sslRead_ReadNumber(&reader, 1, &tmpInt) != SECSuccess) { + return SECFailure; + } + sid->u.ssl3.keys.extendedMasterSecretUsed = (PRUint8)tmpInt; + + if (sslRead_ReadNumber(&reader, 8, &tmpInt) != SECSuccess) { + return SECFailure; + } + sid->u.ssl3.masterWrapMech = (unsigned long)tmpInt; + if (sslRead_ReadNumber(&reader, 8, &tmpInt) != SECSuccess) { + return SECFailure; + } + sid->u.ssl3.masterModuleID = (unsigned long)tmpInt; + if (sslRead_ReadNumber(&reader, 8, &tmpInt) != SECSuccess) { + return SECFailure; + } + sid->u.ssl3.masterSlotID = (unsigned long)tmpInt; + + if (sslRead_ReadNumber(&reader, 4, &tmpInt) != SECSuccess) { + return SECFailure; + } + sid->u.ssl3.masterWrapIndex = (PRUint32)tmpInt; + if (sslRead_ReadNumber(&reader, 2, &tmpInt) != SECSuccess) { + return SECFailure; + } + sid->u.ssl3.masterWrapSeries = (PRUint16)tmpInt; + + if (sslRead_ReadNumber(&reader, 1, &tmpInt) != SECSuccess) { + return SECFailure; + } + sid->u.ssl3.masterValid = (char)tmpInt; + + if (ReadVariableFromBuffer(&reader, &readerBuffer, 1, + &sid->u.ssl3.srvName) != SECSuccess) { + return SECFailure; + } + if (ReadVariableFromBuffer(&reader, &readerBuffer, 2, + &sid->u.ssl3.signedCertTimestamps) != SECSuccess) { + return SECFailure; + } + if (ReadVariableFromBuffer(&reader, &readerBuffer, 1, + &sid->u.ssl3.alpnSelection) != SECSuccess) { + return SECFailure; + } + if (ReadVariableFromBuffer(&reader, &readerBuffer, 2, + &sid->u.ssl3.locked.sessionTicket.ticket) != SECSuccess) { + return SECFailure; + } + if (!sid->u.ssl3.locked.sessionTicket.ticket.len) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + + /* At this point we must have read everything. */ + PORT_Assert(reader.offset == reader.buf.len); + if (reader.offset != reader.buf.len) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + + return SECSuccess; +} + +PRBool +ssl_IsResumptionTokenValid(sslSocket *ss) +{ + PORT_Assert(ss); + sslSessionID *sid = ss->sec.ci.sid; + PORT_Assert(sid); + + // Check that the ticket didn't expire. + PRTime endTime = 0; + NewSessionTicket *ticket = &sid->u.ssl3.locked.sessionTicket; + if (ticket->ticket_lifetime_hint != 0) { + endTime = ticket->received_timestamp + + (PRTime)(ticket->ticket_lifetime_hint * PR_USEC_PER_SEC); + if (endTime < ssl_TimeUsec()) { + return PR_FALSE; + } + } + + // Check that the session entry didn't expire. + if (sid->expirationTime < ssl_TimeUsec()) { + return PR_FALSE; + } + + // Check that the server name (SNI) matches the one set for this session. + // Don't use the token if there's no server name. + if (sid->urlSvrName == NULL || PORT_Strcmp(ss->url, sid->urlSvrName) != 0) { + return PR_FALSE; + } + + // This shouldn't be false, but let's check it anyway. + if (!sid->u.ssl3.keys.resumable) { + return PR_FALSE; + } + + return PR_TRUE; +} + +/* Encode a session ticket into a byte array that can be handed out to a cache. + * Needed memory in encodedToken has to be allocated according to + * *encodedTokenLen. */ +static SECStatus +ssl_EncodeResumptionToken(sslSessionID *sid, sslBuffer *encodedTokenBuf) +{ + PORT_Assert(encodedTokenBuf); + PORT_Assert(sid); + if (!sid || !sid->u.ssl3.locked.sessionTicket.ticket.len || + !encodedTokenBuf || !sid->u.ssl3.keys.resumable || !sid->urlSvrName) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + + /* Encoding format: + * 0-byte: version + * Integers are encoded according to their length. + * SECItems are prepended with a 64-bit length field followed by the bytes. + * Optional bytes are encoded as a 0-length item if not present. + */ + SECStatus rv = sslBuffer_AppendNumber(encodedTokenBuf, + SSLResumptionTokenVersion, 1); + if (rv != SECSuccess) { + return SECFailure; + } + + rv = sslBuffer_AppendNumber(encodedTokenBuf, sid->lastAccessTime, 8); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + rv = sslBuffer_AppendNumber(encodedTokenBuf, sid->expirationTime, 8); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + + // session ticket + rv = sslBuffer_AppendNumber(encodedTokenBuf, + sid->u.ssl3.locked.sessionTicket.received_timestamp, + 8); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + rv = sslBuffer_AppendNumber(encodedTokenBuf, + sid->u.ssl3.locked.sessionTicket.ticket_lifetime_hint, + 4); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + rv = sslBuffer_AppendNumber(encodedTokenBuf, + sid->u.ssl3.locked.sessionTicket.flags, + 4); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + rv = sslBuffer_AppendNumber(encodedTokenBuf, + sid->u.ssl3.locked.sessionTicket.ticket_age_add, + 4); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + rv = sslBuffer_AppendNumber(encodedTokenBuf, + sid->u.ssl3.locked.sessionTicket.max_early_data_size, + 4); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + + rv = sslBuffer_AppendVariable(encodedTokenBuf, sid->peerCert->derCert.data, + sid->peerCert->derCert.len, 3); + if (rv != SECSuccess) { + return SECFailure; + } + + if (sid->peerCertStatus.len > 1) { + /* This is not implemented so it shouldn't happen. + * If it gets implemented, this has to change. + */ + PORT_Assert(0); + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + + if (sid->peerCertStatus.len == 1 && sid->peerCertStatus.items[0].len) { + rv = sslBuffer_AppendVariable(encodedTokenBuf, + sid->peerCertStatus.items[0].data, + sid->peerCertStatus.items[0].len, 2); + if (rv != SECSuccess) { + return SECFailure; + } + } else { + rv = sslBuffer_AppendVariable(encodedTokenBuf, NULL, 0, 2); + if (rv != SECSuccess) { + return SECFailure; + } + } + + PRUint64 len = sid->peerID ? strlen(sid->peerID) : 0; + if (len > PR_UINT8_MAX) { + // This string really shouldn't be that long. + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + rv = sslBuffer_AppendVariable(encodedTokenBuf, + (const unsigned char *)sid->peerID, len, 1); + if (rv != SECSuccess) { + return SECFailure; + } + + len = sid->urlSvrName ? strlen(sid->urlSvrName) : 0; + if (!len) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + if (len > PR_UINT8_MAX) { + // This string really shouldn't be that long. + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + rv = sslBuffer_AppendVariable(encodedTokenBuf, + (const unsigned char *)sid->urlSvrName, + len, 1); + if (rv != SECSuccess) { + return SECFailure; + } + + if (sid->localCert) { + rv = sslBuffer_AppendVariable(encodedTokenBuf, + sid->localCert->derCert.data, + sid->localCert->derCert.len, 3); + if (rv != SECSuccess) { + return SECFailure; + } + } else { + rv = sslBuffer_AppendVariable(encodedTokenBuf, NULL, 0, 3); + if (rv != SECSuccess) { + return SECFailure; + } + } + + rv = sslBuffer_AppendNumber(encodedTokenBuf, sid->addr.pr_s6_addr64[0], 8); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + rv = sslBuffer_AppendNumber(encodedTokenBuf, sid->addr.pr_s6_addr64[1], 8); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + rv = sslBuffer_AppendNumber(encodedTokenBuf, sid->port, 2); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + rv = sslBuffer_AppendNumber(encodedTokenBuf, sid->version, 2); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + rv = sslBuffer_AppendNumber(encodedTokenBuf, sid->creationTime, 8); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + rv = sslBuffer_AppendNumber(encodedTokenBuf, sid->authType, 2); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + rv = sslBuffer_AppendNumber(encodedTokenBuf, sid->authKeyBits, 4); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + rv = sslBuffer_AppendNumber(encodedTokenBuf, sid->keaType, 2); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + rv = sslBuffer_AppendNumber(encodedTokenBuf, sid->keaKeyBits, 4); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + rv = sslBuffer_AppendNumber(encodedTokenBuf, sid->keaGroup, 3); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + rv = sslBuffer_AppendNumber(encodedTokenBuf, sid->sigScheme, 3); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + + rv = sslBuffer_AppendNumber(encodedTokenBuf, sid->u.ssl3.sessionIDLength, 1); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + rv = sslBuffer_AppendVariable(encodedTokenBuf, sid->u.ssl3.sessionID, + SSL3_SESSIONID_BYTES, 1); + if (rv != SECSuccess) { + return SECFailure; + } + + rv = sslBuffer_AppendNumber(encodedTokenBuf, sid->u.ssl3.cipherSuite, 2); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + rv = sslBuffer_AppendNumber(encodedTokenBuf, sid->u.ssl3.policy, 1); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + + rv = sslBuffer_AppendVariable(encodedTokenBuf, + sid->u.ssl3.keys.wrapped_master_secret, + WRAPPED_MASTER_SECRET_SIZE, 1); + if (rv != SECSuccess) { + return SECFailure; + } + + rv = sslBuffer_AppendNumber(encodedTokenBuf, + sid->u.ssl3.keys.wrapped_master_secret_len, + 1); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + rv = sslBuffer_AppendNumber(encodedTokenBuf, + sid->u.ssl3.keys.extendedMasterSecretUsed, + 1); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + + rv = sslBuffer_AppendNumber(encodedTokenBuf, sid->u.ssl3.masterWrapMech, 8); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + rv = sslBuffer_AppendNumber(encodedTokenBuf, sid->u.ssl3.masterModuleID, 8); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + rv = sslBuffer_AppendNumber(encodedTokenBuf, sid->u.ssl3.masterSlotID, 8); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + rv = sslBuffer_AppendNumber(encodedTokenBuf, sid->u.ssl3.masterWrapIndex, 4); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + rv = sslBuffer_AppendNumber(encodedTokenBuf, sid->u.ssl3.masterWrapSeries, 2); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + + rv = sslBuffer_AppendNumber(encodedTokenBuf, sid->u.ssl3.masterValid, 1); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + + rv = sslBuffer_AppendVariable(encodedTokenBuf, sid->u.ssl3.srvName.data, + sid->u.ssl3.srvName.len, 1); + if (rv != SECSuccess) { + return SECFailure; + } + rv = sslBuffer_AppendVariable(encodedTokenBuf, + sid->u.ssl3.signedCertTimestamps.data, + sid->u.ssl3.signedCertTimestamps.len, 2); + if (rv != SECSuccess) { + return SECFailure; + } + + rv = sslBuffer_AppendVariable(encodedTokenBuf, + sid->u.ssl3.alpnSelection.data, + sid->u.ssl3.alpnSelection.len, 1); + if (rv != SECSuccess) { + return SECFailure; + } + + PORT_Assert(sid->u.ssl3.locked.sessionTicket.ticket.len > 1); + rv = sslBuffer_AppendVariable(encodedTokenBuf, + sid->u.ssl3.locked.sessionTicket.ticket.data, + sid->u.ssl3.locked.sessionTicket.ticket.len, + 2); + if (rv != SECSuccess) { + return SECFailure; + } + + return SECSuccess; +} + void -ssl_ChooseSessionIDProcs(sslSecurityInfo *sec) +ssl_CacheExternalToken(sslSocket *ss) { + PORT_Assert(ss); + sslSessionID *sid = ss->sec.ci.sid; + PORT_Assert(sid); + PORT_Assert(sid->cached == never_cached); + PORT_Assert(ss->resumptionTokenCallback); + + SSL_TRC(8, ("SSL [%d]: Cache External: sid=0x%x cached=%d " + "addr=0x%08x%08x%08x%08x port=0x%04x time=%x cached=%d", + ss->fd, + sid, sid->cached, sid->addr.pr_s6_addr32[0], + sid->addr.pr_s6_addr32[1], sid->addr.pr_s6_addr32[2], + sid->addr.pr_s6_addr32[3], sid->port, sid->creationTime, + sid->cached)); + + /* This is only available for stateless resumption. */ + if (sid->u.ssl3.locked.sessionTicket.ticket.data == NULL) { + return; + } + + /* Don't export token if the session used client authentication. */ + if (sid->u.ssl3.clAuthValid) { + return; + } + + if (!sid->creationTime) { + sid->lastAccessTime = sid->creationTime = ssl_TimeUsec(); + } + if (!sid->expirationTime) { + sid->expirationTime = sid->creationTime + ssl3_sid_timeout; + } + + sslBuffer encodedToken = SSL_BUFFER_EMPTY; + + if (ssl_EncodeResumptionToken(sid, &encodedToken) != SECSuccess) { + SSL_TRC(3, ("SSL [%d]: encoding resumption token failed", ss->fd)); + return; + } + PORT_Assert(SSL_BUFFER_LEN(&encodedToken) > 0); + PRINT_BUF(40, (ss, "SSL: encoded resumption token", + SSL_BUFFER_BASE(&encodedToken), + SSL_BUFFER_LEN(&encodedToken))); + ss->resumptionTokenCallback(ss->fd, SSL_BUFFER_BASE(&encodedToken), + SSL_BUFFER_LEN(&encodedToken), + ss->resumptionTokenContext); + + sslBuffer_Clear(&encodedToken); +} + +void +ssl_CacheSessionID(sslSocket *ss) +{ + sslSecurityInfo *sec = &ss->sec; + PORT_Assert(sec); + + if (sec->ci.sid && !sec->ci.sid->u.ssl3.keys.resumable) { + return; + } + + if (!ss->sec.isServer && ss->resumptionTokenCallback) { + ssl_CacheExternalToken(ss); + return; + } + + PORT_Assert(!ss->resumptionTokenCallback); if (sec->isServer) { - sec->cache = ssl_sid_cache; - sec->uncache = ssl_sid_uncache; - } else { - sec->cache = CacheSID; - sec->uncache = LockAndUncacheSID; + ssl_ServerCacheSessionID(sec->ci.sid); + return; + } + + CacheSID(sec->ci.sid); +} + +void +ssl_UncacheSessionID(sslSocket *ss) +{ + if (ss->opt.noCache) { + return; + } + + sslSecurityInfo *sec = &ss->sec; + PORT_Assert(sec); + + if (sec->ci.sid) { + if (sec->isServer) { + ssl_ServerUncacheSessionID(sec->ci.sid); + } else if (!ss->resumptionTokenCallback) { + LockAndUncacheSID(sec->ci.sid); + } } } @@ -438,7 +1155,7 @@ SSL_ClearSessionCache(void) /* returns an unsigned int containing the number of seconds in PR_Now() */ PRUint32 -ssl_Time(void) +ssl_TimeSec(void) { #ifdef UNSAFE_FUZZER_MODE return 1234; @@ -471,7 +1188,7 @@ ssl_TicketTimeValid(const NewSessionTicket *ticket) endTime = ticket->received_timestamp + (PRTime)(ticket->ticket_lifetime_hint * PR_USEC_PER_SEC); - return endTime > PR_Now(); + return endTime > ssl_TimeUsec(); } void diff --git a/security/nss/lib/ssl/sslreveal.c b/security/nss/lib/ssl/sslreveal.c index 4c124a1dc..cc16f574d 100644 --- a/security/nss/lib/ssl/sslreveal.c +++ b/security/nss/lib/ssl/sslreveal.c @@ -92,18 +92,16 @@ SSL_HandshakeNegotiatedExtension(PRFileDesc *socket, /* according to public API SSL_GetChannelInfo, this doesn't need a lock */ if (sslsocket->opt.useSecurity) { - if (sslsocket->ssl3.initialized) { /* SSL3 and TLS */ - /* now we know this socket went through ssl3_InitState() and - * ss->xtnData got initialized, which is the only member accessed by - * ssl3_ExtensionNegotiated(); - * Member xtnData appears to get accessed in functions that handle - * the handshake (hello messages and extension sending), - * therefore the handshake lock should be sufficient. - */ - ssl_GetSSL3HandshakeLock(sslsocket); - *pYes = ssl3_ExtensionNegotiated(sslsocket, extId); - ssl_ReleaseSSL3HandshakeLock(sslsocket); - } + /* now we know this socket went through ssl3_InitState() and + * ss->xtnData got initialized, which is the only member accessed by + * ssl3_ExtensionNegotiated(); + * Member xtnData appears to get accessed in functions that handle + * the handshake (hello messages and extension sending), + * therefore the handshake lock should be sufficient. + */ + ssl_GetSSL3HandshakeLock(sslsocket); + *pYes = ssl3_ExtensionNegotiated(sslsocket, extId); + ssl_ReleaseSSL3HandshakeLock(sslsocket); } return SECSuccess; diff --git a/security/nss/lib/ssl/sslsecur.c b/security/nss/lib/ssl/sslsecur.c index 8bec3d327..f09ec067c 100644 --- a/security/nss/lib/ssl/sslsecur.c +++ b/security/nss/lib/ssl/sslsecur.c @@ -1,3 +1,4 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * Various SSL functions. * @@ -200,7 +201,7 @@ SSL_ResetHandshake(PRFileDesc *s, PRBool asServer) ssl_Release1stHandshakeLock(ss); ssl3_DestroyRemoteExtensions(&ss->ssl3.hs.remoteExtensions); - ssl3_ResetExtensionData(&ss->xtnData); + ssl3_ResetExtensionData(&ss->xtnData, ss); if (!ss->TCPconnected) ss->TCPconnected = (PR_SUCCESS == ssl_DefGetpeername(ss, &addr)); @@ -342,11 +343,6 @@ SSL_RecommendedCanFalseStart(PRFileDesc *fd, PRBool *canFalseStart) return SECFailure; } - if (!ss->ssl3.initialized) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - /* Require a forward-secret key exchange. */ *canFalseStart = ss->ssl3.hs.kea_def->kea == kea_dhe_dss || ss->ssl3.hs.kea_def->kea == kea_dhe_rsa || @@ -435,58 +431,6 @@ SSL_ForceHandshakeWithTimeout(PRFileDesc *fd, /************************************************************************/ /* -** Grow a buffer to hold newLen bytes of data. -** Called for both recv buffers and xmit buffers. -** Caller must hold xmitBufLock or recvBufLock, as appropriate. -*/ -SECStatus -sslBuffer_Grow(sslBuffer *b, unsigned int newLen) -{ - newLen = PR_MAX(newLen, MAX_FRAGMENT_LENGTH + 2048); - if (newLen > b->space) { - unsigned char *newBuf; - if (b->buf) { - newBuf = (unsigned char *)PORT_Realloc(b->buf, newLen); - } else { - newBuf = (unsigned char *)PORT_Alloc(newLen); - } - if (!newBuf) { - return SECFailure; - } - SSL_TRC(10, ("%d: SSL: grow buffer from %d to %d", - SSL_GETPID(), b->space, newLen)); - b->buf = newBuf; - b->space = newLen; - } - return SECSuccess; -} - -SECStatus -sslBuffer_Append(sslBuffer *b, const void *data, unsigned int len) -{ - unsigned int newLen = b->len + len; - SECStatus rv; - - rv = sslBuffer_Grow(b, newLen); - if (rv != SECSuccess) - return rv; - PORT_Memcpy(b->buf + b->len, data, len); - b->len += len; - return SECSuccess; -} - -void -sslBuffer_Clear(sslBuffer *b) -{ - if (b->buf) { - PORT_Free(b->buf); - b->buf = NULL; - b->len = 0; - b->space = 0; - } -} - -/* ** Save away write data that is trying to be written before the security ** handshake has been completed. When the handshake is completed, we will ** flush this data out. @@ -655,9 +599,6 @@ ssl_CopySecurityInfo(sslSocket *ss, sslSocket *os) if (os->sec.peerCert && !ss->sec.peerCert) goto loser; - ss->sec.cache = os->sec.cache; - ss->sec.uncache = os->sec.uncache; - return SECSuccess; loser: @@ -774,8 +715,7 @@ ssl_SecureClose(sslSocket *ss) if (!(ss->shutdownHow & ssl_SHUTDOWN_SEND) && ss->firstHsDone && - !ss->recvdCloseNotify && - ss->ssl3.initialized) { + !ss->recvdCloseNotify) { /* We don't want the final alert to be Nagle delayed. */ if (!ss->delayDisabled) { @@ -805,8 +745,7 @@ ssl_SecureShutdown(sslSocket *ss, int nsprHow) if ((sslHow & ssl_SHUTDOWN_SEND) != 0 && !(ss->shutdownHow & ssl_SHUTDOWN_SEND) && ss->firstHsDone && - !ss->recvdCloseNotify && - ss->ssl3.initialized) { + !ss->recvdCloseNotify) { (void)SSL3_SendAlert(ss, alert_warning, close_notify); } @@ -820,6 +759,55 @@ ssl_SecureShutdown(sslSocket *ss, int nsprHow) /************************************************************************/ +static SECStatus +tls13_CheckKeyUpdate(sslSocket *ss, CipherSpecDirection dir) +{ + PRBool keyUpdate; + ssl3CipherSpec *spec; + sslSequenceNumber seqNum; + sslSequenceNumber margin; + SECStatus rv; + + /* Bug 1413368: enable for DTLS */ + if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3 || IS_DTLS(ss)) { + return SECSuccess; + } + + /* If both sides update at the same number, then this will cause two updates + * to happen at once. The problem is that the KeyUpdate itself consumes a + * sequence number, and that will trigger the reading side to request an + * update. + * + * If we have the writing side update first, the writer will be the one that + * drives the update. An update by the writer doesn't need a response, so + * it is more efficient overall. The margins here are pretty arbitrary, but + * having the write margin larger reduces the number of times that a + * KeyUpdate is sent by a reader. */ + ssl_GetSpecReadLock(ss); + if (dir == CipherSpecRead) { + spec = ss->ssl3.crSpec; + margin = spec->cipherDef->max_records / 8; + } else { + spec = ss->ssl3.cwSpec; + margin = spec->cipherDef->max_records / 4; + } + seqNum = spec->seqNum; + keyUpdate = seqNum > spec->cipherDef->max_records - margin; + ssl_ReleaseSpecReadLock(ss); + if (!keyUpdate) { + return SECSuccess; + } + + SSL_TRC(5, ("%d: SSL[%d]: automatic key update at %llx for %s cipher spec", + SSL_GETPID(), ss->fd, seqNum, + (dir == CipherSpecRead) ? "read" : "write")); + ssl_GetSSL3HandshakeLock(ss); + rv = tls13_SendKeyUpdate(ss, (dir == CipherSpecRead) ? update_requested : update_not_requested, + dir == CipherSpecWrite /* buffer */); + ssl_ReleaseSSL3HandshakeLock(ss); + return rv; +} + int ssl_SecureRecv(sslSocket *ss, unsigned char *buf, int len, int flags) { @@ -859,8 +847,17 @@ ssl_SecureRecv(sslSocket *ss, unsigned char *buf, int len, int flags) rv = ssl_Do1stHandshake(ss); } ssl_Release1stHandshakeLock(ss); + } else { + if (tls13_CheckKeyUpdate(ss, CipherSpecRead) != SECSuccess) { + rv = PR_FAILURE; + } } if (rv < 0) { + if (PORT_GetError() == PR_WOULD_BLOCK_ERROR && + !PR_CLIST_IS_EMPTY(&ss->ssl3.hs.bufferedEarlyData)) { + PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_TLS_1_3); + return tls13_Read0RttData(ss, buf, len); + } return rv; } @@ -942,11 +939,19 @@ ssl_SecureSend(sslSocket *ss, const unsigned char *buf, int len, int flags) } ssl_Release1stHandshakeLock(ss); } + if (rv < 0) { ss->writerThread = NULL; goto done; } + if (ss->firstHsDone) { + if (tls13_CheckKeyUpdate(ss, CipherSpecWrite) != SECSuccess) { + rv = PR_FAILURE; + goto done; + } + } + if (zeroRtt) { /* There's a limit to the number of early data octets we can send. * @@ -1151,7 +1156,7 @@ SSL_InvalidateSession(PRFileDesc *fd) ssl_GetSSL3HandshakeLock(ss); if (ss->sec.ci.sid) { - ss->sec.uncache(ss->sec.ci.sid); + ssl_UncacheSessionID(ss); rv = SECSuccess; } @@ -1241,14 +1246,7 @@ SSL_AuthCertificateComplete(PRFileDesc *fd, PRErrorCode error) } ssl_Get1stHandshakeLock(ss); - - if (!ss->ssl3.initialized) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - rv = SECFailure; - } else { - rv = ssl3_AuthCertificateComplete(ss, error); - } - + rv = ssl3_AuthCertificateComplete(ss, error); ssl_Release1stHandshakeLock(ss); return rv; diff --git a/security/nss/lib/ssl/sslsnce.c b/security/nss/lib/ssl/sslsnce.c index 3ef11f7a7..d7abb3dc3 100644 --- a/security/nss/lib/ssl/sslsnce.c +++ b/security/nss/lib/ssl/sslsnce.c @@ -85,11 +85,12 @@ /* ** Format of a cache entry in the shared memory. */ +PR_STATIC_ASSERT(sizeof(PRTime) == 8); struct sidCacheEntryStr { /* 16 */ PRIPv6Addr addr; /* client's IP address */ - /* 4 */ PRUint32 creationTime; - /* 4 */ PRUint32 lastAccessTime; - /* 4 */ PRUint32 expirationTime; + /* 8 */ PRTime creationTime; + /* 8 */ PRTime lastAccessTime; + /* 8 */ PRTime expirationTime; /* 2 */ PRUint16 version; /* 1 */ PRUint8 valid; /* 1 */ PRUint8 sessionIDLength; @@ -98,25 +99,25 @@ struct sidCacheEntryStr { /* 2 */ PRUint16 authKeyBits; /* 2 */ PRUint16 keaType; /* 2 */ PRUint16 keaKeyBits; - /* 72 - common header total */ + /* 4 */ PRUint32 signatureScheme; + /* 4 */ PRUint32 keaGroup; + /* 92 - common header total */ union { struct { /* 2 */ ssl3CipherSuite cipherSuite; - /* 2 */ PRUint16 compression; /* SSLCompressionMethod */ - - /* 54 */ ssl3SidKeys keys; /* keys, wrapped as needed. */ + /* 52 */ ssl3SidKeys keys; /* keys, wrapped as needed. */ /* 4 */ PRUint32 masterWrapMech; /* 4 */ PRInt32 certIndex; /* 4 */ PRInt32 srvNameIndex; /* 32 */ PRUint8 srvNameHash[SHA256_LENGTH]; /* SHA256 name hash */ /* 2 */ PRUint16 namedCurve; -/*104 */} ssl3; +/*100 */} ssl3; /* force sizeof(sidCacheEntry) to be a multiple of cache line size */ struct { - /*120 */ PRUint8 filler[120]; /* 72+120==192, a multiple of 16 */ + /*116 */ PRUint8 filler[116]; /* 92+116==208, a multiple of 16 */ } forceSize; } u; }; @@ -282,7 +283,7 @@ LockSidCacheLock(sidCacheLock *lock, PRUint32 now) if (rv != SECSuccess) return 0; if (!now) - now = ssl_Time(); + now = ssl_TimeSec(); lock->timeStamp = now; lock->pid = myPid; return now; @@ -298,7 +299,7 @@ UnlockSidCacheLock(sidCacheLock *lock) return rv; } -/* returns the value of ssl_Time on success, zero on failure. */ +/* returns the value of ssl_TimeSec on success, zero on failure. */ static PRUint32 LockSet(cacheDesc *cache, PRUint32 set, PRUint32 now) { @@ -432,9 +433,10 @@ ConvertFromSID(sidCacheEntry *to, sslSessionID *from) to->authKeyBits = from->authKeyBits; to->keaType = from->keaType; to->keaKeyBits = from->keaKeyBits; + to->keaGroup = from->keaGroup; + to->signatureScheme = from->sigScheme; to->u.ssl3.cipherSuite = from->u.ssl3.cipherSuite; - to->u.ssl3.compression = (PRUint16)from->u.ssl3.compression; to->u.ssl3.keys = from->u.ssl3.keys; to->u.ssl3.masterWrapMech = from->u.ssl3.masterWrapMech; to->sessionIDLength = from->u.ssl3.sessionIDLength; @@ -452,9 +454,10 @@ ConvertFromSID(sidCacheEntry *to, sslSessionID *from) SSL_TRC(8, ("%d: SSL3: ConvertSID: time=%d addr=0x%08x%08x%08x%08x " "cipherSuite=%d", - myPid, to->creationTime, to->addr.pr_s6_addr32[0], - to->addr.pr_s6_addr32[1], to->addr.pr_s6_addr32[2], - to->addr.pr_s6_addr32[3], to->u.ssl3.cipherSuite)); + myPid, to->creationTime / PR_USEC_PER_SEC, + to->addr.pr_s6_addr32[0], to->addr.pr_s6_addr32[1], + to->addr.pr_s6_addr32[2], to->addr.pr_s6_addr32[3], + to->u.ssl3.cipherSuite)); } /* @@ -476,7 +479,6 @@ ConvertToSID(sidCacheEntry *from, to->u.ssl3.sessionIDLength = from->sessionIDLength; to->u.ssl3.cipherSuite = from->u.ssl3.cipherSuite; - to->u.ssl3.compression = (SSLCompressionMethod)from->u.ssl3.compression; to->u.ssl3.keys = from->u.ssl3.keys; to->u.ssl3.masterWrapMech = from->u.ssl3.masterWrapMech; if (from->u.ssl3.srvNameIndex != -1 && psnce) { @@ -493,12 +495,6 @@ ConvertToSID(sidCacheEntry *from, PORT_Memcpy(to->u.ssl3.sessionID, from->sessionID, from->sessionIDLength); - /* the portions of the SID that are only restored on the client - * are set to invalid values on the server. - */ - to->u.ssl3.clientWriteKey = NULL; - to->u.ssl3.serverWriteKey = NULL; - to->urlSvrName = NULL; to->u.ssl3.masterModuleID = (SECMODModuleID)-1; /* invalid value */ @@ -541,6 +537,8 @@ ConvertToSID(sidCacheEntry *from, to->authKeyBits = from->authKeyBits; to->keaType = from->keaType; to->keaKeyBits = from->keaKeyBits; + to->keaGroup = from->keaGroup; + to->sigScheme = from->signatureScheme; return to; @@ -731,9 +729,11 @@ ServerSessionIDLookup(const PRIPv6Addr *addr, /* ** Place a sid into the cache, if it isn't already there. */ -static void -ServerSessionIDCache(sslSessionID *sid) +void +ssl_ServerCacheSessionID(sslSessionID *sid) { + PORT_Assert(sid); + sidCacheEntry sce; PRUint32 now = 0; cacheDesc *cache = &globalCache; @@ -748,17 +748,19 @@ ServerSessionIDCache(sslSessionID *sid) PORT_Assert(sid->creationTime != 0); if (!sid->creationTime) - sid->lastAccessTime = sid->creationTime = ssl_Time(); + sid->lastAccessTime = sid->creationTime = ssl_TimeUsec(); /* override caller's expiration time, which uses client timeout * duration, not server timeout duration. */ - sid->expirationTime = sid->creationTime + cache->ssl3Timeout; + sid->expirationTime = + sid->creationTime + cache->ssl3Timeout * PR_USEC_PER_SEC; SSL_TRC(8, ("%d: SSL: CacheMT: cached=%d addr=0x%08x%08x%08x%08x time=%x " "cipherSuite=%d", myPid, sid->cached, sid->addr.pr_s6_addr32[0], sid->addr.pr_s6_addr32[1], sid->addr.pr_s6_addr32[2], sid->addr.pr_s6_addr32[3], - sid->creationTime, sid->u.ssl3.cipherSuite)); + sid->creationTime / PR_USEC_PER_SEC, + sid->u.ssl3.cipherSuite)); PRINT_BUF(8, (0, "sessionID:", sid->u.ssl3.sessionID, sid->u.ssl3.sessionIDLength)); @@ -794,8 +796,8 @@ ServerSessionIDCache(sslSessionID *sid) ** Although this is static, it is called from ssl via global function pointer ** ssl_sid_uncache. This invalidates the referenced cache entry. */ -static void -ServerSessionIDUncache(sslSessionID *sid) +void +ssl_ServerUncacheSessionID(sslSessionID *sid) { cacheDesc *cache = &globalCache; PRUint8 *sessionID; @@ -820,7 +822,8 @@ ServerSessionIDUncache(sslSessionID *sid) myPid, sid->cached, sid->addr.pr_s6_addr32[0], sid->addr.pr_s6_addr32[1], sid->addr.pr_s6_addr32[2], sid->addr.pr_s6_addr32[3], - sid->creationTime, sid->u.ssl3.cipherSuite)); + sid->creationTime / PR_USEC_PER_SEC, + sid->u.ssl3.cipherSuite)); PRINT_BUF(8, (0, "sessionID:", sessionID, sessionIDLength)); set = SIDindex(cache, &sid->addr, sessionID, sessionIDLength); now = LockSet(cache, set, 0); @@ -1086,7 +1089,7 @@ InitCache(cacheDesc *cache, int maxCacheEntries, int maxCertCacheEntries, cache->srvNameCacheData = (srvNameCacheEntry *)(cache->cacheMem + (ptrdiff_t)cache->srvNameCacheData); /* initialize the locks */ - init_time = ssl_Time(); + init_time = ssl_TimeSec(); pLock = cache->sidCacheLocks; for (locks_to_initialize = cache->numSIDCacheLocks + 3; locks_initialized < locks_to_initialize; @@ -1134,6 +1137,10 @@ SSL_SetMaxServerCacheLocks(PRUint32 maxLocks) return SECSuccess; } +PR_STATIC_ASSERT(sizeof(sidCacheEntry) % 16 == 0); +PR_STATIC_ASSERT(sizeof(certCacheEntry) == 4096); +PR_STATIC_ASSERT(sizeof(srvNameCacheEntry) == 1072); + static SECStatus ssl_ConfigServerSessionIDCacheInstanceWithOpt(cacheDesc *cache, PRUint32 ssl3_timeout, @@ -1145,10 +1152,6 @@ ssl_ConfigServerSessionIDCacheInstanceWithOpt(cacheDesc *cache, { SECStatus rv; - PORT_Assert(sizeof(sidCacheEntry) == 192); - PORT_Assert(sizeof(certCacheEntry) == 4096); - PORT_Assert(sizeof(srvNameCacheEntry) == 1072); - rv = ssl_Init(); if (rv != SECSuccess) { return rv; @@ -1165,8 +1168,6 @@ ssl_ConfigServerSessionIDCacheInstanceWithOpt(cacheDesc *cache, } ssl_sid_lookup = ServerSessionIDLookup; - ssl_sid_cache = ServerSessionIDCache; - ssl_sid_uncache = ServerSessionIDUncache; return SECSuccess; } @@ -1349,8 +1350,6 @@ SSL_InheritMPServerSIDCacheInstance(cacheDesc *cache, const char *envString) ssl_InitSessionCacheLocks(PR_FALSE); ssl_sid_lookup = ServerSessionIDLookup; - ssl_sid_cache = ServerSessionIDCache; - ssl_sid_uncache = ServerSessionIDUncache; if (!envString) { envString = PR_GetEnvSecure(envVarName); @@ -1519,7 +1518,7 @@ LockPoller(void *arg) if (sharedCache->stopPolling) break; - now = ssl_Time(); + now = ssl_TimeSec(); then = now - expiration; for (pLock = cache->sidCacheLocks, locks_polled = 0; locks_to_poll > locks_polled && !sharedCache->stopPolling; diff --git a/security/nss/lib/ssl/sslsock.c b/security/nss/lib/ssl/sslsock.c index 99828c85b..e08d5e232 100644 --- a/security/nss/lib/ssl/sslsock.c +++ b/security/nss/lib/ssl/sslsock.c @@ -11,6 +11,7 @@ #include "cert.h" #include "keyhi.h" #include "ssl.h" +#include "sslexp.h" #include "sslimpl.h" #include "sslproto.h" #include "nspr.h" @@ -52,38 +53,35 @@ static const sslSocketOps ssl_secure_ops = { /* SSL. */ ** default settings for socket enables */ static sslOptions ssl_defaults = { - { siBuffer, NULL, 0 }, /* nextProtoNego */ - PR_TRUE, /* useSecurity */ - PR_FALSE, /* useSocks */ - PR_FALSE, /* requestCertificate */ - 2, /* requireCertificate */ - PR_FALSE, /* handshakeAsClient */ - PR_FALSE, /* handshakeAsServer */ - PR_FALSE, /* noCache */ - PR_FALSE, /* fdx */ - PR_TRUE, /* detectRollBack */ - PR_FALSE, /* noLocks */ - PR_FALSE, /* enableSessionTickets */ - PR_FALSE, /* enableDeflate */ - 2, /* enableRenegotiation (default: requires extension) */ - PR_FALSE, /* requireSafeNegotiation */ - PR_FALSE, /* enableFalseStart */ - PR_TRUE, /* cbcRandomIV */ - PR_FALSE, /* enableOCSPStapling */ - PR_FALSE, /* enableNPN */ - PR_TRUE, /* enableALPN */ - PR_TRUE, /* reuseServerECDHEKey */ - PR_FALSE, /* enableFallbackSCSV */ - PR_TRUE, /* enableServerDhe */ - PR_FALSE, /* enableExtendedMS */ - PR_FALSE, /* enableSignedCertTimestamps */ - PR_FALSE, /* requireDHENamedGroups */ - PR_FALSE, /* enable0RttData */ -#ifdef NSS_ENABLE_TLS13_SHORT_HEADERS - PR_TRUE /* enableShortHeaders */ -#else - PR_FALSE /* enableShortHeaders */ -#endif + .nextProtoNego = { siBuffer, NULL, 0 }, + .maxEarlyDataSize = 1 << 16, + .useSecurity = PR_TRUE, + .useSocks = PR_FALSE, + .requestCertificate = PR_FALSE, + .requireCertificate = SSL_REQUIRE_FIRST_HANDSHAKE, + .handshakeAsClient = PR_FALSE, + .handshakeAsServer = PR_FALSE, + .noCache = PR_FALSE, + .fdx = PR_FALSE, + .detectRollBack = PR_TRUE, + .noLocks = PR_FALSE, + .enableSessionTickets = PR_FALSE, + .enableDeflate = PR_FALSE, + .enableRenegotiation = SSL_RENEGOTIATE_REQUIRES_XTN, + .requireSafeNegotiation = PR_FALSE, + .enableFalseStart = PR_FALSE, + .cbcRandomIV = PR_TRUE, + .enableOCSPStapling = PR_FALSE, + .enableNPN = PR_FALSE, + .enableALPN = PR_TRUE, + .reuseServerECDHEKey = PR_TRUE, + .enableFallbackSCSV = PR_FALSE, + .enableServerDhe = PR_TRUE, + .enableExtendedMS = PR_FALSE, + .enableSignedCertTimestamps = PR_FALSE, + .requireDHENamedGroups = PR_FALSE, + .enable0RttData = PR_FALSE, + .enableTls13CompatMode = PR_FALSE }; /* @@ -107,10 +105,7 @@ static SSLVersionRange versions_defaults_datagram = { (variant == ssl_variant_stream ? NSS_TLS_VERSION_MAX_POLICY : NSS_DTLS_VERSION_MAX_POLICY) sslSessionIDLookupFunc ssl_sid_lookup; -sslSessionIDCacheFunc ssl_sid_cache; -sslSessionIDUncacheFunc ssl_sid_uncache; -static PRBool ssl_inited = PR_FALSE; static PRDescIdentity ssl_layer_id; PRBool locksEverDisabled; /* implicitly PR_FALSE */ @@ -122,6 +117,7 @@ FILE *ssl_trace_iob; #ifdef NSS_ALLOW_SSLKEYLOGFILE FILE *ssl_keylog_iob; +PZLock *ssl_keylog_lock; #endif char lockStatus[] = "Locks are ENABLED. "; @@ -300,6 +296,7 @@ ssl_DupSocket(sslSocket *os) if (ss->opt.useSecurity) { PRCList *cursor; + for (cursor = PR_NEXT_LINK(&os->serverCerts); cursor != &os->serverCerts; cursor = PR_NEXT_LINK(cursor)) { @@ -309,7 +306,6 @@ ssl_DupSocket(sslSocket *os) PR_APPEND_LINK(&sc->link, &ss->serverCerts); } - PR_INIT_CLIST(&ss->ephemeralKeyPairs); for (cursor = PR_NEXT_LINK(&os->ephemeralKeyPairs); cursor != &os->ephemeralKeyPairs; cursor = PR_NEXT_LINK(cursor)) { @@ -320,6 +316,18 @@ ssl_DupSocket(sslSocket *os) PR_APPEND_LINK(&skp->link, &ss->ephemeralKeyPairs); } + for (cursor = PR_NEXT_LINK(&os->extensionHooks); + cursor != &os->extensionHooks; + cursor = PR_NEXT_LINK(cursor)) { + sslCustomExtensionHooks *oh = (sslCustomExtensionHooks *)cursor; + sslCustomExtensionHooks *sh = PORT_ZNew(sslCustomExtensionHooks); + if (!sh) { + goto loser; + } + *sh = *oh; + PR_APPEND_LINK(&sh->link, &ss->extensionHooks); + } + /* * XXX the preceding CERT_ and SECKEY_ functions can fail and return NULL. * XXX We should detect this, and not just march on with NULL pointers. @@ -347,6 +355,8 @@ ssl_DupSocket(sslSocket *os) os->namedGroupPreferences, sizeof(ss->namedGroupPreferences)); ss->additionalShares = os->additionalShares; + ss->resumptionTokenCallback = os->resumptionTokenCallback; + ss->resumptionTokenContext = os->resumptionTokenContext; /* Create security data */ rv = ssl_CopySecurityInfo(ss, os); @@ -354,6 +364,7 @@ ssl_DupSocket(sslSocket *os) goto loser; } } + return ss; loser: @@ -422,9 +433,16 @@ ssl_DestroySocketContents(sslSocket *ss) PR_REMOVE_LINK(cursor); ssl_FreeServerCert((sslServerCert *)cursor); } + + /* Remove extension handlers. */ + ssl_ClearPRCList(&ss->extensionHooks, NULL); + ssl_FreeEphemeralKeyPairs(ss); SECITEM_FreeItem(&ss->opt.nextProtoNego, PR_FALSE); ssl3_FreeSniNameArray(&ss->xtnData); + + ssl_ClearPRCList(&ss->ssl3.hs.dtlsSentHandshake, NULL); + ssl_ClearPRCList(&ss->ssl3.hs.dtlsRcvdHandshake, NULL); } /* @@ -501,7 +519,7 @@ PrepareSocket(sslSocket *ss) } SECStatus -SSL_Enable(PRFileDesc *fd, int which, PRBool on) +SSL_Enable(PRFileDesc *fd, int which, PRIntn on) { return SSL_OptionSet(fd, which, on); } @@ -513,9 +531,9 @@ static PRBool ssl_VersionIsSupportedByPolicy( * ssl.h in the section "SSL version range setting API". */ static void -ssl_EnableTLS(SSLVersionRange *vrange, PRBool on) +ssl_EnableTLS(SSLVersionRange *vrange, PRIntn enable) { - if (on) { + if (enable) { /* don't turn it on if tls1.0 disallowed by by policy */ if (!ssl_VersionIsSupportedByPolicy(ssl_variant_stream, SSL_LIBRARY_VERSION_TLS_1_0)) { @@ -523,14 +541,14 @@ ssl_EnableTLS(SSLVersionRange *vrange, PRBool on) } } if (SSL_ALL_VERSIONS_DISABLED(vrange)) { - if (on) { + if (enable) { vrange->min = SSL_LIBRARY_VERSION_TLS_1_0; vrange->max = SSL_LIBRARY_VERSION_TLS_1_0; } /* else don't change anything */ return; } - if (on) { + if (enable) { /* Expand the range of enabled version to include TLS 1.0 */ vrange->min = PR_MIN(vrange->min, SSL_LIBRARY_VERSION_TLS_1_0); vrange->max = PR_MAX(vrange->max, SSL_LIBRARY_VERSION_TLS_1_0); @@ -550,9 +568,9 @@ ssl_EnableTLS(SSLVersionRange *vrange, PRBool on) * ssl.h in the section "SSL version range setting API". */ static void -ssl_EnableSSL3(SSLVersionRange *vrange, PRBool on) +ssl_EnableSSL3(SSLVersionRange *vrange, PRIntn enable) { - if (on) { + if (enable) { /* don't turn it on if ssl3 disallowed by by policy */ if (!ssl_VersionIsSupportedByPolicy(ssl_variant_stream, SSL_LIBRARY_VERSION_3_0)) { @@ -560,14 +578,14 @@ ssl_EnableSSL3(SSLVersionRange *vrange, PRBool on) } } if (SSL_ALL_VERSIONS_DISABLED(vrange)) { - if (on) { + if (enable) { vrange->min = SSL_LIBRARY_VERSION_3_0; vrange->max = SSL_LIBRARY_VERSION_3_0; } /* else don't change anything */ return; } - if (on) { + if (enable) { /* Expand the range of enabled versions to include SSL 3.0. We know * SSL 3.0 or some version of TLS is already enabled at this point, so * we don't need to change vrange->max. @@ -586,7 +604,7 @@ ssl_EnableSSL3(SSLVersionRange *vrange, PRBool on) } SECStatus -SSL_OptionSet(PRFileDesc *fd, PRInt32 which, PRBool on) +SSL_OptionSet(PRFileDesc *fd, PRInt32 which, PRIntn val) { sslSocket *ss = ssl_FindSocket(fd); SECStatus rv = SECSuccess; @@ -605,63 +623,63 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 which, PRBool on) case SSL_SOCKS: ss->opt.useSocks = PR_FALSE; rv = PrepareSocket(ss); - if (on) { + if (val) { PORT_SetError(SEC_ERROR_INVALID_ARGS); rv = SECFailure; } break; case SSL_SECURITY: - ss->opt.useSecurity = on; + ss->opt.useSecurity = val; rv = PrepareSocket(ss); break; case SSL_REQUEST_CERTIFICATE: - ss->opt.requestCertificate = on; + ss->opt.requestCertificate = val; break; case SSL_REQUIRE_CERTIFICATE: - ss->opt.requireCertificate = on; + ss->opt.requireCertificate = val; break; case SSL_HANDSHAKE_AS_CLIENT: - if (ss->opt.handshakeAsServer && on) { + if (ss->opt.handshakeAsServer && val) { PORT_SetError(SEC_ERROR_INVALID_ARGS); rv = SECFailure; break; } - ss->opt.handshakeAsClient = on; + ss->opt.handshakeAsClient = val; break; case SSL_HANDSHAKE_AS_SERVER: - if (ss->opt.handshakeAsClient && on) { + if (ss->opt.handshakeAsClient && val) { PORT_SetError(SEC_ERROR_INVALID_ARGS); rv = SECFailure; break; } - ss->opt.handshakeAsServer = on; + ss->opt.handshakeAsServer = val; break; case SSL_ENABLE_TLS: if (IS_DTLS(ss)) { - if (on) { + if (val) { PORT_SetError(SEC_ERROR_INVALID_ARGS); rv = SECFailure; /* not allowed */ } break; } - ssl_EnableTLS(&ss->vrange, on); + ssl_EnableTLS(&ss->vrange, val); break; case SSL_ENABLE_SSL3: if (IS_DTLS(ss)) { - if (on) { + if (val) { PORT_SetError(SEC_ERROR_INVALID_ARGS); rv = SECFailure; /* not allowed */ } break; } - ssl_EnableSSL3(&ss->vrange, on); + ssl_EnableSSL3(&ss->vrange, val); break; case SSL_ENABLE_SSL2: @@ -670,26 +688,26 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 which, PRBool on) * However, if an old application requests to disable SSL v2, * we shouldn't fail. */ - if (on) { + if (val) { PORT_SetError(SEC_ERROR_INVALID_ARGS); rv = SECFailure; } break; case SSL_NO_CACHE: - ss->opt.noCache = on; + ss->opt.noCache = val; break; case SSL_ENABLE_FDX: - if (on && ss->opt.noLocks) { + if (val && ss->opt.noLocks) { PORT_SetError(SEC_ERROR_INVALID_ARGS); rv = SECFailure; } - ss->opt.fdx = on; + ss->opt.fdx = val; break; case SSL_ROLLBACK_DETECTION: - ss->opt.detectRollBack = on; + ss->opt.detectRollBack = val; break; case SSL_NO_STEP_DOWN: @@ -699,14 +717,14 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 which, PRBool on) break; case SSL_NO_LOCKS: - if (on && ss->opt.fdx) { + if (val && ss->opt.fdx) { PORT_SetError(SEC_ERROR_INVALID_ARGS); rv = SECFailure; } - if (on && ssl_force_locks) - on = PR_FALSE; /* silent override */ - ss->opt.noLocks = on; - if (on) { + if (val && ssl_force_locks) + val = PR_FALSE; /* silent override */ + ss->opt.noLocks = val; + if (val) { locksEverDisabled = PR_TRUE; strcpy(lockStatus + LOCKSTATUS_OFFSET, "DISABLED."); } else if (!holdingLocks) { @@ -718,71 +736,75 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 which, PRBool on) break; case SSL_ENABLE_SESSION_TICKETS: - ss->opt.enableSessionTickets = on; + ss->opt.enableSessionTickets = val; break; case SSL_ENABLE_DEFLATE: - ss->opt.enableDeflate = on; + ss->opt.enableDeflate = val; break; case SSL_ENABLE_RENEGOTIATION: - if (IS_DTLS(ss) && on != SSL_RENEGOTIATE_NEVER) { + if (IS_DTLS(ss) && val != SSL_RENEGOTIATE_NEVER) { PORT_SetError(SEC_ERROR_INVALID_ARGS); rv = SECFailure; break; } - ss->opt.enableRenegotiation = on; + ss->opt.enableRenegotiation = val; break; case SSL_REQUIRE_SAFE_NEGOTIATION: - ss->opt.requireSafeNegotiation = on; + ss->opt.requireSafeNegotiation = val; break; case SSL_ENABLE_FALSE_START: - ss->opt.enableFalseStart = on; + ss->opt.enableFalseStart = val; break; case SSL_CBC_RANDOM_IV: - ss->opt.cbcRandomIV = on; + ss->opt.cbcRandomIV = val; break; case SSL_ENABLE_OCSP_STAPLING: - ss->opt.enableOCSPStapling = on; + ss->opt.enableOCSPStapling = val; break; case SSL_ENABLE_NPN: break; case SSL_ENABLE_ALPN: - ss->opt.enableALPN = on; + ss->opt.enableALPN = val; break; case SSL_REUSE_SERVER_ECDHE_KEY: - ss->opt.reuseServerECDHEKey = on; + ss->opt.reuseServerECDHEKey = val; break; case SSL_ENABLE_FALLBACK_SCSV: - ss->opt.enableFallbackSCSV = on; + ss->opt.enableFallbackSCSV = val; break; case SSL_ENABLE_SERVER_DHE: - ss->opt.enableServerDhe = on; + ss->opt.enableServerDhe = val; break; case SSL_ENABLE_EXTENDED_MASTER_SECRET: - ss->opt.enableExtendedMS = on; + ss->opt.enableExtendedMS = val; break; case SSL_ENABLE_SIGNED_CERT_TIMESTAMPS: - ss->opt.enableSignedCertTimestamps = on; + ss->opt.enableSignedCertTimestamps = val; break; case SSL_REQUIRE_DH_NAMED_GROUPS: - ss->opt.requireDHENamedGroups = on; + ss->opt.requireDHENamedGroups = val; break; case SSL_ENABLE_0RTT_DATA: - ss->opt.enable0RttData = on; + ss->opt.enable0RttData = val; + break; + + case SSL_ENABLE_TLS13_COMPAT_MODE: + ss->opt.enableTls13CompatMode = val; break; default: @@ -804,19 +826,19 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 which, PRBool on) } SECStatus -SSL_OptionGet(PRFileDesc *fd, PRInt32 which, PRBool *pOn) +SSL_OptionGet(PRFileDesc *fd, PRInt32 which, PRIntn *pVal) { sslSocket *ss = ssl_FindSocket(fd); SECStatus rv = SECSuccess; - PRBool on = PR_FALSE; + PRIntn val = PR_FALSE; - if (!pOn) { + if (!pVal) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } if (!ss) { SSL_DBG(("%d: SSL[%d]: bad socket in Enable", SSL_GETPID(), fd)); - *pOn = PR_FALSE; + *pVal = PR_FALSE; return SECFailure; } @@ -825,98 +847,101 @@ SSL_OptionGet(PRFileDesc *fd, PRInt32 which, PRBool *pOn) switch (which) { case SSL_SOCKS: - on = PR_FALSE; + val = PR_FALSE; break; case SSL_SECURITY: - on = ss->opt.useSecurity; + val = ss->opt.useSecurity; break; case SSL_REQUEST_CERTIFICATE: - on = ss->opt.requestCertificate; + val = ss->opt.requestCertificate; break; case SSL_REQUIRE_CERTIFICATE: - on = ss->opt.requireCertificate; + val = ss->opt.requireCertificate; break; case SSL_HANDSHAKE_AS_CLIENT: - on = ss->opt.handshakeAsClient; + val = ss->opt.handshakeAsClient; break; case SSL_HANDSHAKE_AS_SERVER: - on = ss->opt.handshakeAsServer; + val = ss->opt.handshakeAsServer; break; case SSL_ENABLE_TLS: - on = ss->vrange.max >= SSL_LIBRARY_VERSION_TLS_1_0; + val = ss->vrange.max >= SSL_LIBRARY_VERSION_TLS_1_0; break; case SSL_ENABLE_SSL3: - on = ss->vrange.min == SSL_LIBRARY_VERSION_3_0; + val = ss->vrange.min == SSL_LIBRARY_VERSION_3_0; break; case SSL_ENABLE_SSL2: case SSL_V2_COMPATIBLE_HELLO: - on = PR_FALSE; + val = PR_FALSE; break; case SSL_NO_CACHE: - on = ss->opt.noCache; + val = ss->opt.noCache; break; case SSL_ENABLE_FDX: - on = ss->opt.fdx; + val = ss->opt.fdx; break; case SSL_ROLLBACK_DETECTION: - on = ss->opt.detectRollBack; + val = ss->opt.detectRollBack; break; case SSL_NO_STEP_DOWN: - on = PR_FALSE; + val = PR_FALSE; break; case SSL_BYPASS_PKCS11: - on = PR_FALSE; + val = PR_FALSE; break; case SSL_NO_LOCKS: - on = ss->opt.noLocks; + val = ss->opt.noLocks; break; case SSL_ENABLE_SESSION_TICKETS: - on = ss->opt.enableSessionTickets; + val = ss->opt.enableSessionTickets; break; case SSL_ENABLE_DEFLATE: - on = ss->opt.enableDeflate; + val = ss->opt.enableDeflate; break; case SSL_ENABLE_RENEGOTIATION: - on = ss->opt.enableRenegotiation; + val = ss->opt.enableRenegotiation; break; case SSL_REQUIRE_SAFE_NEGOTIATION: - on = ss->opt.requireSafeNegotiation; + val = ss->opt.requireSafeNegotiation; break; case SSL_ENABLE_FALSE_START: - on = ss->opt.enableFalseStart; + val = ss->opt.enableFalseStart; break; case SSL_CBC_RANDOM_IV: - on = ss->opt.cbcRandomIV; + val = ss->opt.cbcRandomIV; break; case SSL_ENABLE_OCSP_STAPLING: - on = ss->opt.enableOCSPStapling; + val = ss->opt.enableOCSPStapling; break; case SSL_ENABLE_NPN: - on = ss->opt.enableNPN; + val = ss->opt.enableNPN; break; case SSL_ENABLE_ALPN: - on = ss->opt.enableALPN; + val = ss->opt.enableALPN; break; case SSL_REUSE_SERVER_ECDHE_KEY: - on = ss->opt.reuseServerECDHEKey; + val = ss->opt.reuseServerECDHEKey; break; case SSL_ENABLE_FALLBACK_SCSV: - on = ss->opt.enableFallbackSCSV; + val = ss->opt.enableFallbackSCSV; break; case SSL_ENABLE_SERVER_DHE: - on = ss->opt.enableServerDhe; + val = ss->opt.enableServerDhe; break; case SSL_ENABLE_EXTENDED_MASTER_SECRET: - on = ss->opt.enableExtendedMS; + val = ss->opt.enableExtendedMS; break; case SSL_ENABLE_SIGNED_CERT_TIMESTAMPS: - on = ss->opt.enableSignedCertTimestamps; + val = ss->opt.enableSignedCertTimestamps; break; case SSL_REQUIRE_DH_NAMED_GROUPS: - on = ss->opt.requireDHENamedGroups; + val = ss->opt.requireDHENamedGroups; break; case SSL_ENABLE_0RTT_DATA: - on = ss->opt.enable0RttData; + val = ss->opt.enable0RttData; + break; + case SSL_ENABLE_TLS13_COMPAT_MODE: + val = ss->opt.enableTls13CompatMode; break; default: PORT_SetError(SEC_ERROR_INVALID_ARGS); @@ -926,17 +951,17 @@ SSL_OptionGet(PRFileDesc *fd, PRInt32 which, PRBool *pOn) ssl_ReleaseSSL3HandshakeLock(ss); ssl_Release1stHandshakeLock(ss); - *pOn = on; + *pVal = val; return rv; } SECStatus -SSL_OptionGetDefault(PRInt32 which, PRBool *pOn) +SSL_OptionGetDefault(PRInt32 which, PRIntn *pVal) { SECStatus rv = SECSuccess; - PRBool on = PR_FALSE; + PRIntn val = PR_FALSE; - if (!pOn) { + if (!pVal) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } @@ -945,114 +970,117 @@ SSL_OptionGetDefault(PRInt32 which, PRBool *pOn) switch (which) { case SSL_SOCKS: - on = PR_FALSE; + val = PR_FALSE; break; case SSL_SECURITY: - on = ssl_defaults.useSecurity; + val = ssl_defaults.useSecurity; break; case SSL_REQUEST_CERTIFICATE: - on = ssl_defaults.requestCertificate; + val = ssl_defaults.requestCertificate; break; case SSL_REQUIRE_CERTIFICATE: - on = ssl_defaults.requireCertificate; + val = ssl_defaults.requireCertificate; break; case SSL_HANDSHAKE_AS_CLIENT: - on = ssl_defaults.handshakeAsClient; + val = ssl_defaults.handshakeAsClient; break; case SSL_HANDSHAKE_AS_SERVER: - on = ssl_defaults.handshakeAsServer; + val = ssl_defaults.handshakeAsServer; break; case SSL_ENABLE_TLS: - on = versions_defaults_stream.max >= SSL_LIBRARY_VERSION_TLS_1_0; + val = versions_defaults_stream.max >= SSL_LIBRARY_VERSION_TLS_1_0; break; case SSL_ENABLE_SSL3: - on = versions_defaults_stream.min == SSL_LIBRARY_VERSION_3_0; + val = versions_defaults_stream.min == SSL_LIBRARY_VERSION_3_0; break; case SSL_ENABLE_SSL2: case SSL_V2_COMPATIBLE_HELLO: - on = PR_FALSE; + val = PR_FALSE; break; case SSL_NO_CACHE: - on = ssl_defaults.noCache; + val = ssl_defaults.noCache; break; case SSL_ENABLE_FDX: - on = ssl_defaults.fdx; + val = ssl_defaults.fdx; break; case SSL_ROLLBACK_DETECTION: - on = ssl_defaults.detectRollBack; + val = ssl_defaults.detectRollBack; break; case SSL_NO_STEP_DOWN: - on = PR_FALSE; + val = PR_FALSE; break; case SSL_BYPASS_PKCS11: - on = PR_FALSE; + val = PR_FALSE; break; case SSL_NO_LOCKS: - on = ssl_defaults.noLocks; + val = ssl_defaults.noLocks; break; case SSL_ENABLE_SESSION_TICKETS: - on = ssl_defaults.enableSessionTickets; + val = ssl_defaults.enableSessionTickets; break; case SSL_ENABLE_DEFLATE: - on = ssl_defaults.enableDeflate; + val = ssl_defaults.enableDeflate; break; case SSL_ENABLE_RENEGOTIATION: - on = ssl_defaults.enableRenegotiation; + val = ssl_defaults.enableRenegotiation; break; case SSL_REQUIRE_SAFE_NEGOTIATION: - on = ssl_defaults.requireSafeNegotiation; + val = ssl_defaults.requireSafeNegotiation; break; case SSL_ENABLE_FALSE_START: - on = ssl_defaults.enableFalseStart; + val = ssl_defaults.enableFalseStart; break; case SSL_CBC_RANDOM_IV: - on = ssl_defaults.cbcRandomIV; + val = ssl_defaults.cbcRandomIV; break; case SSL_ENABLE_OCSP_STAPLING: - on = ssl_defaults.enableOCSPStapling; + val = ssl_defaults.enableOCSPStapling; break; case SSL_ENABLE_NPN: - on = ssl_defaults.enableNPN; + val = ssl_defaults.enableNPN; break; case SSL_ENABLE_ALPN: - on = ssl_defaults.enableALPN; + val = ssl_defaults.enableALPN; break; case SSL_REUSE_SERVER_ECDHE_KEY: - on = ssl_defaults.reuseServerECDHEKey; + val = ssl_defaults.reuseServerECDHEKey; break; case SSL_ENABLE_FALLBACK_SCSV: - on = ssl_defaults.enableFallbackSCSV; + val = ssl_defaults.enableFallbackSCSV; break; case SSL_ENABLE_SERVER_DHE: - on = ssl_defaults.enableServerDhe; + val = ssl_defaults.enableServerDhe; break; case SSL_ENABLE_EXTENDED_MASTER_SECRET: - on = ssl_defaults.enableExtendedMS; + val = ssl_defaults.enableExtendedMS; break; case SSL_ENABLE_SIGNED_CERT_TIMESTAMPS: - on = ssl_defaults.enableSignedCertTimestamps; + val = ssl_defaults.enableSignedCertTimestamps; break; case SSL_ENABLE_0RTT_DATA: - on = ssl_defaults.enable0RttData; + val = ssl_defaults.enable0RttData; + break; + case SSL_ENABLE_TLS13_COMPAT_MODE: + val = ssl_defaults.enableTls13CompatMode; break; default: PORT_SetError(SEC_ERROR_INVALID_ARGS); rv = SECFailure; } - *pOn = on; + *pVal = val; return rv; } /* XXX Use Global Lock to protect this stuff. */ SECStatus -SSL_EnableDefault(int which, PRBool on) +SSL_EnableDefault(int which, PRIntn val) { - return SSL_OptionSetDefault(which, on); + return SSL_OptionSetDefault(which, val); } SECStatus -SSL_OptionSetDefault(PRInt32 which, PRBool on) +SSL_OptionSetDefault(PRInt32 which, PRIntn val) { SECStatus status = ssl_Init(); @@ -1065,46 +1093,46 @@ SSL_OptionSetDefault(PRInt32 which, PRBool on) switch (which) { case SSL_SOCKS: ssl_defaults.useSocks = PR_FALSE; - if (on) { + if (val) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } break; case SSL_SECURITY: - ssl_defaults.useSecurity = on; + ssl_defaults.useSecurity = val; break; case SSL_REQUEST_CERTIFICATE: - ssl_defaults.requestCertificate = on; + ssl_defaults.requestCertificate = val; break; case SSL_REQUIRE_CERTIFICATE: - ssl_defaults.requireCertificate = on; + ssl_defaults.requireCertificate = val; break; case SSL_HANDSHAKE_AS_CLIENT: - if (ssl_defaults.handshakeAsServer && on) { + if (ssl_defaults.handshakeAsServer && val) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } - ssl_defaults.handshakeAsClient = on; + ssl_defaults.handshakeAsClient = val; break; case SSL_HANDSHAKE_AS_SERVER: - if (ssl_defaults.handshakeAsClient && on) { + if (ssl_defaults.handshakeAsClient && val) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } - ssl_defaults.handshakeAsServer = on; + ssl_defaults.handshakeAsServer = val; break; case SSL_ENABLE_TLS: - ssl_EnableTLS(&versions_defaults_stream, on); + ssl_EnableTLS(&versions_defaults_stream, val); break; case SSL_ENABLE_SSL3: - ssl_EnableSSL3(&versions_defaults_stream, on); + ssl_EnableSSL3(&versions_defaults_stream, val); break; case SSL_ENABLE_SSL2: @@ -1113,26 +1141,26 @@ SSL_OptionSetDefault(PRInt32 which, PRBool on) * However, if an old application requests to disable SSL v2, * we shouldn't fail. */ - if (on) { + if (val) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } break; case SSL_NO_CACHE: - ssl_defaults.noCache = on; + ssl_defaults.noCache = val; break; case SSL_ENABLE_FDX: - if (on && ssl_defaults.noLocks) { + if (val && ssl_defaults.noLocks) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } - ssl_defaults.fdx = on; + ssl_defaults.fdx = val; break; case SSL_ROLLBACK_DETECTION: - ssl_defaults.detectRollBack = on; + ssl_defaults.detectRollBack = val; break; case SSL_NO_STEP_DOWN: @@ -1142,76 +1170,80 @@ SSL_OptionSetDefault(PRInt32 which, PRBool on) break; case SSL_NO_LOCKS: - if (on && ssl_defaults.fdx) { + if (val && ssl_defaults.fdx) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } - if (on && ssl_force_locks) - on = PR_FALSE; /* silent override */ - ssl_defaults.noLocks = on; - if (on) { + if (val && ssl_force_locks) + val = PR_FALSE; /* silent override */ + ssl_defaults.noLocks = val; + if (val) { locksEverDisabled = PR_TRUE; strcpy(lockStatus + LOCKSTATUS_OFFSET, "DISABLED."); } break; case SSL_ENABLE_SESSION_TICKETS: - ssl_defaults.enableSessionTickets = on; + ssl_defaults.enableSessionTickets = val; break; case SSL_ENABLE_DEFLATE: - ssl_defaults.enableDeflate = on; + ssl_defaults.enableDeflate = val; break; case SSL_ENABLE_RENEGOTIATION: - ssl_defaults.enableRenegotiation = on; + ssl_defaults.enableRenegotiation = val; break; case SSL_REQUIRE_SAFE_NEGOTIATION: - ssl_defaults.requireSafeNegotiation = on; + ssl_defaults.requireSafeNegotiation = val; break; case SSL_ENABLE_FALSE_START: - ssl_defaults.enableFalseStart = on; + ssl_defaults.enableFalseStart = val; break; case SSL_CBC_RANDOM_IV: - ssl_defaults.cbcRandomIV = on; + ssl_defaults.cbcRandomIV = val; break; case SSL_ENABLE_OCSP_STAPLING: - ssl_defaults.enableOCSPStapling = on; + ssl_defaults.enableOCSPStapling = val; break; case SSL_ENABLE_NPN: break; case SSL_ENABLE_ALPN: - ssl_defaults.enableALPN = on; + ssl_defaults.enableALPN = val; break; case SSL_REUSE_SERVER_ECDHE_KEY: - ssl_defaults.reuseServerECDHEKey = on; + ssl_defaults.reuseServerECDHEKey = val; break; case SSL_ENABLE_FALLBACK_SCSV: - ssl_defaults.enableFallbackSCSV = on; + ssl_defaults.enableFallbackSCSV = val; break; case SSL_ENABLE_SERVER_DHE: - ssl_defaults.enableServerDhe = on; + ssl_defaults.enableServerDhe = val; break; case SSL_ENABLE_EXTENDED_MASTER_SECRET: - ssl_defaults.enableExtendedMS = on; + ssl_defaults.enableExtendedMS = val; break; case SSL_ENABLE_SIGNED_CERT_TIMESTAMPS: - ssl_defaults.enableSignedCertTimestamps = on; + ssl_defaults.enableSignedCertTimestamps = val; break; case SSL_ENABLE_0RTT_DATA: - ssl_defaults.enable0RttData = on; + ssl_defaults.enable0RttData = val; + break; + + case SSL_ENABLE_TLS13_COMPAT_MODE: + ssl_defaults.enableTls13CompatMode = val; break; default: @@ -1221,6 +1253,18 @@ SSL_OptionSetDefault(PRInt32 which, PRBool on) return SECSuccess; } +SECStatus +SSLExp_SetMaxEarlyDataSize(PRFileDesc *fd, PRUint32 size) +{ + sslSocket *ss = ssl_FindSocket(fd); + if (!ss) { + return SECFailure; /* Error code already set. */ + } + + ss->opt.maxEarlyDataSize = size; + return SECSuccess; +} + /* function tells us if the cipher suite is one that we no longer support. */ static PRBool ssl_IsRemovedCipherSuite(PRInt32 suite) @@ -2124,6 +2168,25 @@ SSL_ReconfigFD(PRFileDesc *model, PRFileDesc *fd) return NULL; PR_APPEND_LINK(&skp->link, &ss->ephemeralKeyPairs); } + + while (!PR_CLIST_IS_EMPTY(&ss->extensionHooks)) { + cursor = PR_LIST_TAIL(&ss->extensionHooks); + PR_REMOVE_LINK(cursor); + PORT_Free(cursor); + } + for (cursor = PR_NEXT_LINK(&sm->extensionHooks); + cursor != &sm->extensionHooks; + cursor = PR_NEXT_LINK(cursor)) { + SECStatus rv; + sslCustomExtensionHooks *hook = (sslCustomExtensionHooks *)cursor; + rv = SSL_InstallExtensionHooks(ss->fd, hook->type, + hook->writer, hook->writerArg, + hook->handler, hook->handlerArg); + if (rv != SECSuccess) { + return NULL; + } + } + PORT_Memcpy((void *)ss->namedGroupPreferences, sm->namedGroupPreferences, sizeof(ss->namedGroupPreferences)); @@ -2214,7 +2277,7 @@ ssl3_GetEffectiveVersionPolicy(SSLProtocolVariant variant, return SECSuccess; } -/* +/* * Assumes that rangeParam values are within the supported boundaries, * but should contain all potentially allowed versions, even if they contain * conflicting versions. @@ -3124,7 +3187,7 @@ ssl_WriteV(PRFileDesc *fd, const PRIOVec *iov, PRInt32 vectors, } blocking = ssl_FdIsBlocking(fd); -#define K16 sizeof(buf) +#define K16 ((int)sizeof(buf)) #define KILL_VECTORS \ while (vectors && !iov->iov_len) { \ ++iov; \ @@ -3411,7 +3474,6 @@ ssl_InitIOLayer(void) { ssl_layer_id = PR_GetUniqueIdentity("SSL"); ssl_SetupIOMethods(); - ssl_inited = PR_TRUE; return PR_SUCCESS; } @@ -3421,15 +3483,13 @@ ssl_PushIOLayer(sslSocket *ns, PRFileDesc *stack, PRDescIdentity id) PRFileDesc *layer = NULL; PRStatus status; - if (!ssl_inited) { - status = PR_CallOnce(&initIoLayerOnce, &ssl_InitIOLayer); - if (status != PR_SUCCESS) - goto loser; + status = PR_CallOnce(&initIoLayerOnce, &ssl_InitIOLayer); + if (status != PR_SUCCESS) { + goto loser; } - - if (ns == NULL) + if (ns == NULL) { goto loser; - + } layer = PR_CreateIOLayerStub(ssl_layer_id, &combined_methods); if (layer == NULL) goto loser; @@ -3542,6 +3602,12 @@ ssl_SetDefaultsFromEnvironment(void) ssl_keylog_iob); } SSL_TRACE(("SSL: logging SSL/TLS secrets to %s", ev)); + ssl_keylog_lock = PR_NewLock(); + if (!ssl_keylog_lock) { + SSL_TRACE(("SSL: failed to create key log lock")); + fclose(ssl_keylog_iob); + ssl_keylog_iob = NULL; + } } } #endif @@ -3746,7 +3812,6 @@ ssl_NewSocket(PRBool makeLocks, SSLProtocolVariant protocolVariant) SECStatus rv; sslSocket *ss; int i; - ssl_SetDefaultsFromEnvironment(); if (ssl_force_locks) @@ -3777,6 +3842,7 @@ ssl_NewSocket(PRBool makeLocks, SSLProtocolVariant protocolVariant) PR_INIT_CLIST(&ss->serverCerts); PR_INIT_CLIST(&ss->ephemeralKeyPairs); + PR_INIT_CLIST(&ss->extensionHooks); ss->dbHandle = CERT_GetDefaultCertDB(); @@ -3804,7 +3870,11 @@ ssl_NewSocket(PRBool makeLocks, SSLProtocolVariant protocolVariant) PR_INIT_CLIST(&ss->ssl3.hs.lastMessageFlight); PR_INIT_CLIST(&ss->ssl3.hs.cipherSpecs); PR_INIT_CLIST(&ss->ssl3.hs.bufferedEarlyData); - ssl3_InitExtensionData(&ss->xtnData); + ssl3_InitExtensionData(&ss->xtnData, ss); + PR_INIT_CLIST(&ss->ssl3.hs.dtlsSentHandshake); + PR_INIT_CLIST(&ss->ssl3.hs.dtlsRcvdHandshake); + dtls_InitTimers(ss); + if (makeLocks) { rv = ssl_MakeLocks(ss); if (rv != SECSuccess) @@ -3816,6 +3886,10 @@ ssl_NewSocket(PRBool makeLocks, SSLProtocolVariant protocolVariant) rv = ssl3_InitGather(&ss->gs); if (rv != SECSuccess) goto loser; + rv = ssl3_InitState(ss); + if (rv != SECSuccess) { + goto loser; + } return ss; loser: @@ -3840,3 +3914,227 @@ SSL_CanBypass(CERTCertificate *cert, SECKEYPrivateKey *srvPrivkey, *pcanbypass = PR_FALSE; return SECSuccess; } + +/* Functions that are truly experimental use EXP, functions that are no longer + * experimental use PUB. + * + * When initially defining a new API, add that API here using the EXP() macro + * and name the function with a SSLExp_ prefix. Define the experimental API as + * a macro in sslexp.h using the SSL_EXPERIMENTAL_API() macro defined there. + * + * Once an API is stable and proven, move the macro definition in sslexp.h to a + * proper function declaration in ssl.h. Keeping the function in this list + * ensures that code built against the release that contained the experimental + * API will continue to work; use PUB() to reference the public function. + */ +#define EXP(n) \ + { \ + "SSL_" #n, SSLExp_##n \ + } +#define PUB(n) \ + { \ + "SSL_" #n, SSL_##n \ + } +struct { + const char *const name; + void *function; +} ssl_experimental_functions[] = { +#ifndef SSL_DISABLE_EXPERIMENTAL_API + EXP(GetExtensionSupport), + EXP(HelloRetryRequestCallback), + EXP(InstallExtensionHooks), + EXP(KeyUpdate), + EXP(SendSessionTicket), + EXP(SetMaxEarlyDataSize), + EXP(SetupAntiReplay), + EXP(SetResumptionTokenCallback), + EXP(SetResumptionToken), + EXP(GetResumptionTokenInfo), + EXP(DestroyResumptionTokenInfo), +#endif + { "", NULL } +}; +#undef EXP +#undef PUB + +void * +SSL_GetExperimentalAPI(const char *name) +{ + unsigned int i; + for (i = 0; i < PR_ARRAY_SIZE(ssl_experimental_functions); ++i) { + if (strcmp(name, ssl_experimental_functions[i].name) == 0) { + return ssl_experimental_functions[i].function; + } + } + PORT_SetError(SSL_ERROR_UNSUPPORTED_EXPERIMENTAL_API); + return NULL; +} + +void +ssl_ClearPRCList(PRCList *list, void (*f)(void *)) +{ + PRCList *cursor; + + while (!PR_CLIST_IS_EMPTY(list)) { + cursor = PR_LIST_TAIL(list); + + PR_REMOVE_LINK(cursor); + if (f) { + f(cursor); + } + PORT_Free(cursor); + } +} + +/* Experimental APIs for session cache handling. */ + +SECStatus +SSLExp_SetResumptionTokenCallback(PRFileDesc *fd, + SSLResumptionTokenCallback cb, + void *ctx) +{ + sslSocket *ss = ssl_FindSocket(fd); + + if (!ss) { + SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetResumptionTokenCallback", + SSL_GETPID(), fd)); + return SECFailure; + } + + ssl_Get1stHandshakeLock(ss); + ssl_GetSSL3HandshakeLock(ss); + ss->resumptionTokenCallback = cb; + ss->resumptionTokenContext = ctx; + ssl_ReleaseSSL3HandshakeLock(ss); + ssl_Release1stHandshakeLock(ss); + + return SECSuccess; +} + +SECStatus +SSLExp_SetResumptionToken(PRFileDesc *fd, const PRUint8 *token, + unsigned int len) +{ + sslSocket *ss = ssl_FindSocket(fd); + + if (!ss) { + SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetResumptionToken", + SSL_GETPID(), fd)); + return SECFailure; + } + + ssl_Get1stHandshakeLock(ss); + ssl_GetSSL3HandshakeLock(ss); + + if (ss->firstHsDone || ss->ssl3.hs.ws != idle_handshake || + ss->sec.isServer || len == 0 || !token) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + goto done; + } + + // We override any previously set session. + if (ss->sec.ci.sid) { + ssl_FreeSID(ss->sec.ci.sid); + ss->sec.ci.sid = NULL; + } + + PRINT_BUF(50, (ss, "incoming resumption token", token, len)); + + ss->sec.ci.sid = ssl3_NewSessionID(ss, PR_FALSE); + if (!ss->sec.ci.sid) { + goto done; + } + + /* Populate NewSessionTicket values */ + SECStatus rv = ssl_DecodeResumptionToken(ss->sec.ci.sid, token, len); + if (rv != SECSuccess) { + // If decoding fails, we assume the token is bad. + PORT_SetError(SSL_ERROR_BAD_RESUMPTION_TOKEN_ERROR); + ssl_FreeSID(ss->sec.ci.sid); + ss->sec.ci.sid = NULL; + goto done; + } + + // Make sure that the token is valid. + if (!ssl_IsResumptionTokenValid(ss)) { + ssl_FreeSID(ss->sec.ci.sid); + ss->sec.ci.sid = NULL; + PORT_SetError(SSL_ERROR_BAD_RESUMPTION_TOKEN_ERROR); + goto done; + } + + /* Use the sid->cached as marker that this is from an external cache and + * we don't have to look up anything in the NSS internal cache. */ + ss->sec.ci.sid->cached = in_external_cache; + // This has to be 2 to not free this in sendClientHello. + ss->sec.ci.sid->references = 2; + ss->sec.ci.sid->lastAccessTime = ssl_TimeSec(); + + ssl_ReleaseSSL3HandshakeLock(ss); + ssl_Release1stHandshakeLock(ss); + return SECSuccess; + +done: + ssl_ReleaseSSL3HandshakeLock(ss); + ssl_Release1stHandshakeLock(ss); + + return SECFailure; +} + +SECStatus +SSLExp_DestroyResumptionTokenInfo(SSLResumptionTokenInfo *token) +{ + if (!token) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + if (token->peerCert) { + CERT_DestroyCertificate(token->peerCert); + } + PORT_Free(token->alpnSelection); + PORT_Memset(token, 0, token->length); + return SECSuccess; +} + +SECStatus +SSLExp_GetResumptionTokenInfo(const PRUint8 *tokenData, unsigned int tokenLen, + SSLResumptionTokenInfo *tokenOut, PRUintn len) +{ + if (!tokenData || !tokenOut || !tokenLen || + len > sizeof(SSLResumptionTokenInfo)) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + sslSessionID sid = { 0 }; + SSLResumptionTokenInfo token; + + /* Populate sid values */ + if (ssl_DecodeResumptionToken(&sid, tokenData, tokenLen) != SECSuccess) { + // If decoding fails, we assume the token is bad. + PORT_SetError(SSL_ERROR_BAD_RESUMPTION_TOKEN_ERROR); + return SECFailure; + } + + token.peerCert = CERT_DupCertificate(sid.peerCert); + + token.alpnSelectionLen = sid.u.ssl3.alpnSelection.len; + token.alpnSelection = PORT_ZAlloc(token.alpnSelectionLen); + if (!token.alpnSelection) { + return SECFailure; + } + PORT_Memcpy(token.alpnSelection, sid.u.ssl3.alpnSelection.data, + token.alpnSelectionLen); + + if (sid.u.ssl3.locked.sessionTicket.flags & ticket_allow_early_data) { + token.maxEarlyDataSize = + sid.u.ssl3.locked.sessionTicket.max_early_data_size; + } else { + token.maxEarlyDataSize = 0; + } + + token.length = PR_MIN(sizeof(SSLResumptionTokenInfo), len); + PORT_Memcpy(tokenOut, &token, token.length); + + ssl_DestroySID(&sid, PR_FALSE); + return SECSuccess; +} diff --git a/security/nss/lib/ssl/sslspec.c b/security/nss/lib/ssl/sslspec.c new file mode 100644 index 000000000..26c3eb546 --- /dev/null +++ b/security/nss/lib/ssl/sslspec.c @@ -0,0 +1,273 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * Handling of cipher specs. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "ssl.h" +#include "sslproto.h" +#include "pk11func.h" +#include "secitem.h" + +#include "sslimpl.h" + +/* Record protection algorithms, indexed by SSL3BulkCipher. + * + * The |max_records| field (|mr| below) is set to a number that is higher than + * recommended in some literature (esp. TLS 1.3) because we currently abort the + * connection when this limit is reached and we want to ensure that we only + * rarely hit this limit. See bug 1268745 for details. + */ +#define MR_MAX RECORD_SEQ_MAX /* 2^48-1 */ +#define MR_128 (0x5aULL << 28) /* For AES and similar. */ +#define MR_LOW (1ULL << 20) /* For weak ciphers. */ +/* clang-format off */ +static const ssl3BulkCipherDef ssl_bulk_cipher_defs[] = { + /* |--------- Lengths ---------| */ + /* cipher calg : s : */ + /* : e b n */ + /* oid short_name mr : c l o */ + /* k r o t n */ + /* e e i c a c */ + /* y t type v k g e */ + {cipher_null, ssl_calg_null, 0, 0, type_stream, 0, 0, 0, 0, + SEC_OID_NULL_CIPHER, "NULL", MR_MAX}, + {cipher_rc4, ssl_calg_rc4, 16,16, type_stream, 0, 0, 0, 0, + SEC_OID_RC4, "RC4", MR_LOW}, + {cipher_des, ssl_calg_des, 8, 8, type_block, 8, 8, 0, 0, + SEC_OID_DES_CBC, "DES-CBC", MR_LOW}, + {cipher_3des, ssl_calg_3des, 24,24, type_block, 8, 8, 0, 0, + SEC_OID_DES_EDE3_CBC, "3DES-EDE-CBC", MR_LOW}, + {cipher_aes_128, ssl_calg_aes, 16,16, type_block, 16,16, 0, 0, + SEC_OID_AES_128_CBC, "AES-128", MR_128}, + {cipher_aes_256, ssl_calg_aes, 32,32, type_block, 16,16, 0, 0, + SEC_OID_AES_256_CBC, "AES-256", MR_128}, + {cipher_camellia_128, ssl_calg_camellia, 16,16, type_block, 16,16, 0, 0, + SEC_OID_CAMELLIA_128_CBC, "Camellia-128", MR_128}, + {cipher_camellia_256, ssl_calg_camellia, 32,32, type_block, 16,16, 0, 0, + SEC_OID_CAMELLIA_256_CBC, "Camellia-256", MR_128}, + {cipher_seed, ssl_calg_seed, 16,16, type_block, 16,16, 0, 0, + SEC_OID_SEED_CBC, "SEED-CBC", MR_128}, + {cipher_aes_128_gcm, ssl_calg_aes_gcm, 16,16, type_aead, 4, 0,16, 8, + SEC_OID_AES_128_GCM, "AES-128-GCM", MR_128}, + {cipher_aes_256_gcm, ssl_calg_aes_gcm, 32,32, type_aead, 4, 0,16, 8, + SEC_OID_AES_256_GCM, "AES-256-GCM", MR_128}, + {cipher_chacha20, ssl_calg_chacha20, 32,32, type_aead, 12, 0,16, 0, + SEC_OID_CHACHA20_POLY1305, "ChaCha20-Poly1305", MR_MAX}, + {cipher_missing, ssl_calg_null, 0, 0, type_stream, 0, 0, 0, 0, + SEC_OID_UNKNOWN, "missing", 0U}, +}; +/* clang-format on */ + +const ssl3BulkCipherDef * +ssl_GetBulkCipherDef(const ssl3CipherSuiteDef *suiteDef) +{ + SSL3BulkCipher bulkCipher = suiteDef->bulk_cipher_alg; + PORT_Assert(bulkCipher < PR_ARRAY_SIZE(ssl_bulk_cipher_defs)); + PORT_Assert(ssl_bulk_cipher_defs[bulkCipher].cipher == bulkCipher); + return &ssl_bulk_cipher_defs[bulkCipher]; +} + +/* indexed by SSL3MACAlgorithm */ +static const ssl3MACDef ssl_mac_defs[] = { + /* pad_size is only used for SSL 3.0 MAC. See RFC 6101 Sec. 5.2.3.1. */ + /* mac mmech pad_size mac_size */ + { ssl_mac_null, CKM_INVALID_MECHANISM, 0, 0, 0 }, + { ssl_mac_md5, CKM_SSL3_MD5_MAC, 48, MD5_LENGTH, SEC_OID_HMAC_MD5 }, + { ssl_mac_sha, CKM_SSL3_SHA1_MAC, 40, SHA1_LENGTH, SEC_OID_HMAC_SHA1 }, + { ssl_hmac_md5, CKM_MD5_HMAC, 0, MD5_LENGTH, SEC_OID_HMAC_MD5 }, + { ssl_hmac_sha, CKM_SHA_1_HMAC, 0, SHA1_LENGTH, SEC_OID_HMAC_SHA1 }, + { ssl_hmac_sha256, CKM_SHA256_HMAC, 0, SHA256_LENGTH, SEC_OID_HMAC_SHA256 }, + { ssl_mac_aead, CKM_INVALID_MECHANISM, 0, 0, 0 }, + { ssl_hmac_sha384, CKM_SHA384_HMAC, 0, SHA384_LENGTH, SEC_OID_HMAC_SHA384 } +}; + +const ssl3MACDef * +ssl_GetMacDefByAlg(SSL3MACAlgorithm mac) +{ + /* Cast here for clang: https://bugs.llvm.org/show_bug.cgi?id=16154 */ + PORT_Assert((size_t)mac < PR_ARRAY_SIZE(ssl_mac_defs)); + PORT_Assert(ssl_mac_defs[mac].mac == mac); + return &ssl_mac_defs[mac]; +} + +const ssl3MACDef * +ssl_GetMacDef(const sslSocket *ss, const ssl3CipherSuiteDef *suiteDef) +{ + SSL3MACAlgorithm mac = suiteDef->mac_alg; + if (ss->version > SSL_LIBRARY_VERSION_3_0) { + switch (mac) { + case ssl_mac_md5: + mac = ssl_hmac_md5; + break; + case ssl_mac_sha: + mac = ssl_hmac_sha; + break; + default: + break; + } + } + return ssl_GetMacDefByAlg(mac); +} + +ssl3CipherSpec * +ssl_FindCipherSpecByEpoch(sslSocket *ss, CipherSpecDirection direction, + DTLSEpoch epoch) +{ + PRCList *cur_p; + for (cur_p = PR_LIST_HEAD(&ss->ssl3.hs.cipherSpecs); + cur_p != &ss->ssl3.hs.cipherSpecs; + cur_p = PR_NEXT_LINK(cur_p)) { + ssl3CipherSpec *spec = (ssl3CipherSpec *)cur_p; + + if (spec->epoch != epoch) { + continue; + } + if (direction != spec->direction) { + continue; + } + return spec; + } + return NULL; +} + +ssl3CipherSpec * +ssl_CreateCipherSpec(sslSocket *ss, CipherSpecDirection direction) +{ + ssl3CipherSpec *spec = PORT_ZNew(ssl3CipherSpec); + if (!spec) { + return NULL; + } + spec->refCt = 1; + spec->version = ss->version; + spec->direction = direction; + SSL_TRC(10, ("%d: SSL[%d]: new %s spec %d ct=%d", + SSL_GETPID(), ss->fd, SPEC_DIR(spec), spec, + spec->refCt)); + return spec; +} + +void +ssl_SaveCipherSpec(sslSocket *ss, ssl3CipherSpec *spec) +{ + PR_APPEND_LINK(&spec->link, &ss->ssl3.hs.cipherSpecs); +} + +/* Called from ssl3_InitState. */ +/* Caller must hold the SpecWriteLock. */ +SECStatus +ssl_SetupNullCipherSpec(sslSocket *ss, CipherSpecDirection dir) +{ + ssl3CipherSpec *spec; + + PORT_Assert(ss->opt.noLocks || ssl_HaveSpecWriteLock(ss)); + + spec = ssl_CreateCipherSpec(ss, dir); + if (!spec) { + return SECFailure; + } + + /* Set default versions. This value will be used to generate and send + * alerts if a version is not negotiated. These values are overridden when + * sending a ClientHello and when a version is negotiated. */ + spec->version = SSL_LIBRARY_VERSION_TLS_1_0; + spec->recordVersion = IS_DTLS(ss) + ? SSL_LIBRARY_VERSION_DTLS_1_0_WIRE + : SSL_LIBRARY_VERSION_TLS_1_0; + spec->cipherDef = &ssl_bulk_cipher_defs[cipher_null]; + PORT_Assert(spec->cipherDef->cipher == cipher_null); + spec->macDef = &ssl_mac_defs[ssl_mac_null]; + PORT_Assert(spec->macDef->mac == ssl_mac_null); + spec->cipher = Null_Cipher; + + spec->phase = "cleartext"; + dtls_InitRecvdRecords(&spec->recvdRecords); + + ssl_SaveCipherSpec(ss, spec); + if (dir == CipherSpecRead) { + ss->ssl3.crSpec = spec; + } else { + ss->ssl3.cwSpec = spec; + } + return SECSuccess; +} + +void +ssl_CipherSpecAddRef(ssl3CipherSpec *spec) +{ + ++spec->refCt; + SSL_TRC(10, ("%d: SSL[-]: Increment ref ct for %s spec %d. new ct = %d", + SSL_GETPID(), SPEC_DIR(spec), spec, spec->refCt)); +} + +static void +ssl_DestroyKeyMaterial(ssl3KeyMaterial *keyMaterial) +{ + PK11_FreeSymKey(keyMaterial->key); + PK11_FreeSymKey(keyMaterial->macKey); + if (keyMaterial->macContext != NULL) { + PK11_DestroyContext(keyMaterial->macContext, PR_TRUE); + } +} + +static void +ssl_FreeCipherSpec(ssl3CipherSpec *spec) +{ + SSL_TRC(10, ("%d: SSL[-]: Freeing %s spec %d. epoch=%d", + SSL_GETPID(), SPEC_DIR(spec), spec, spec->epoch)); + + PR_REMOVE_LINK(&spec->link); + + /* PORT_Assert( ss->opt.noLocks || ssl_HaveSpecWriteLock(ss)); Don't have ss! */ + if (spec->cipherContext) { + PK11_DestroyContext(spec->cipherContext, PR_TRUE); + } + PK11_FreeSymKey(spec->masterSecret); + ssl_DestroyKeyMaterial(&spec->keyMaterial); + + PORT_ZFree(spec, sizeof(*spec)); +} + +/* This function is never called on a spec which is on the + * cipherSpecs list. */ +void +ssl_CipherSpecRelease(ssl3CipherSpec *spec) +{ + if (!spec) { + return; + } + + PORT_Assert(spec->refCt > 0); + --spec->refCt; + SSL_TRC(10, ("%d: SSL[-]: decrement refct for %s spec %d. epoch=%d new ct = %d", + SSL_GETPID(), SPEC_DIR(spec), spec, spec->epoch, spec->refCt)); + if (!spec->refCt) { + ssl_FreeCipherSpec(spec); + } +} + +void +ssl_DestroyCipherSpecs(PRCList *list) +{ + while (!PR_CLIST_IS_EMPTY(list)) { + ssl3CipherSpec *spec = (ssl3CipherSpec *)PR_LIST_TAIL(list); + ssl_FreeCipherSpec(spec); + } +} + +void +ssl_CipherSpecReleaseByEpoch(sslSocket *ss, CipherSpecDirection dir, + DTLSEpoch epoch) +{ + ssl3CipherSpec *spec; + SSL_TRC(10, ("%d: SSL[%d]: releasing %s cipher spec for epoch %d", + SSL_GETPID(), ss->fd, + (dir == CipherSpecRead) ? "read" : "write", epoch)); + + spec = ssl_FindCipherSpecByEpoch(ss, dir, epoch); + if (spec) { + ssl_CipherSpecRelease(spec); + } +} diff --git a/security/nss/lib/ssl/sslspec.h b/security/nss/lib/ssl/sslspec.h new file mode 100644 index 000000000..729ac1006 --- /dev/null +++ b/security/nss/lib/ssl/sslspec.h @@ -0,0 +1,194 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is PRIVATE to SSL. + * + * 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 __sslspec_h_ +#define __sslspec_h_ + +#include "sslexp.h" +#include "prclist.h" + +typedef enum { + TrafficKeyClearText = 0, + TrafficKeyEarlyApplicationData = 1, + TrafficKeyHandshake = 2, + TrafficKeyApplicationData = 3 +} TrafficKeyType; + +typedef enum { + CipherSpecRead, + CipherSpecWrite, +} CipherSpecDirection; + +#define SPEC_DIR(spec) \ + ((spec->direction == CipherSpecRead) ? "read" : "write") + +typedef struct ssl3CipherSpecStr ssl3CipherSpec; +typedef struct ssl3BulkCipherDefStr ssl3BulkCipherDef; +typedef struct ssl3MACDefStr ssl3MACDef; +typedef struct ssl3CipherSuiteDefStr ssl3CipherSuiteDef; +typedef PRUint64 sslSequenceNumber; +typedef PRUint16 DTLSEpoch; + +/* The SSL bulk cipher definition */ +typedef enum { + cipher_null, + cipher_rc4, + cipher_des, + cipher_3des, + cipher_aes_128, + cipher_aes_256, + cipher_camellia_128, + cipher_camellia_256, + cipher_seed, + cipher_aes_128_gcm, + cipher_aes_256_gcm, + cipher_chacha20, + cipher_missing /* reserved for no such supported cipher */ + /* This enum must match ssl3_cipherName[] in ssl3con.c. */ +} SSL3BulkCipher; + +typedef enum { + type_stream, + type_block, + type_aead +} CipherType; + +/* +** There are tables of these, all const. +*/ +struct ssl3BulkCipherDefStr { + SSL3BulkCipher cipher; + SSLCipherAlgorithm calg; + unsigned int key_size; + unsigned int secret_key_size; + CipherType type; + unsigned int iv_size; + unsigned int block_size; + unsigned int tag_size; /* for AEAD ciphers. */ + unsigned int explicit_nonce_size; /* for AEAD ciphers. */ + SECOidTag oid; + const char *short_name; + /* The maximum number of records that can be sent/received with the same + * symmetric key before the connection will be terminated. */ + PRUint64 max_records; +}; + +/* to make some of these old enums public without namespace pollution, +** it was necessary to prepend ssl_ to the names. +** These #defines preserve compatibility with the old code here in libssl. +*/ +typedef SSLMACAlgorithm SSL3MACAlgorithm; + +/* + * There are tables of these, all const. + */ +struct ssl3MACDefStr { + SSL3MACAlgorithm mac; + CK_MECHANISM_TYPE mmech; + int pad_size; + int mac_size; + SECOidTag oid; +}; + +#define MAX_IV_LENGTH 24 + +typedef struct { + PK11SymKey *key; + PK11SymKey *macKey; + PK11Context *macContext; + PRUint8 iv[MAX_IV_LENGTH]; +} ssl3KeyMaterial; + +typedef SECStatus (*SSLCipher)(void *context, + unsigned char *out, + int *outlen, + int maxout, + const unsigned char *in, + int inlen); +typedef SECStatus (*SSLAEADCipher)( + ssl3KeyMaterial *keys, + PRBool doDecrypt, + unsigned char *out, + int *outlen, + int maxout, + const unsigned char *in, + int inlen, + const unsigned char *additionalData, + int additionalDataLen); + +/* The DTLS anti-replay window in number of packets. Defined here because we + * need it in the cipher spec. Note that this is a ring buffer but left and + * right represent the true window, with modular arithmetic used to map them + * onto the buffer. + */ +#define DTLS_RECVD_RECORDS_WINDOW 1024 +#define RECORD_SEQ_MASK ((1ULL << 48) - 1) +#define RECORD_SEQ_MAX RECORD_SEQ_MASK +PR_STATIC_ASSERT(DTLS_RECVD_RECORDS_WINDOW % 8 == 0); + +typedef struct DTLSRecvdRecordsStr { + unsigned char data[DTLS_RECVD_RECORDS_WINDOW / 8]; + sslSequenceNumber left; + sslSequenceNumber right; +} DTLSRecvdRecords; + +/* + * These are the "specs" used for reading and writing records. Access to the + * pointers to these specs, and all the specs' contents (direct and indirect) is + * protected by the reader/writer lock ss->specLock. + */ +struct ssl3CipherSpecStr { + PRCList link; + PRUint8 refCt; + + CipherSpecDirection direction; + SSL3ProtocolVersion version; + SSL3ProtocolVersion recordVersion; + + const ssl3BulkCipherDef *cipherDef; + const ssl3MACDef *macDef; + + SSLCipher cipher; + SSLAEADCipher aead; + void *cipherContext; + + PK11SymKey *masterSecret; + ssl3KeyMaterial keyMaterial; + + DTLSEpoch epoch; + const char *phase; + sslSequenceNumber seqNum; + 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; +}; + +typedef void (*sslCipherSpecChangedFunc)(void *arg, + PRBool sending, + ssl3CipherSpec *newSpec); + +const ssl3BulkCipherDef *ssl_GetBulkCipherDef(const ssl3CipherSuiteDef *cipher_def); +const ssl3MACDef *ssl_GetMacDefByAlg(SSL3MACAlgorithm mac); +const ssl3MACDef *ssl_GetMacDef(const sslSocket *ss, const ssl3CipherSuiteDef *suiteDef); + +ssl3CipherSpec *ssl_CreateCipherSpec(sslSocket *ss, CipherSpecDirection direction); +void ssl_SaveCipherSpec(sslSocket *ss, ssl3CipherSpec *spec); +void ssl_CipherSpecAddRef(ssl3CipherSpec *spec); +void ssl_CipherSpecRelease(ssl3CipherSpec *spec); +void ssl_DestroyCipherSpecs(PRCList *list); +SECStatus ssl_SetupNullCipherSpec(sslSocket *ss, CipherSpecDirection dir); + +ssl3CipherSpec *ssl_FindCipherSpecByEpoch(sslSocket *ss, + CipherSpecDirection direction, + DTLSEpoch epoch); +void ssl_CipherSpecReleaseByEpoch(sslSocket *ss, CipherSpecDirection direction, + DTLSEpoch epoch); + +#endif /* __sslspec_h_ */ diff --git a/security/nss/lib/ssl/sslt.h b/security/nss/lib/ssl/sslt.h index bd9a2ae88..e2b80fb43 100644 --- a/security/nss/lib/ssl/sslt.h +++ b/security/nss/lib/ssl/sslt.h @@ -13,6 +13,28 @@ #include "secitem.h" #include "certt.h" +typedef enum { + ssl_hs_hello_request = 0, + ssl_hs_client_hello = 1, + ssl_hs_server_hello = 2, + ssl_hs_hello_verify_request = 3, + ssl_hs_new_session_ticket = 4, + ssl_hs_end_of_early_data = 5, + ssl_hs_hello_retry_request = 6, + ssl_hs_encrypted_extensions = 8, + ssl_hs_certificate = 11, + ssl_hs_server_key_exchange = 12, + ssl_hs_certificate_request = 13, + ssl_hs_server_hello_done = 14, + ssl_hs_certificate_verify = 15, + ssl_hs_client_key_exchange = 16, + ssl_hs_finished = 20, + ssl_hs_certificate_status = 22, + ssl_hs_key_update = 24, + ssl_hs_next_proto = 67, + ssl_hs_message_hash = 254, /* Not a real message. */ +} SSLHandshakeType; + typedef struct SSL3StatisticsStr { /* statistics from ssl3_SendClientHello (sch) */ long sch_sid_cache_hits; @@ -101,11 +123,14 @@ typedef enum { ssl_sig_ecdsa_secp256r1_sha256 = 0x0403, ssl_sig_ecdsa_secp384r1_sha384 = 0x0503, ssl_sig_ecdsa_secp521r1_sha512 = 0x0603, - ssl_sig_rsa_pss_sha256 = 0x0804, - ssl_sig_rsa_pss_sha384 = 0x0805, - ssl_sig_rsa_pss_sha512 = 0x0806, + ssl_sig_rsa_pss_rsae_sha256 = 0x0804, + ssl_sig_rsa_pss_rsae_sha384 = 0x0805, + ssl_sig_rsa_pss_rsae_sha512 = 0x0806, ssl_sig_ed25519 = 0x0807, ssl_sig_ed448 = 0x0808, + ssl_sig_rsa_pss_pss_sha256 = 0x0809, + ssl_sig_rsa_pss_pss_sha384 = 0x080a, + ssl_sig_rsa_pss_pss_sha512 = 0x080b, ssl_sig_dsa_sha1 = 0x0202, ssl_sig_dsa_sha256 = 0x0402, @@ -121,20 +146,25 @@ typedef enum { ssl_sig_rsa_pkcs1_sha1md5 = 0x10101, } SSLSignatureScheme; +/* Deprecated names maintained only for source compatibility. */ +#define ssl_sig_rsa_pss_sha256 ssl_sig_rsa_pss_rsae_sha256 +#define ssl_sig_rsa_pss_sha384 ssl_sig_rsa_pss_rsae_sha384 +#define ssl_sig_rsa_pss_sha512 ssl_sig_rsa_pss_rsae_sha512 + /* ** SSLAuthType describes the type of key that is used to authenticate a ** connection. That is, the type of key in the end-entity certificate. */ typedef enum { ssl_auth_null = 0, - ssl_auth_rsa_decrypt = 1, /* static RSA */ + ssl_auth_rsa_decrypt = 1, /* RSA key exchange. */ ssl_auth_dsa = 2, ssl_auth_kea = 3, /* unused */ ssl_auth_ecdsa = 4, - ssl_auth_ecdh_rsa = 5, /* ECDH cert with an RSA signature */ - ssl_auth_ecdh_ecdsa = 6, /* ECDH cert with an ECDSA signature */ - ssl_auth_rsa_sign = 7, /* RSA PKCS#1.5 signing */ - ssl_auth_rsa_pss = 8, + ssl_auth_ecdh_rsa = 5, /* ECDH cert with an RSA signature. */ + ssl_auth_ecdh_ecdsa = 6, /* ECDH cert with an ECDSA signature. */ + ssl_auth_rsa_sign = 7, /* RSA signing with an rsaEncryption key. */ + ssl_auth_rsa_pss = 8, /* RSA signing with a PSS key. */ ssl_auth_psk = 9, ssl_auth_tls13_any = 10, ssl_auth_size /* number of authentication types */ @@ -275,6 +305,14 @@ typedef struct SSLChannelInfoStr { SSLAuthType authType; SSLSignatureScheme signatureScheme; + /* The following fields were added in NSS 3.34. */ + /* When the session was resumed this holds the key exchange group of the + * original handshake. */ + SSLNamedGroup originalKeaGroup; + /* This field is PR_TRUE when the session is resumed and PR_FALSE + * otherwise. */ + PRBool resumed; + /* When adding new fields to this structure, please document the * NSS version in which they were added. */ } SSLChannelInfo; @@ -395,16 +433,19 @@ typedef enum { ssl_padding_xtn = 21, ssl_extended_master_secret_xtn = 23, ssl_session_ticket_xtn = 35, - ssl_tls13_key_share_xtn = 40, + /* 40 was used in draft versions of TLS 1.3; it is now reserved. */ ssl_tls13_pre_shared_key_xtn = 41, ssl_tls13_early_data_xtn = 42, ssl_tls13_supported_versions_xtn = 43, ssl_tls13_cookie_xtn = 44, ssl_tls13_psk_key_exchange_modes_xtn = 45, - ssl_tls13_ticket_early_data_info_xtn = 46, - ssl_next_proto_nego_xtn = 13172, + ssl_tls13_ticket_early_data_info_xtn = 46, /* Deprecated. */ + ssl_tls13_certificate_authorities_xtn = 47, + ssl_signature_algorithms_cert_xtn = 50, + ssl_tls13_key_share_xtn = 51, + ssl_next_proto_nego_xtn = 13172, /* Deprecated. */ ssl_renegotiation_info_xtn = 0xff01, - ssl_tls13_short_header_xtn = 0xff03 + ssl_tls13_short_header_xtn = 0xff03 /* Deprecated. */ } SSLExtensionType; /* This is the old name for the supported_groups extensions. */ diff --git a/security/nss/lib/ssl/tls13con.c b/security/nss/lib/ssl/tls13con.c index 560493848..c06acc83a 100644 --- a/security/nss/lib/ssl/tls13con.c +++ b/security/nss/lib/ssl/tls13con.c @@ -17,23 +17,14 @@ #include "sslimpl.h" #include "sslproto.h" #include "sslerr.h" +#include "ssl3exthandle.h" #include "tls13hkdf.h" #include "tls13con.h" +#include "tls13err.h" #include "tls13exthandle.h" +#include "tls13hashstate.h" -typedef enum { - TrafficKeyClearText = 0, - TrafficKeyEarlyApplicationData = 1, - TrafficKeyHandshake = 2, - TrafficKeyApplicationData = 3 -} TrafficKeyType; - -typedef enum { - CipherSpecRead, - CipherSpecWrite, -} CipherSpecDirection; - -static SECStatus tls13_SetCipherSpec(sslSocket *ss, TrafficKeyType type, +static SECStatus tls13_SetCipherSpec(sslSocket *ss, PRUint16 epoch, CipherSpecDirection install, PRBool deleteSecret); static SECStatus tls13_AESGCM( @@ -53,8 +44,9 @@ static SECStatus tls13_SendEncryptedExtensions(sslSocket *ss); static void tls13_SetKeyExchangeType(sslSocket *ss, const sslNamedGroupDef *group); static SECStatus tls13_HandleClientKeyShare(sslSocket *ss, TLS13KeyShareEntry *peerShare); -static SECStatus tls13_SendHelloRetryRequest(sslSocket *ss, - const sslNamedGroupDef *selectedGroup); +static SECStatus tls13_SendHelloRetryRequest( + sslSocket *ss, const sslNamedGroupDef *selectedGroup, + const PRUint8 *token, unsigned int tokenLen); static SECStatus tls13_HandleServerKeyShare(sslSocket *ss); static SECStatus tls13_HandleEncryptedExtensions(sslSocket *ss, PRUint8 *b, @@ -62,40 +54,46 @@ static SECStatus tls13_HandleEncryptedExtensions(sslSocket *ss, PRUint8 *b, static SECStatus tls13_SendCertificate(sslSocket *ss); static SECStatus tls13_HandleCertificate( sslSocket *ss, PRUint8 *b, PRUint32 length); +static SECStatus tls13_ReinjectHandshakeTranscript(sslSocket *ss); static SECStatus tls13_HandleCertificateRequest(sslSocket *ss, PRUint8 *b, PRUint32 length); static SECStatus tls13_SendCertificateVerify(sslSocket *ss, SECKEYPrivateKey *privKey); static SECStatus tls13_HandleCertificateVerify( - sslSocket *ss, PRUint8 *b, PRUint32 length, - SSL3Hashes *hashes); + sslSocket *ss, PRUint8 *b, PRUint32 length); static SECStatus tls13_RecoverWrappedSharedSecret(sslSocket *ss, sslSessionID *sid); static SECStatus +tls13_DeriveSecretWrap(sslSocket *ss, PK11SymKey *key, + const char *prefix, + const char *suffix, + const char *keylogLabel, + PK11SymKey **dest); +static SECStatus tls13_DeriveSecret(sslSocket *ss, PK11SymKey *key, - const char *prefix, - const char *suffix, + const char *label, + unsigned int labelLen, const SSL3Hashes *hashes, PK11SymKey **dest); static SECStatus tls13_SendEndOfEarlyData(sslSocket *ss); +static SECStatus tls13_HandleEndOfEarlyData(sslSocket *ss, PRUint8 *b, + PRUint32 length); static SECStatus tls13_SendFinished(sslSocket *ss, PK11SymKey *baseKey); -static SECStatus tls13_ComputePskBinderHash(sslSocket *ss, - unsigned long prefixLength, +static SECStatus tls13_ComputePskBinderHash(sslSocket *ss, unsigned int prefix, SSL3Hashes *hashes); -static SECStatus tls13_VerifyFinished(sslSocket *ss, SSL3HandshakeType message, +static SECStatus tls13_VerifyFinished(sslSocket *ss, SSLHandshakeType message, PK11SymKey *secret, PRUint8 *b, PRUint32 length, const SSL3Hashes *hashes); static SECStatus tls13_ClientHandleFinished(sslSocket *ss, - PRUint8 *b, PRUint32 length, - const SSL3Hashes *hashes); + PRUint8 *b, PRUint32 length); static SECStatus tls13_ServerHandleFinished(sslSocket *ss, - PRUint8 *b, PRUint32 length, - const SSL3Hashes *hashes); + PRUint8 *b, PRUint32 length); +static SECStatus tls13_SendNewSessionTicket(sslSocket *ss, + const PRUint8 *appToken, + unsigned int appTokenLen); static SECStatus tls13_HandleNewSessionTicket(sslSocket *ss, PRUint8 *b, PRUint32 length); -static SECStatus tls13_ComputeHandshakeHashes(sslSocket *ss, - SSL3Hashes *hashes); static SECStatus tls13_ComputeEarlySecrets(sslSocket *ss); static SECStatus tls13_ComputeHandshakeSecrets(sslSocket *ss); static SECStatus tls13_ComputeApplicationSecrets(sslSocket *ss); @@ -107,26 +105,28 @@ static SECStatus tls13_ComputeFinished( static SECStatus tls13_SendClientSecondRound(sslSocket *ss); static SECStatus tls13_FinishHandshake(sslSocket *ss); -const char kHkdfLabelClient[] = "client"; -const char kHkdfLabelServer[] = "server"; -const char kHkdfLabelPskBinderKey[] = "resumption psk binder key"; -const char kHkdfLabelEarlyTrafficSecret[] = "early traffic secret"; -const char kHkdfLabelEarlyExporterSecret[] = "early exporter master secret"; -const char kHkdfLabelHandshakeTrafficSecret[] = "handshake traffic secret"; -const char kHkdfLabelApplicationTrafficSecret[] = "application traffic secret"; +const char kHkdfLabelClient[] = "c"; +const char kHkdfLabelServer[] = "s"; +const char kHkdfLabelDerivedSecret[] = "derived"; +const char kHkdfLabelPskBinderKey[] = "res binder"; +const char kHkdfLabelEarlyTrafficSecret[] = "e traffic"; +const char kHkdfLabelEarlyExporterSecret[] = "e exp master"; +const char kHkdfLabelHandshakeTrafficSecret[] = "hs traffic"; +const char kHkdfLabelApplicationTrafficSecret[] = "ap traffic"; const char kHkdfLabelFinishedSecret[] = "finished"; -const char kHkdfLabelResumptionMasterSecret[] = "resumption master secret"; -const char kHkdfLabelExporterMasterSecret[] = "exporter master secret"; +const char kHkdfLabelResumptionMasterSecret[] = "res master"; +const char kHkdfLabelExporterMasterSecret[] = "exp master"; +const char kHkdfLabelResumption[] = "resumption"; const char kHkdfPurposeKey[] = "key"; const char kHkdfPurposeIv[] = "iv"; -#define TRAFFIC_SECRET(ss, dir, name) ((ss->sec.isServer ^ \ - (dir == CipherSpecWrite)) \ - ? ss->ssl3.hs.client##name \ - : ss->ssl3.hs.server##name) - -const SSL3ProtocolVersion kTlsRecordVersion = SSL_LIBRARY_VERSION_TLS_1_0; -const SSL3ProtocolVersion kDtlsRecordVersion = SSL_LIBRARY_VERSION_TLS_1_1; +const char keylogLabelClientEarlyTrafficSecret[] = "CLIENT_EARLY_TRAFFIC_SECRET"; +const char keylogLabelClientHsTrafficSecret[] = "CLIENT_HANDSHAKE_TRAFFIC_SECRET"; +const char keylogLabelServerHsTrafficSecret[] = "SERVER_HANDSHAKE_TRAFFIC_SECRET"; +const char keylogLabelClientTrafficSecret[] = "CLIENT_TRAFFIC_SECRET_0"; +const char keylogLabelServerTrafficSecret[] = "SERVER_TRAFFIC_SECRET_0"; +const char keylogLabelEarlyExporterSecret[] = "EARLY_EXPORTER_SECRET"; +const char keylogLabelExporterSecret[] = "EXPORTER_SECRET"; /* Belt and suspenders in case we ever add a TLS 1.4. */ PR_STATIC_ASSERT(SSL_LIBRARY_VERSION_MAX_SUPPORTED <= @@ -165,6 +165,7 @@ tls13_HandshakeState(SSL3WaitState st) switch (st) { STATE_CASE(idle_handshake); STATE_CASE(wait_client_hello); + STATE_CASE(wait_end_of_early_data); STATE_CASE(wait_client_cert); STATE_CASE(wait_client_key); STATE_CASE(wait_cert_verify); @@ -336,6 +337,23 @@ tls13_GetHmacMechanism(sslSocket *ss) } SECStatus +tls13_ComputeHash(sslSocket *ss, SSL3Hashes *hashes, + const PRUint8 *buf, unsigned int len) +{ + SECStatus rv; + + rv = PK11_HashBuf(ssl3_HashTypeToOID(tls13_GetHash(ss)), + hashes->u.raw, buf, len); + if (rv != SECSuccess) { + FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error); + return SECFailure; + } + hashes->len = tls13_GetHashSize(ss); + + return SECSuccess; +} + +SECStatus tls13_CreateKeyShare(sslSocket *ss, const sslNamedGroupDef *groupDef) { SECStatus rv; @@ -444,13 +462,14 @@ tls13_SetupClientHello(sslSocket *ss) if (rv != SECSuccess) { FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error); SSL_AtomicIncrementLong(&ssl3stats->sch_sid_cache_not_ok); - ss->sec.uncache(ss->sec.ci.sid); + ssl_UncacheSessionID(ss); ssl_FreeSID(ss->sec.ci.sid); ss->sec.ci.sid = NULL; return SECFailure; } - rv = ssl3_SetCipherSuite(ss, ss->sec.ci.sid->u.ssl3.cipherSuite, PR_FALSE); + ss->ssl3.hs.cipher_suite = ss->sec.ci.sid->u.ssl3.cipherSuite; + rv = ssl3_SetupCipherSuite(ss, PR_FALSE); if (rv != SECSuccess) { FATAL_ERROR(ss, PORT_GetError(), internal_error); return SECFailure; @@ -558,9 +577,241 @@ loser: return SECFailure; } +static PRBool +tls13_UseServerSecret(sslSocket *ss, CipherSpecDirection direction) +{ + return ss->sec.isServer == (direction == CipherSpecWrite); +} + +static PK11SymKey ** +tls13_TrafficSecretRef(sslSocket *ss, CipherSpecDirection direction) +{ + if (tls13_UseServerSecret(ss, direction)) { + return &ss->ssl3.hs.serverTrafficSecret; + } + return &ss->ssl3.hs.clientTrafficSecret; +} + +SECStatus +tls13_UpdateTrafficKeys(sslSocket *ss, CipherSpecDirection direction) +{ + PK11SymKey **secret; + PK11SymKey *updatedSecret; + PRUint16 epoch; + SECStatus rv; + + secret = tls13_TrafficSecretRef(ss, direction); + rv = tls13_HkdfExpandLabel(*secret, tls13_GetHash(ss), + NULL, 0, + kHkdfLabelApplicationTrafficSecret, + strlen(kHkdfLabelApplicationTrafficSecret), + tls13_GetHmacMechanism(ss), + tls13_GetHashSize(ss), + &updatedSecret); + if (rv != SECSuccess) { + return SECFailure; + } + + PK11_FreeSymKey(*secret); + *secret = updatedSecret; + + ssl_GetSpecReadLock(ss); + if (direction == CipherSpecRead) { + epoch = ss->ssl3.crSpec->epoch; + } else { + epoch = ss->ssl3.cwSpec->epoch; + } + ssl_ReleaseSpecReadLock(ss); + + if (epoch == PR_UINT16_MAX) { + /* Good chance that this is an overflow from too many updates. */ + FATAL_ERROR(ss, SSL_ERROR_TOO_MANY_KEY_UPDATES, internal_error); + return SECFailure; + } + ++epoch; + + rv = tls13_SetCipherSpec(ss, epoch, direction, PR_FALSE); + if (rv != SECSuccess) { + FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error); + return SECFailure; + } + + return SECSuccess; +} + +SECStatus +tls13_SendKeyUpdate(sslSocket *ss, tls13KeyUpdateRequest request, PRBool buffer) +{ + SECStatus rv; + + SSL_TRC(3, ("%d: TLS13[%d]: %s send key update, response %s", + SSL_GETPID(), ss->fd, SSL_ROLE(ss), + (request == update_requested) ? "requested" + : "not requested")); + + PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); + + if (!ss->firstHsDone) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + + rv = TLS13_CHECK_HS_STATE(ss, SEC_ERROR_LIBRARY_FAILURE, + idle_handshake); + if (rv != SECSuccess) { + return SECFailure; + } + + /* Not supported. */ + if (IS_DTLS(ss)) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + + ssl_GetXmitBufLock(ss); + rv = ssl3_AppendHandshakeHeader(ss, ssl_hs_key_update, 1); + if (rv != SECSuccess) { + FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error); + goto loser; + } + rv = ssl3_AppendHandshakeNumber(ss, request, 1); + if (rv != SECSuccess) { + FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error); + goto loser; + } + + /* If we have been asked to buffer, then do so. This allows us to coalesce + * a KeyUpdate with a pending write. */ + rv = ssl3_FlushHandshake(ss, buffer ? ssl_SEND_FLAG_FORCE_INTO_BUFFER : 0); + if (rv != SECSuccess) { + goto loser; /* error code set by ssl3_FlushHandshake */ + } + ssl_ReleaseXmitBufLock(ss); + + rv = tls13_UpdateTrafficKeys(ss, CipherSpecWrite); + if (rv != SECSuccess) { + goto loser; /* error code set by tls13_UpdateTrafficKeys */ + } + + return SECSuccess; + +loser: + ssl_ReleaseXmitBufLock(ss); + return SECFailure; +} + +SECStatus +SSLExp_KeyUpdate(PRFileDesc *fd, PRBool requestUpdate) +{ + SECStatus rv; + sslSocket *ss = ssl_FindSocket(fd); + if (!ss) { + return SECFailure; + } + + if (!ss->firstHsDone) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + + rv = TLS13_CHECK_HS_STATE(ss, SEC_ERROR_INVALID_ARGS, + idle_handshake); + if (rv != SECSuccess) { + return SECFailure; + } + + ssl_GetSSL3HandshakeLock(ss); + rv = tls13_SendKeyUpdate(ss, requestUpdate ? update_requested : update_not_requested, + PR_FALSE /* don't buffer */); + + /* Remember that we are the ones that initiated this KeyUpdate. */ + if (rv == SECSuccess) { + ss->ssl3.peerRequestedKeyUpdate = PR_FALSE; + } + ssl_ReleaseSSL3HandshakeLock(ss); + return rv; +} + +/* + * enum { + * update_not_requested(0), update_requested(1), (255) + * } KeyUpdateRequest; + * + * struct { + * KeyUpdateRequest request_update; + * } KeyUpdate; + */ +static SECStatus +tls13_HandleKeyUpdate(sslSocket *ss, PRUint8 *b, unsigned int length) +{ + SECStatus rv; + PRUint32 update; + + SSL_TRC(3, ("%d: TLS13[%d]: %s handle key update", + SSL_GETPID(), ss->fd, SSL_ROLE(ss))); + + PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss)); + PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); + + PORT_Assert(ss->firstHsDone); + if (!ss->firstHsDone) { + FATAL_ERROR(ss, SSL_ERROR_RX_UNEXPECTED_KEY_UPDATE, unexpected_message); + return SECFailure; + } + + rv = TLS13_CHECK_HS_STATE(ss, SSL_ERROR_RX_UNEXPECTED_KEY_UPDATE, + idle_handshake); + if (rv != SECSuccess) { + /* We should never be idle_handshake prior to firstHsDone. */ + FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error); + return SECFailure; + } + + rv = ssl3_ConsumeHandshakeNumber(ss, &update, 1, &b, &length); + if (rv != SECSuccess) { + return SECFailure; /* Error code set already. */ + } + if (length != 0) { + FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_KEY_UPDATE, decode_error); + return SECFailure; + } + if (!(update == update_requested || + update == update_not_requested)) { + FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_KEY_UPDATE, decode_error); + return SECFailure; + } + + rv = tls13_UpdateTrafficKeys(ss, CipherSpecRead); + if (rv != SECSuccess) { + return SECFailure; /* Error code set by tls13_UpdateTrafficKeys. */ + } + + if (update == update_requested) { + PRBool sendUpdate; + if (ss->ssl3.peerRequestedKeyUpdate) { + /* 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; + ssl_ReleaseSpecReadLock(ss); + } else { + sendUpdate = PR_TRUE; + } + if (sendUpdate) { + /* Respond immediately (don't buffer). */ + rv = tls13_SendKeyUpdate(ss, update_not_requested, PR_FALSE); + if (rv != SECSuccess) { + return SECFailure; /* Error already set. */ + } + } + ss->ssl3.peerRequestedKeyUpdate = PR_TRUE; + } + + return SECSuccess; +} + SECStatus -tls13_HandlePostHelloHandshakeMessage(sslSocket *ss, PRUint8 *b, - PRUint32 length, SSL3Hashes *hashesPtr) +tls13_HandlePostHelloHandshakeMessage(sslSocket *ss, PRUint8 *b, PRUint32 length) { if (ss->sec.isServer && ss->ssl3.hs.zeroRttIgnore != ssl_0rtt_ignore_none) { SSL_TRC(3, ("%d: TLS13[%d]: %s successfully decrypted handshake after" @@ -571,36 +822,34 @@ tls13_HandlePostHelloHandshakeMessage(sslSocket *ss, PRUint8 *b, /* TODO(ekr@rtfm.com): Would it be better to check all the states here? */ switch (ss->ssl3.hs.msg_type) { - case certificate: + case ssl_hs_certificate: return tls13_HandleCertificate(ss, b, length); - case certificate_request: + case ssl_hs_certificate_request: return tls13_HandleCertificateRequest(ss, b, length); - case certificate_verify: - if (!hashesPtr) { - FATAL_ERROR(ss, SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY, unexpected_message); - return SECFailure; - } - return tls13_HandleCertificateVerify(ss, b, length, hashesPtr); + case ssl_hs_certificate_verify: + return tls13_HandleCertificateVerify(ss, b, length); - case encrypted_extensions: + case ssl_hs_encrypted_extensions: return tls13_HandleEncryptedExtensions(ss, b, length); - case new_session_ticket: + case ssl_hs_new_session_ticket: return tls13_HandleNewSessionTicket(ss, b, length); - case finished: - if (!hashesPtr) { - FATAL_ERROR(ss, SSL_ERROR_RX_UNEXPECTED_FINISHED, unexpected_message); - return SECFailure; - } + case ssl_hs_finished: if (ss->sec.isServer) { - return tls13_ServerHandleFinished(ss, b, length, hashesPtr); + return tls13_ServerHandleFinished(ss, b, length); } else { - return tls13_ClientHandleFinished(ss, b, length, hashesPtr); + return tls13_ClientHandleFinished(ss, b, length); } + case ssl_hs_end_of_early_data: + return tls13_HandleEndOfEarlyData(ss, b, length); + + case ssl_hs_key_update: + return tls13_HandleKeyUpdate(ss, b, length); + default: FATAL_ERROR(ss, SSL_ERROR_RX_UNKNOWN_HANDSHAKE, unexpected_message); return SECFailure; @@ -619,10 +868,6 @@ tls13_RecoverWrappedSharedSecret(sslSocket *ss, sslSessionID *sid) SSL_TRC(3, ("%d: TLS13[%d]: recovering static secret (%s)", SSL_GETPID(), ss->fd, SSL_ROLE(ss))); - if (!sid->u.ssl3.keys.msIsWrapped) { - PORT_Assert(0); /* I think this can't happen. */ - return SECFailure; - } /* Now find the hash used as the PRF for the previous handshake. */ hashType = tls13_GetHashForCipherSuite(sid->u.ssl3.cipherSuite); @@ -673,53 +918,55 @@ tls13_RecoverWrappedSharedSecret(sslSocket *ss, sslSessionID *sid) /* Key Derivation Functions. * - * Below is the key schedule from [draft-ietf-tls-tls13]. - * - * * The relevant functions from this file are indicated by tls13_Foo(). * 0 * | * v - * PSK -> HKDF-Extract + * PSK -> HKDF-Extract = Early Secret * | - * v - * Early Secret ---> Derive-Secret(., "client early traffic secret", - * | ClientHello) - * | = client_early_traffic_secret - * v - * (EC)DHE -> HKDF-Extract + * +-----> Derive-Secret(., "ext binder" | "res binder", "") + * | = binder_key + * | + * +-----> Derive-Secret(., "c e traffic", + * | ClientHello) + * | = client_early_traffic_secret * | + * +-----> Derive-Secret(., "e exp master", + * | ClientHello) + * | = early_exporter_secret * v - * Handshake Secret + * Derive-Secret(., "derived", "") * | - * +---------> Derive-Secret(., "client handshake traffic secret", - * | ClientHello...ServerHello) - * | = client_handshake_traffic_secret + * v + *(EC)DHE -> HKDF-Extract = Handshake Secret * | - * +---------> Derive-Secret(., "server handshake traffic secret", - * | ClientHello...ServerHello) - * | = server_handshake_traffic_secret + * +-----> Derive-Secret(., "c hs traffic", + * | ClientHello...ServerHello) + * | = client_handshake_traffic_secret * | + * +-----> Derive-Secret(., "s hs traffic", + * | ClientHello...ServerHello) + * | = server_handshake_traffic_secret * v - * 0 -> HKDF-Extract + * Derive-Secret(., "derived", "") * | * v - * Master Secret + * 0 -> HKDF-Extract = Master Secret * | - * +---------> Derive-Secret(., "client application traffic secret", - * | ClientHello...Server Finished) - * | = client_traffic_secret_0 + * +-----> Derive-Secret(., "c ap traffic", + * | ClientHello...Server Finished) + * | = client_traffic_secret_0 * | - * +---------> Derive-Secret(., "server application traffic secret", - * | ClientHello...Server Finished) - * | = server_traffic_secret_0 + * +-----> Derive-Secret(., "s ap traffic", + * | ClientHello...Server Finished) + * | = server_traffic_secret_0 * | - * +---------> Derive-Secret(., "exporter master secret", - * | ClientHello...Client Finished) - * | = exporter_secret + * +-----> Derive-Secret(., "exp master", + * | ClientHello...Server Finished) + * | = exporter_secret * | - * +---------> Derive-Secret(., "resumption master secret", - * ClientHello...Client Finished) - * = resumption_secret + * +-----> Derive-Secret(., "res master", + * ClientHello...Client Finished) + * = resumption_master_secret * */ @@ -742,35 +989,43 @@ tls13_ComputeEarlySecrets(sslSocket *ss) PORT_Assert(ss->statelessResume == (ss->ssl3.hs.resumptionMasterSecret != NULL)); if (ss->statelessResume) { - PRUint8 buf[1] = { 0 }; - SSL3Hashes hashes; - PK11_FreeSymKey(ss->ssl3.hs.resumptionMasterSecret); ss->ssl3.hs.resumptionMasterSecret = NULL; - rv = PK11_HashBuf(ssl3_HashTypeToOID(tls13_GetHash(ss)), - hashes.u.raw, buf, 0); + rv = tls13_DeriveSecretNullHash(ss, ss->ssl3.hs.currentSecret, + kHkdfLabelPskBinderKey, + strlen(kHkdfLabelPskBinderKey), + &ss->ssl3.hs.pskBinderKey); if (rv != SECSuccess) { - FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error); return SECFailure; } - hashes.len = tls13_GetHashSize(ss); + } + PORT_Assert(!ss->ssl3.hs.resumptionMasterSecret); - rv = tls13_DeriveSecret(ss, ss->ssl3.hs.currentSecret, - NULL, kHkdfLabelPskBinderKey, &hashes, - &ss->ssl3.hs.pskBinderKey); - if (rv != SECSuccess) { - return SECFailure; - } + return SECSuccess; +} + +/* This derives the early traffic and early exporter secrets. */ +static SECStatus +tls13_DeriveEarlySecrets(sslSocket *ss) +{ + SECStatus rv; + + rv = tls13_DeriveSecretWrap(ss, ss->ssl3.hs.currentSecret, + kHkdfLabelClient, + kHkdfLabelEarlyTrafficSecret, + keylogLabelClientEarlyTrafficSecret, + &ss->ssl3.hs.clientEarlyTrafficSecret); + if (rv != SECSuccess) { + return SECFailure; + } - rv = tls13_DeriveSecret(ss, ss->ssl3.hs.currentSecret, + rv = tls13_DeriveSecretWrap(ss, ss->ssl3.hs.currentSecret, NULL, kHkdfLabelEarlyExporterSecret, - &hashes, &ss->ssl3.hs.earlyExporterSecret); - if (rv != SECSuccess) { - return SECFailure; - } - } else { - PORT_Assert(!ss->ssl3.hs.resumptionMasterSecret); + keylogLabelEarlyExporterSecret, + &ss->ssl3.hs.earlyExporterSecret); + if (rv != SECSuccess) { + return SECFailure; } return SECSuccess; @@ -780,6 +1035,7 @@ static SECStatus tls13_ComputeHandshakeSecrets(sslSocket *ss) { SECStatus rv; + PK11SymKey *derivedSecret = NULL; PK11SymKey *newSecret = NULL; SSL_TRC(5, ("%d: TLS13[%d]: compute handshake secrets (%s)", @@ -788,8 +1044,21 @@ tls13_ComputeHandshakeSecrets(sslSocket *ss) /* First update |currentSecret| to add |dheSecret|, if any. */ PORT_Assert(ss->ssl3.hs.currentSecret); PORT_Assert(ss->ssl3.hs.dheSecret); - rv = tls13_HkdfExtract(ss->ssl3.hs.currentSecret, ss->ssl3.hs.dheSecret, + + /* Expand before we extract. */ + rv = tls13_DeriveSecretNullHash(ss, ss->ssl3.hs.currentSecret, + kHkdfLabelDerivedSecret, + strlen(kHkdfLabelDerivedSecret), + &derivedSecret); + if (rv != SECSuccess) { + LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE); + return rv; + } + + rv = tls13_HkdfExtract(derivedSecret, ss->ssl3.hs.dheSecret, tls13_GetHash(ss), &newSecret); + PK11_FreeSymKey(derivedSecret); + if (rv != SECSuccess) { LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE); return rv; @@ -800,18 +1069,20 @@ tls13_ComputeHandshakeSecrets(sslSocket *ss) ss->ssl3.hs.currentSecret = newSecret; /* Now compute |*HsTrafficSecret| */ - rv = tls13_DeriveSecret(ss, ss->ssl3.hs.currentSecret, - kHkdfLabelClient, - kHkdfLabelHandshakeTrafficSecret, NULL, - &ss->ssl3.hs.clientHsTrafficSecret); + rv = tls13_DeriveSecretWrap(ss, ss->ssl3.hs.currentSecret, + kHkdfLabelClient, + kHkdfLabelHandshakeTrafficSecret, + keylogLabelClientHsTrafficSecret, + &ss->ssl3.hs.clientHsTrafficSecret); if (rv != SECSuccess) { LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE); return rv; } - rv = tls13_DeriveSecret(ss, ss->ssl3.hs.currentSecret, - kHkdfLabelServer, - kHkdfLabelHandshakeTrafficSecret, NULL, - &ss->ssl3.hs.serverHsTrafficSecret); + rv = tls13_DeriveSecretWrap(ss, ss->ssl3.hs.currentSecret, + kHkdfLabelServer, + kHkdfLabelHandshakeTrafficSecret, + keylogLabelServerHsTrafficSecret, + &ss->ssl3.hs.serverHsTrafficSecret); if (rv != SECSuccess) { LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE); return rv; @@ -822,11 +1093,19 @@ tls13_ComputeHandshakeSecrets(sslSocket *ss) /* Crank HKDF forward to make master secret, which we * stuff in current secret. */ - rv = tls13_HkdfExtract(ss->ssl3.hs.currentSecret, + rv = tls13_DeriveSecretNullHash(ss, ss->ssl3.hs.currentSecret, + kHkdfLabelDerivedSecret, + strlen(kHkdfLabelDerivedSecret), + &derivedSecret); + if (rv != SECSuccess) { + LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE); + return rv; + } + rv = tls13_HkdfExtract(derivedSecret, NULL, tls13_GetHash(ss), &newSecret); - + PK11_FreeSymKey(derivedSecret); if (rv != SECSuccess) { LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE); return SECFailure; @@ -842,26 +1121,27 @@ tls13_ComputeApplicationSecrets(sslSocket *ss) { SECStatus rv; - rv = tls13_DeriveSecret(ss, ss->ssl3.hs.currentSecret, - kHkdfLabelClient, - kHkdfLabelApplicationTrafficSecret, - NULL, - &ss->ssl3.hs.clientTrafficSecret); + rv = tls13_DeriveSecretWrap(ss, ss->ssl3.hs.currentSecret, + kHkdfLabelClient, + kHkdfLabelApplicationTrafficSecret, + keylogLabelClientTrafficSecret, + &ss->ssl3.hs.clientTrafficSecret); if (rv != SECSuccess) { return SECFailure; } - rv = tls13_DeriveSecret(ss, ss->ssl3.hs.currentSecret, - kHkdfLabelServer, - kHkdfLabelApplicationTrafficSecret, - NULL, - &ss->ssl3.hs.serverTrafficSecret); + rv = tls13_DeriveSecretWrap(ss, ss->ssl3.hs.currentSecret, + kHkdfLabelServer, + kHkdfLabelApplicationTrafficSecret, + keylogLabelServerTrafficSecret, + &ss->ssl3.hs.serverTrafficSecret); if (rv != SECSuccess) { return SECFailure; } - rv = tls13_DeriveSecret(ss, ss->ssl3.hs.currentSecret, - NULL, kHkdfLabelExporterMasterSecret, - NULL, &ss->ssl3.hs.exporterSecret); + rv = tls13_DeriveSecretWrap(ss, ss->ssl3.hs.currentSecret, + NULL, kHkdfLabelExporterMasterSecret, + keylogLabelExporterSecret, + &ss->ssl3.hs.exporterSecret); if (rv != SECSuccess) { return SECFailure; } @@ -873,30 +1153,20 @@ static SECStatus tls13_ComputeFinalSecrets(sslSocket *ss) { SECStatus rv; - PK11SymKey *resumptionMasterSecret = NULL; - PORT_Assert(!ss->ssl3.crSpec->master_secret); - PORT_Assert(!ss->ssl3.cwSpec->master_secret); + PORT_Assert(!ss->ssl3.crSpec->masterSecret); + PORT_Assert(!ss->ssl3.cwSpec->masterSecret); - rv = tls13_DeriveSecret(ss, ss->ssl3.hs.currentSecret, - NULL, kHkdfLabelResumptionMasterSecret, - NULL, &resumptionMasterSecret); + rv = tls13_DeriveSecretWrap(ss, ss->ssl3.hs.currentSecret, + NULL, kHkdfLabelResumptionMasterSecret, + NULL, + &ss->ssl3.hs.resumptionMasterSecret); PK11_FreeSymKey(ss->ssl3.hs.currentSecret); ss->ssl3.hs.currentSecret = NULL; if (rv != SECSuccess) { return SECFailure; } - /* This is pretty gross. TLS 1.3 uses a number of master secrets: - * The master secret to generate the keys and then the resumption - * master secret for future connections. To make this work without - * refactoring too much of the SSLv3 code, we store the RMS in - * |crSpec->master_secret| and |cwSpec->master_secret|. - */ - ss->ssl3.crSpec->master_secret = resumptionMasterSecret; - ss->ssl3.cwSpec->master_secret = - PK11_ReferenceSymKey(ss->ssl3.crSpec->master_secret); - return SECSuccess; } @@ -909,6 +1179,8 @@ tls13_RestoreCipherInfo(sslSocket *ss, sslSessionID *sid) */ ss->sec.authType = sid->authType; ss->sec.authKeyBits = sid->authKeyBits; + ss->sec.originalKeaGroup = ssl_LookupNamedGroup(sid->keaGroup); + ss->sec.signatureScheme = sid->sigScheme; } /* Check whether resumption-PSK is allowed. */ @@ -961,6 +1233,10 @@ tls13_CanNegotiateZeroRtt(sslSocket *ss, const sslSessionID *sid) &sid->u.ssl3.alpnSelection) != 0) return PR_FALSE; + if (tls13_IsReplay(ss, sid)) { + return PR_FALSE; + } + return PR_TRUE; } @@ -1046,7 +1322,9 @@ tls13_FindKeyShareEntry(sslSocket *ss, const sslNamedGroupDef *group) } static SECStatus -tls13_NegotiateKeyExchange(sslSocket *ss, TLS13KeyShareEntry **clientShare) +tls13_NegotiateKeyExchange(sslSocket *ss, + const sslNamedGroupDef **requestedGroup, + TLS13KeyShareEntry **clientShare) { unsigned int index; TLS13KeyShareEntry *entry = NULL; @@ -1126,13 +1404,16 @@ tls13_NegotiateKeyExchange(sslSocket *ss, TLS13KeyShareEntry **clientShare) SSL_TRC(3, ("%d: TLS13[%d]: group = %d", SSL_GETPID(), ss->fd, preferredGroup->name)); - if (!entry) { - return tls13_SendHelloRetryRequest(ss, preferredGroup); + /* Either provide a share, or provide a group that should be requested in a + * HelloRetryRequest, but not both. */ + if (entry) { + PORT_Assert(preferredGroup == entry->group); + *clientShare = entry; + *requestedGroup = NULL; + } else { + *clientShare = NULL; + *requestedGroup = preferredGroup; } - - PORT_Assert(preferredGroup == entry->group); - *clientShare = entry; - return SECSuccess; } @@ -1145,9 +1426,9 @@ ssl_SignatureSchemeToAuthType(SSLSignatureScheme scheme) case ssl_sig_rsa_pkcs1_sha384: case ssl_sig_rsa_pkcs1_sha512: /* We report PSS signatures as being just RSA signatures. */ - case ssl_sig_rsa_pss_sha256: - case ssl_sig_rsa_pss_sha384: - case ssl_sig_rsa_pss_sha512: + case ssl_sig_rsa_pss_rsae_sha256: + case ssl_sig_rsa_pss_rsae_sha384: + case ssl_sig_rsa_pss_rsae_sha512: return ssl_auth_rsa_sign; case ssl_sig_ecdsa_secp256r1_sha256: case ssl_sig_ecdsa_secp384r1_sha384: @@ -1190,8 +1471,8 @@ tls13_SelectServerCert(sslSocket *ss) rv = ssl_PickSignatureScheme(ss, cert->serverKeyPair->pubKey, cert->serverKeyPair->privKey, - ss->xtnData.clientSigSchemes, - ss->xtnData.numClientSigScheme, + ss->xtnData.sigSchemes, + ss->xtnData.numSigSchemes, PR_FALSE); if (rv == SECSuccess) { /* Found one. */ @@ -1208,6 +1489,62 @@ tls13_SelectServerCert(sslSocket *ss) return SECFailure; } +/* Note: |requestedGroup| is non-NULL when we send a key_share extension. */ +static SECStatus +tls13_MaybeSendHelloRetry(sslSocket *ss, const sslNamedGroupDef *requestedGroup, + PRBool *hrrSent) +{ + SSLHelloRetryRequestAction action = ssl_hello_retry_accept; + PRUint8 token[256] = { 0 }; + unsigned int tokenLen = 0; + SECStatus rv; + + if (ss->hrrCallback) { + action = ss->hrrCallback(!ss->ssl3.hs.helloRetry, + ss->xtnData.applicationToken.data, + ss->xtnData.applicationToken.len, + token, &tokenLen, sizeof(token), + ss->hrrCallbackArg); + } + + /* These use SSL3_SendAlert directly to avoid an assertion in + * tls13_FatalError(), which is ordinarily OK. */ + if (action == ssl_hello_retry_request && ss->ssl3.hs.helloRetry) { + (void)SSL3_SendAlert(ss, alert_fatal, internal_error); + PORT_SetError(SSL_ERROR_APP_CALLBACK_ERROR); + return SECFailure; + } + + if (action != ssl_hello_retry_request && tokenLen) { + (void)SSL3_SendAlert(ss, alert_fatal, internal_error); + PORT_SetError(SSL_ERROR_APP_CALLBACK_ERROR); + return SECFailure; + } + + if (tokenLen > sizeof(token)) { + (void)SSL3_SendAlert(ss, alert_fatal, internal_error); + PORT_SetError(SSL_ERROR_APP_CALLBACK_ERROR); + return SECFailure; + } + + if (action == ssl_hello_retry_fail) { + FATAL_ERROR(ss, SSL_ERROR_APPLICATION_ABORT, handshake_failure); + return SECFailure; + } + + if (!requestedGroup && action != ssl_hello_retry_request) { + return SECSuccess; + } + + rv = tls13_SendHelloRetryRequest(ss, requestedGroup, token, tokenLen); + if (rv != SECSuccess) { + return SECFailure; /* Code already set. */ + } + + *hrrSent = PR_TRUE; + return SECSuccess; +} + static SECStatus tls13_NegotiateAuthentication(sslSocket *ss) { @@ -1237,13 +1574,19 @@ tls13_NegotiateAuthentication(sslSocket *ss) SECStatus tls13_HandleClientHelloPart2(sslSocket *ss, const SECItem *suites, - sslSessionID *sid) + sslSessionID *sid, + const PRUint8 *msg, + unsigned int len) { SECStatus rv; SSL3Statistics *ssl3stats = SSL_GetStatistics(); + const sslNamedGroupDef *requestedGroup = NULL; TLS13KeyShareEntry *clientShare = NULL; - int j; - ssl3CipherSuite previousCipherSuite; + ssl3CipherSuite previousCipherSuite = 0; + const sslNamedGroupDef *previousGroup = NULL; + PRBool hrr = PR_FALSE; + + ss->ssl3.hs.endOfFlight = PR_TRUE; if (ssl3_ExtensionNegotiated(ss, ssl_tls13_early_data_xtn)) { ss->ssl3.hs.zeroRttState = ssl_0rtt_sent; @@ -1251,24 +1594,59 @@ tls13_HandleClientHelloPart2(sslSocket *ss, #ifndef PARANOID /* Look for a matching cipher suite. */ - j = ssl3_config_match_init(ss); - if (j <= 0) { /* no ciphers are working/supported by PK11 */ + if (ssl3_config_match_init(ss) == 0) { /* no ciphers are working/supported by PK11 */ FATAL_ERROR(ss, PORT_GetError(), internal_error); goto loser; } #endif - previousCipherSuite = ss->ssl3.hs.cipher_suite; + /* Negotiate cipher suite. */ rv = ssl3_NegotiateCipherSuite(ss, suites, PR_FALSE); if (rv != SECSuccess) { FATAL_ERROR(ss, SSL_ERROR_NO_CYPHER_OVERLAP, handshake_failure); goto loser; } + /* If we are going around again, then we should make sure that the cipher * suite selection doesn't change. That's a sign of client shennanigans. */ - if (ss->ssl3.hs.helloRetry && - ss->ssl3.hs.cipher_suite != previousCipherSuite) { - FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, handshake_failure); + if (ss->ssl3.hs.helloRetry) { + + /* Update sequence numbers before checking the cookie so that any alerts + * we generate are sent with the right sequence numbers. */ + if (IS_DTLS(ss)) { + /* Count the first ClientHello and the HelloRetryRequest. */ + ss->ssl3.hs.sendMessageSeq = 1; + ss->ssl3.hs.recvMessageSeq = 1; + 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; + ssl_ReleaseSpecWriteLock(ss); + } + + if (!ssl3_ExtensionNegotiated(ss, ssl_tls13_cookie_xtn) || + !ss->xtnData.cookie.len) { + FATAL_ERROR(ss, SSL_ERROR_MISSING_COOKIE_EXTENSION, + missing_extension); + goto loser; + } + PRINT_BUF(50, (ss, "Client sent cookie", + ss->xtnData.cookie.data, ss->xtnData.cookie.len)); + + rv = tls13_RecoverHashState(ss, ss->xtnData.cookie.data, + ss->xtnData.cookie.len, + &previousCipherSuite, + &previousGroup); + if (rv != SECSuccess) { + FATAL_ERROR(ss, SSL_ERROR_BAD_2ND_CLIENT_HELLO, illegal_parameter); + goto loser; + } + } + + /* Now merge the ClientHello into the hash state. */ + rv = ssl_HashHandshakeMessage(ss, ssl_hs_client_hello, msg, len); + if (rv != SECSuccess) { + FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error); goto loser; } @@ -1296,15 +1674,52 @@ tls13_HandleClientHelloPart2(sslSocket *ss, } /* Select key exchange. */ - rv = tls13_NegotiateKeyExchange(ss, &clientShare); + rv = tls13_NegotiateKeyExchange(ss, &requestedGroup, &clientShare); if (rv != SECSuccess) { goto loser; } + /* We should get either one of these, but not both. */ + PORT_Assert((requestedGroup && !clientShare) || + (!requestedGroup && clientShare)); - /* If we didn't find a client key share, we have to retry. */ - if (!clientShare) { + /* After HelloRetryRequest, check consistency of cipher and group. */ + if (ss->ssl3.hs.helloRetry) { + PORT_Assert(previousCipherSuite); + if (ss->ssl3.hs.cipher_suite != previousCipherSuite) { + FATAL_ERROR(ss, SSL_ERROR_BAD_2ND_CLIENT_HELLO, + illegal_parameter); + goto loser; + } + if (!clientShare) { + FATAL_ERROR(ss, SSL_ERROR_BAD_2ND_CLIENT_HELLO, + illegal_parameter); + goto loser; + } + + /* If we requested a new key share, check that the client provided just + * one of the right type. */ + if (previousGroup) { + if (PR_PREV_LINK(&ss->xtnData.remoteKeyShares) != + PR_NEXT_LINK(&ss->xtnData.remoteKeyShares)) { + FATAL_ERROR(ss, SSL_ERROR_BAD_2ND_CLIENT_HELLO, + illegal_parameter); + goto loser; + } + if (clientShare->group != previousGroup) { + FATAL_ERROR(ss, SSL_ERROR_BAD_2ND_CLIENT_HELLO, + illegal_parameter); + goto loser; + } + } + } + + rv = tls13_MaybeSendHelloRetry(ss, requestedGroup, &hrr); + if (rv != SECSuccess) { + goto loser; + } + if (hrr) { if (sid) { /* Free the sid. */ - ss->sec.uncache(sid); + ssl_UncacheSessionID(ss); ssl_FreeSID(sid); } PORT_Assert(ss->ssl3.hs.helloRetry); @@ -1354,8 +1769,7 @@ tls13_HandleClientHelloPart2(sslSocket *ss, } else { if (sid) { /* we had a sid, but it's no longer valid, free it */ SSL_AtomicIncrementLong(&ssl3stats->hch_sid_cache_not_ok); - if (ss->sec.uncache) - ss->sec.uncache(sid); + ssl_UncacheSessionID(ss); ssl_FreeSID(sid); sid = NULL; } @@ -1373,14 +1787,17 @@ tls13_HandleClientHelloPart2(sslSocket *ss, if (ss->statelessResume) { SSL3Hashes hashes; - rv = tls13_ComputePskBinderHash(ss, ss->xtnData.pskBinderPrefixLen, - &hashes); + PORT_Assert(ss->ssl3.hs.messages.len > ss->xtnData.pskBindersLen); + rv = tls13_ComputePskBinderHash( + ss, + ss->ssl3.hs.messages.len - ss->xtnData.pskBindersLen, + &hashes); if (rv != SECSuccess) { FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error); goto loser; } - rv = tls13_VerifyFinished(ss, client_hello, + rv = tls13_VerifyFinished(ss, ssl_hs_client_hello, ss->ssl3.hs.pskBinderKey, ss->xtnData.pskBinder.data, ss->xtnData.pskBinder.len, @@ -1412,7 +1829,7 @@ tls13_HandleClientHelloPart2(sslSocket *ss, if (sid) { /* We had a sid, but it's no longer valid, free it. */ SSL_AtomicIncrementLong(&ssl3stats->hch_sid_cache_not_ok); - ss->sec.uncache(sid); + ssl_UncacheSessionID(ss); ssl_FreeSID(sid); } else { SSL_AtomicIncrementLong(&ssl3stats->hch_sid_cache_misses); @@ -1429,11 +1846,7 @@ tls13_HandleClientHelloPart2(sslSocket *ss, sid = NULL; if (ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted) { - rv = tls13_DeriveSecret(ss, ss->ssl3.hs.currentSecret, - kHkdfLabelClient, - kHkdfLabelEarlyTrafficSecret, - NULL, /* Current running hash. */ - &ss->ssl3.hs.clientEarlyTrafficSecret); + rv = tls13_DeriveEarlySecrets(ss); if (rv != SECSuccess) { FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error); return SECFailure; @@ -1452,76 +1865,149 @@ tls13_HandleClientHelloPart2(sslSocket *ss, loser: if (sid) { - ss->sec.uncache(sid); + ssl_UncacheSessionID(ss); ssl_FreeSID(sid); } return SECFailure; } -static SECStatus -tls13_SendHelloRetryRequest(sslSocket *ss, const sslNamedGroupDef *selectedGroup) +SECStatus +SSLExp_HelloRetryRequestCallback(PRFileDesc *fd, + SSLHelloRetryRequestCallback cb, void *arg) { - SECStatus rv; - - SSL_TRC(3, ("%d: TLS13[%d]: send hello retry request handshake", - SSL_GETPID(), ss->fd)); - - PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); - - /* We asked already, but made no progress. */ - if (ss->ssl3.hs.helloRetry) { - FATAL_ERROR(ss, SSL_ERROR_BAD_2ND_CLIENT_HELLO, illegal_parameter); - return SECFailure; + sslSocket *ss = ssl_FindSocket(fd); + if (!ss) { + return SECFailure; /* Code already set. */ } - ssl_GetXmitBufLock(ss); - rv = ssl3_AppendHandshakeHeader(ss, hello_retry_request, - 2 + /* version */ - 2 + /* extension length */ - 2 + /* group extension id */ - 2 + /* group extension length */ - 2 /* group */); + ss->hrrCallback = cb; + ss->hrrCallbackArg = arg; + return SECSuccess; +} + +/* + * struct { + * ProtocolVersion server_version; + * CipherSuite cipher_suite; + * Extension extensions<2..2^16-1>; + * } HelloRetryRequest; + * + * Note: this function takes an empty buffer and returns + * a non-empty one on success, in which case the caller must + * eventually clean up. + */ +SECStatus +tls13_ConstructHelloRetryRequest(sslSocket *ss, + ssl3CipherSuite cipherSuite, + const sslNamedGroupDef *selectedGroup, + PRUint8 *cookie, unsigned int cookieLen, + sslBuffer *buffer) +{ + SECStatus rv; + sslBuffer extensionsBuf = SSL_BUFFER_EMPTY; + PORT_Assert(buffer->len == 0); + + /* Note: cookie is pointing to a stack variable, so is only valid + * now. */ + ss->xtnData.selectedGroup = selectedGroup; + ss->xtnData.cookie.data = cookie; + ss->xtnData.cookie.len = cookieLen; + rv = ssl_ConstructExtensions(ss, &extensionsBuf, + ssl_hs_hello_retry_request); if (rv != SECSuccess) { - FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error); goto loser; } + /* These extensions can't be empty. */ + PORT_Assert(SSL_BUFFER_LEN(&extensionsBuf) > 0); - rv = ssl3_AppendHandshakeNumber( - ss, tls13_EncodeDraftVersion(ss->version), 2); + /* Clean up cookie so we're not pointing at random memory. */ + ss->xtnData.cookie.data = NULL; + ss->xtnData.cookie.len = 0; + + rv = ssl_ConstructServerHello(ss, PR_TRUE, &extensionsBuf, buffer); if (rv != SECSuccess) { - FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error); goto loser; } + sslBuffer_Clear(&extensionsBuf); + return SECSuccess; + +loser: + sslBuffer_Clear(&extensionsBuf); + sslBuffer_Clear(buffer); + return SECFailure; +} + +static SECStatus +tls13_SendHelloRetryRequest(sslSocket *ss, + const sslNamedGroupDef *requestedGroup, + const PRUint8 *appToken, unsigned int appTokenLen) +{ + SECStatus rv; + unsigned int cookieLen; + PRUint8 cookie[1024]; + sslBuffer messageBuf = SSL_BUFFER_EMPTY; - /* Length of extensions. */ - rv = ssl3_AppendHandshakeNumber(ss, 2 + 2 + 2, 2); + SSL_TRC(3, ("%d: TLS13[%d]: send hello retry request handshake", + SSL_GETPID(), ss->fd)); + + PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); + + /* Compute the cookie we are going to need. */ + rv = tls13_MakeHrrCookie(ss, requestedGroup, + appToken, appTokenLen, + cookie, &cookieLen, sizeof(cookie)); if (rv != SECSuccess) { FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error); - goto loser; + return SECFailure; } - /* Key share extension - currently the only reason we send this. */ - rv = ssl3_AppendHandshakeNumber(ss, ssl_tls13_key_share_xtn, 2); + /* Now build the body of the message. */ + rv = tls13_ConstructHelloRetryRequest(ss, ss->ssl3.hs.cipher_suite, + requestedGroup, + cookie, cookieLen, &messageBuf); if (rv != SECSuccess) { FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error); - goto loser; + return SECFailure; } - /* Key share extension length. */ - rv = ssl3_AppendHandshakeNumber(ss, 2, 2); + + /* And send it. */ + ssl_GetXmitBufLock(ss); + rv = ssl3_AppendHandshakeHeader(ss, ssl_hs_server_hello, + SSL_BUFFER_LEN(&messageBuf)); if (rv != SECSuccess) { - FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error); goto loser; } - rv = ssl3_AppendHandshakeNumber(ss, selectedGroup->name, 2); + rv = ssl3_AppendBufferToHandshake(ss, &messageBuf); if (rv != SECSuccess) { - FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error); goto loser; } + sslBuffer_Clear(&messageBuf); /* Done with messageBuf */ - rv = ssl3_FlushHandshake(ss, 0); - if (rv != SECSuccess) { - goto loser; /* error code set by ssl3_FlushHandshake */ + if (ss->ssl3.hs.fakeSid.len) { + PRInt32 sent; + + PORT_Assert(!IS_DTLS(ss)); + rv = ssl3_SendChangeCipherSpecsInt(ss); + if (rv != SECSuccess) { + goto loser; + } + /* ssl3_SendChangeCipherSpecsInt() only flushes to the output buffer, so we + * have to force a send. */ + sent = ssl_SendSavedWriteData(ss); + if (sent < 0 && PORT_GetError() != PR_WOULD_BLOCK_ERROR) { + PORT_SetError(SSL_ERROR_SOCKET_WRITE_FAILURE); + goto loser; + } + } else { + rv = ssl3_FlushHandshake(ss, 0); + if (rv != SECSuccess) { + goto loser; /* error code set by ssl3_FlushHandshake */ + } } + + /* 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)); ssl_ReleaseXmitBufLock(ss); ss->ssl3.hs.helloRetry = PR_TRUE; @@ -1535,6 +2021,7 @@ tls13_SendHelloRetryRequest(sslSocket *ss, const sslNamedGroupDef *selectedGroup return SECSuccess; loser: + sslBuffer_Clear(&messageBuf); ssl_ReleaseXmitBufLock(ss); return SECFailure; } @@ -1606,67 +2093,96 @@ static SECStatus tls13_SendCertificateRequest(sslSocket *ss) { SECStatus rv; - unsigned int calen; - SECItem *names; - unsigned int nnames; - SECItem *name; - int i; - PRUint8 sigSchemes[MAX_SIGNATURE_SCHEMES * 2]; - unsigned int sigSchemesLength = 0; - int length; + sslBuffer extensionBuf = SSL_BUFFER_EMPTY; SSL_TRC(3, ("%d: TLS13[%d]: begin send certificate_request", SSL_GETPID(), ss->fd)); - rv = ssl3_EncodeSigAlgs(ss, sigSchemes, sizeof(sigSchemes), - &sigSchemesLength); + rv = ssl_ConstructExtensions(ss, &extensionBuf, ssl_hs_certificate_request); if (rv != SECSuccess) { - return rv; + return SECFailure; /* Code already set. */ } + /* We should always have at least one of these. */ + PORT_Assert(SSL_BUFFER_LEN(&extensionBuf) > 0); - rv = ssl_GetCertificateRequestCAs(ss, &calen, &names, &nnames); + rv = ssl3_AppendHandshakeHeader(ss, ssl_hs_certificate_request, + 1 + 0 + /* empty request context */ + 2 + /* extension length */ + SSL_BUFFER_LEN(&extensionBuf)); if (rv != SECSuccess) { - return rv; + goto loser; /* err set by AppendHandshake. */ } - length = 1 + 0 /* length byte for empty request context */ + - 2 + sigSchemesLength + 2 + calen + 2; - rv = ssl3_AppendHandshakeHeader(ss, certificate_request, length); - if (rv != SECSuccess) { - return rv; /* err set by AppendHandshake. */ - } + /* Context. */ rv = ssl3_AppendHandshakeNumber(ss, 0, 1); if (rv != SECSuccess) { - return rv; /* err set by AppendHandshake. */ + goto loser; /* err set by AppendHandshake. */ } - rv = ssl3_AppendHandshakeVariable(ss, sigSchemes, sigSchemesLength, 2); + /* Extensions. */ + rv = ssl3_AppendBufferToHandshakeVariable(ss, &extensionBuf, 2); if (rv != SECSuccess) { - return rv; /* err set by AppendHandshake. */ + goto loser; /* err set by AppendHandshake. */ } - rv = ssl3_AppendHandshakeNumber(ss, calen, 2); + + sslBuffer_Clear(&extensionBuf); + return SECSuccess; + +loser: + sslBuffer_Clear(&extensionBuf); + return SECFailure; +} + +/* [draft-ietf-tls-tls13; S 4.4.1] says: + * + * Transcript-Hash(ClientHello1, HelloRetryRequest, ... MN) = + * Hash(message_hash || // Handshake type + * 00 00 Hash.length || // Handshake message length + * Hash(ClientHello1) || // Hash of ClientHello1 + * HelloRetryRequest ... MN) + */ +static SECStatus +tls13_ReinjectHandshakeTranscript(sslSocket *ss) +{ + SSL3Hashes hashes; + SECStatus rv; + + // First compute the hash. + rv = tls13_ComputeHash(ss, &hashes, + ss->ssl3.hs.messages.buf, + ss->ssl3.hs.messages.len); if (rv != SECSuccess) { - return rv; /* err set by AppendHandshake. */ - } - for (i = 0, name = names; i < nnames; i++, name++) { - rv = ssl3_AppendHandshakeVariable(ss, name->data, name->len, 2); - if (rv != SECSuccess) { - return rv; /* err set by AppendHandshake. */ - } + return SECFailure; } - rv = ssl3_AppendHandshakeNumber(ss, 0, 2); + + // Now re-init the handshake. + ssl3_RestartHandshakeHashes(ss); + + // And reinject the message. + rv = ssl_HashHandshakeMessage(ss, ssl_hs_message_hash, + hashes.u.raw, hashes.len); if (rv != SECSuccess) { - return rv; /* err set by AppendHandshake. */ + return SECFailure; } return SECSuccess; } +static unsigned int +ssl_ListCount(PRCList *list) +{ + unsigned int c = 0; + PRCList *cur; + for (cur = PR_NEXT_LINK(list); cur != list; cur = PR_NEXT_LINK(cur)) { + ++c; + } + return c; +} + SECStatus -tls13_HandleHelloRetryRequest(sslSocket *ss, PRUint8 *b, PRUint32 length) +tls13_HandleHelloRetryRequest(sslSocket *ss, const PRUint8 *savedMsg, + PRUint32 savedLength) { SECStatus rv; - PRUint32 tmp; - SSL3ProtocolVersion version; SSL_TRC(3, ("%d: TLS13[%d]: handle hello retry request", SSL_GETPID(), ss->fd)); @@ -1679,84 +2195,77 @@ tls13_HandleHelloRetryRequest(sslSocket *ss, PRUint8 *b, PRUint32 length) unexpected_message); return SECFailure; } - - /* Client only. */ - rv = TLS13_CHECK_HS_STATE(ss, SSL_ERROR_RX_UNEXPECTED_HELLO_RETRY_REQUEST, - wait_server_hello); - if (rv != SECSuccess) { - return SECFailure; - } - - /* Fool me once, shame on you; fool me twice... */ - if (ss->ssl3.hs.helloRetry) { - FATAL_ERROR(ss, SSL_ERROR_RX_UNEXPECTED_HELLO_RETRY_REQUEST, - unexpected_message); - return SECFailure; - } + PORT_Assert(ss->ssl3.hs.ws == wait_server_hello); if (ss->ssl3.hs.zeroRttState == ssl_0rtt_sent) { ss->ssl3.hs.zeroRttState = ssl_0rtt_ignored; /* Restore the null cipher spec for writing. */ ssl_GetSpecWriteLock(ss); - tls13_CipherSpecRelease(ss->ssl3.cwSpec); - ss->ssl3.cwSpec = ss->ssl3.crSpec; - PORT_Assert(ss->ssl3.cwSpec->cipher_def->cipher == cipher_null); + ssl_CipherSpecRelease(ss->ssl3.cwSpec); + ss->ssl3.cwSpec = ssl_FindCipherSpecByEpoch(ss, CipherSpecWrite, + TrafficKeyClearText); + PORT_Assert(ss->ssl3.cwSpec); ssl_ReleaseSpecWriteLock(ss); } else { PORT_Assert(ss->ssl3.hs.zeroRttState == ssl_0rtt_none); } - /* Version. */ - rv = ssl_ClientReadVersion(ss, &b, &length, &version); - if (rv != SECSuccess) { - return SECFailure; /* alert already sent */ - } - if (version > ss->vrange.max || version < SSL_LIBRARY_VERSION_TLS_1_3) { - FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_HELLO_RETRY_REQUEST, - protocol_version); - return SECFailure; - } - - /* Extensions. */ - rv = ssl3_ConsumeHandshakeNumber(ss, &tmp, 2, &b, &length); - if (rv != SECSuccess) { - return SECFailure; /* error code already set */ - } - /* Extensions must be non-empty and use the remainder of the message. - * This means that a HelloRetryRequest cannot be a no-op: we must have an - * extension, it must be one that we understand and recognize as being valid - * for HelloRetryRequest, and all the extensions we permit cause us to - * modify our ClientHello in some way. */ - if (!tmp || tmp != length) { + /* 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 + * extensions, supported_versions plus one other. That other must be one + * that we understand and recognize as being valid for HelloRetryRequest, + * and all the extensions we permit cause us to modify our second + * ClientHello in some meaningful way. */ + if (ssl_ListCount(&ss->ssl3.hs.remoteExtensions) <= 1) { FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_HELLO_RETRY_REQUEST, decode_error); return SECFailure; } - rv = ssl3_HandleExtensions(ss, &b, &length, hello_retry_request); + rv = ssl3_HandleParsedExtensions(ss, ssl_hs_hello_retry_request); + ssl3_DestroyRemoteExtensions(&ss->ssl3.hs.remoteExtensions); if (rv != SECSuccess) { return SECFailure; /* Error code set below */ } ss->ssl3.hs.helloRetry = PR_TRUE; + rv = tls13_ReinjectHandshakeTranscript(ss); + if (rv != SECSuccess) { + return rv; + } + + rv = ssl_HashHandshakeMessage(ss, ssl_hs_server_hello, + savedMsg, savedLength); + if (rv != SECSuccess) { + return SECFailure; + } ssl_GetXmitBufLock(ss); + if (ss->opt.enableTls13CompatMode && !IS_DTLS(ss) && + ss->ssl3.hs.zeroRttState == ssl_0rtt_none) { + rv = ssl3_SendChangeCipherSpecsInt(ss); + if (rv != SECSuccess) { + goto loser; + } + } rv = ssl3_SendClientHello(ss, client_hello_retry); - ssl_ReleaseXmitBufLock(ss); if (rv != SECSuccess) { - return SECFailure; + goto loser; } + ssl_ReleaseXmitBufLock(ss); return SECSuccess; + +loser: + ssl_ReleaseXmitBufLock(ss); + return SECFailure; } static SECStatus tls13_HandleCertificateRequest(sslSocket *ss, PRUint8 *b, PRUint32 length) { SECStatus rv; - TLS13CertificateRequest *certRequest = NULL; SECItem context = { siBuffer, NULL, 0 }; - PLArenaPool *arena; SECItem extensionsData = { siBuffer, NULL, 0 }; SSL_TRC(3, ("%d: TLS13[%d]: handle certificate_request sequence", @@ -1775,71 +2284,51 @@ tls13_HandleCertificateRequest(sslSocket *ss, PRUint8 *b, PRUint32 length) PORT_Assert(ss->ssl3.clientCertChain == NULL); PORT_Assert(ss->ssl3.clientCertificate == NULL); PORT_Assert(ss->ssl3.clientPrivateKey == NULL); - PORT_Assert(ss->ssl3.hs.certificateRequest == NULL); + PORT_Assert(!ss->ssl3.hs.clientCertRequested); - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if (!arena) { - FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error); + rv = ssl3_ConsumeHandshakeVariable(ss, &context, 1, &b, &length); + if (rv != SECSuccess) { return SECFailure; } - rv = ssl3_ConsumeHandshakeVariable(ss, &context, 1, &b, &length); - if (rv != SECSuccess) - goto loser; - /* We don't support post-handshake client auth, the certificate request - * context must always be null. */ + * context must always be empty. */ if (context.len > 0) { FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CERT_REQUEST, illegal_parameter); - goto loser; - } - - certRequest = PORT_ArenaZNew(arena, TLS13CertificateRequest); - if (!certRequest) - goto loser; - certRequest->arena = arena; - certRequest->ca_list.arena = arena; - - rv = ssl_ParseSignatureSchemes(ss, arena, - &certRequest->signatureSchemes, - &certRequest->signatureSchemeCount, - &b, &length); - if (rv != SECSuccess || certRequest->signatureSchemeCount == 0) { - FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CERT_REQUEST, - decode_error); - goto loser; + return SECFailure; } - rv = ssl3_ParseCertificateRequestCAs(ss, &b, &length, arena, - &certRequest->ca_list); - if (rv != SECSuccess) - goto loser; /* alert already sent */ - - /* Verify that the extensions are sane. */ rv = ssl3_ConsumeHandshakeVariable(ss, &extensionsData, 2, &b, &length); if (rv != SECSuccess) { - goto loser; + return SECFailure; + } + + if (length) { + FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CERT_REQUEST, decode_error); + return SECFailure; } - /* Process all the extensions (note: currently a no-op). */ + /* Process all the extensions. */ rv = ssl3_HandleExtensions(ss, &extensionsData.data, &extensionsData.len, - certificate_request); + ssl_hs_certificate_request); if (rv != SECSuccess) { - goto loser; + return SECFailure; } - rv = SECITEM_CopyItem(arena, &certRequest->context, &context); - if (rv != SECSuccess) - goto loser; + if (!ss->xtnData.numSigSchemes) { + FATAL_ERROR(ss, SSL_ERROR_MISSING_SIGNATURE_ALGORITHMS_EXTENSION, + missing_extension); + return SECFailure; + } - TLS13_SET_HS_STATE(ss, wait_server_cert); - ss->ssl3.hs.certificateRequest = certRequest; + rv = SECITEM_CopyItem(NULL, &ss->xtnData.certReqContext, &context); + if (rv != SECSuccess) { + return SECFailure; + } + ss->ssl3.hs.clientCertRequested = PR_TRUE; + TLS13_SET_HS_STATE(ss, wait_server_cert); return SECSuccess; - -loser: - PORT_FreeArena(arena, PR_FALSE); - return SECFailure; } static SECStatus @@ -1859,12 +2348,10 @@ tls13_SendEncryptedServerSequence(sslSocket *ss) return SECFailure; } - ss->ssl3.hs.shortHeaders = ssl3_ExtensionNegotiated( - ss, ssl_tls13_short_header_xtn); - if (ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted) { - rv = ssl3_RegisterExtensionSender(ss, &ss->xtnData, ssl_tls13_early_data_xtn, - tls13_ServerSendEarlyDataXtn); + rv = ssl3_RegisterExtensionSender(ss, &ss->xtnData, + ssl_tls13_early_data_xtn, + ssl_SendEmptyExtension); if (rv != SECSuccess) { return SECFailure; /* Error code set already. */ } @@ -1917,11 +2404,29 @@ tls13_SendServerHelloSequence(sslSocket *ss) PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); + rv = ssl3_RegisterExtensionSender(ss, &ss->xtnData, + ssl_tls13_supported_versions_xtn, + tls13_ServerSendSupportedVersionsXtn); + if (rv != SECSuccess) { + return SECFailure; + } + rv = ssl3_SendServerHello(ss); if (rv != SECSuccess) { return rv; /* err code is set. */ } + if (ss->ssl3.hs.fakeSid.len) { + PORT_Assert(!IS_DTLS(ss)); + SECITEM_FreeItem(&ss->ssl3.hs.fakeSid, PR_FALSE); + if (!ss->ssl3.hs.helloRetry) { + rv = ssl3_SendChangeCipherSpecsInt(ss); + if (rv != SECSuccess) { + return rv; + } + } + } + rv = tls13_SendEncryptedServerSequence(ss); if (rv != SECSuccess) { err = PORT_GetError(); @@ -1953,14 +2458,18 @@ tls13_SendServerHelloSequence(sslSocket *ss) return SECFailure; } + if (IS_DTLS(ss)) { + /* We need this for reading ACKs. */ + ssl_CipherSpecAddRef(ss->ssl3.crSpec); + } if (ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted) { - rv = tls13_SetCipherSpec(ss, - TrafficKeyEarlyApplicationData, + rv = tls13_SetCipherSpec(ss, TrafficKeyEarlyApplicationData, CipherSpecRead, PR_TRUE); if (rv != SECSuccess) { LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE); return SECFailure; } + TLS13_SET_HS_STATE(ss, wait_end_of_early_data); } else { PORT_Assert(ss->ssl3.hs.zeroRttState == ssl_0rtt_none || ss->ssl3.hs.zeroRttState == ssl_0rtt_ignored); @@ -1972,11 +2481,12 @@ tls13_SendServerHelloSequence(sslSocket *ss) LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE); return SECFailure; } + TLS13_SET_HS_STATE(ss, + ss->opt.requestCertificate ? wait_client_cert + : wait_finished); } - TLS13_SET_HS_STATE(ss, - ss->opt.requestCertificate ? wait_client_cert - : wait_finished); + ss->ssl3.hs.serverHelloTime = ssl_TimeUsec(); return SECSuccess; } @@ -2023,12 +2533,12 @@ tls13_HandleServerHelloPart2(sslSocket *ss) SSL_AtomicIncrementLong(&ssl3stats->hsh_sid_stateless_resumes); } else { /* !PSK */ - if (ssl3_ClientExtensionAdvertised(ss, ssl_tls13_pre_shared_key_xtn)) { + if (ssl3_ExtensionAdvertised(ss, ssl_tls13_pre_shared_key_xtn)) { SSL_AtomicIncrementLong(&ssl3stats->hsh_sid_cache_misses); } if (sid->cached == in_client_cache) { /* If we tried to resume and failed, let's not try again. */ - ss->sec.uncache(sid); + ssl_UncacheSessionID(ss); } } @@ -2068,8 +2578,12 @@ tls13_HandleServerHelloPart2(sslSocket *ss) return SECFailure; /* error code is set. */ } - ss->ssl3.hs.shortHeaders = ssl3_ExtensionNegotiated( - ss, ssl_tls13_short_header_xtn); + if (ss->ssl3.hs.zeroRttState == ssl_0rtt_sent) { + /* When we send 0-RTT, we saved the null spec in case we needed it to + * send another ClientHello in response to a HelloRetryRequest. Now + * that we won't be receiving a HelloRetryRequest, release the spec. */ + ssl_CipherSpecReleaseByEpoch(ss, CipherSpecWrite, TrafficKeyClearText); + } rv = tls13_SetCipherSpec(ss, TrafficKeyHandshake, CipherSpecRead, PR_FALSE); @@ -2171,8 +2685,7 @@ tls13_SendCertificate(sslSocket *ss) int certChainLen = 0; int i; SECItem context = { siBuffer, NULL, 0 }; - PRInt32 extensionsLen = 0; - PRUint32 maxBytes = 65535; + sslBuffer extensionBuf = SSL_BUFFER_EMPTY; SSL_TRC(3, ("%d: TLS1.3[%d]: send certificate handshake", SSL_GETPID(), ss->fd)); @@ -2195,26 +2708,28 @@ tls13_SendCertificate(sslSocket *ss) ss->sec.localCert = CERT_DupCertificate(ss->ssl3.clientCertificate); } - /* Get the extensions length. This only applies to the leaf cert, - * because we don't yet send extensions for non-leaf certs. */ - extensionsLen = ssl3_CallHelloExtensionSenders( - ss, PR_FALSE, maxBytes, &ss->xtnData.certificateSenders[0]); - if (!ss->sec.isServer) { - PORT_Assert(ss->ssl3.hs.certificateRequest); - context = ss->ssl3.hs.certificateRequest->context; + PORT_Assert(ss->ssl3.hs.clientCertRequested); + context = ss->xtnData.certReqContext; } if (certChain) { for (i = 0; i < certChain->len; i++) { - certChainLen += - 3 + certChain->certs[i].len + /* cert length + cert */ - 2 + (!i ? extensionsLen : 0); /* extensions length + extensions */ + /* Each cert is 3 octet length, cert, and extensions */ + certChainLen += 3 + certChain->certs[i].len + 2; + } + + /* Build the extensions. This only applies to the leaf cert, because we + * don't yet send extensions for non-leaf certs. */ + rv = ssl_ConstructExtensions(ss, &extensionBuf, ssl_hs_certificate); + if (rv != SECSuccess) { + return SECFailure; /* code already set */ } + /* extensionBuf.len is only added once, for the leaf cert. */ + certChainLen += SSL_BUFFER_LEN(&extensionBuf); } - rv = ssl3_AppendHandshakeHeader(ss, certificate, - 1 + context.len + - 3 + certChainLen); + rv = ssl3_AppendHandshakeHeader(ss, ssl_hs_certificate, + 1 + context.len + 3 + certChainLen); if (rv != SECSuccess) { return SECFailure; /* err set by AppendHandshake. */ } @@ -2222,50 +2737,44 @@ tls13_SendCertificate(sslSocket *ss) rv = ssl3_AppendHandshakeVariable(ss, context.data, context.len, 1); if (rv != SECSuccess) { - return SECFailure; /* err set by AppendHandshake. */ + goto loser; /* err set by AppendHandshake. */ } rv = ssl3_AppendHandshakeNumber(ss, certChainLen, 3); if (rv != SECSuccess) { - return SECFailure; /* err set by AppendHandshake. */ + goto loser; /* err set by AppendHandshake. */ } if (certChain) { for (i = 0; i < certChain->len; i++) { - PRInt32 sentLen; - rv = ssl3_AppendHandshakeVariable(ss, certChain->certs[i].data, certChain->certs[i].len, 3); if (rv != SECSuccess) { - return SECFailure; /* err set by AppendHandshake. */ + goto loser; /* err set by AppendHandshake. */ } if (i) { /* Not end-entity. */ rv = ssl3_AppendHandshakeNumber(ss, 0, 2); if (rv != SECSuccess) { - return SECFailure; /* err set by AppendHandshake. */ + goto loser; /* err set by AppendHandshake. */ } continue; } /* End-entity, send extensions. */ - rv = ssl3_AppendHandshakeNumber(ss, extensionsLen, 2); + rv = ssl3_AppendBufferToHandshakeVariable(ss, &extensionBuf, 2); if (rv != SECSuccess) { - return SECFailure; /* err set by AppendHandshake. */ - } - - sentLen = ssl3_CallHelloExtensionSenders( - ss, PR_TRUE, extensionsLen, - &ss->xtnData.certificateSenders[0]); - PORT_Assert(sentLen == extensionsLen); - if (sentLen != extensionsLen) { - LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE); - return SECFailure; + goto loser; /* err set by AppendHandshake. */ } } } + sslBuffer_Clear(&extensionBuf); return SECSuccess; + +loser: + sslBuffer_Clear(&extensionBuf); + return SECFailure; } static SECStatus @@ -2293,7 +2802,7 @@ tls13_HandleCertificateEntry(sslSocket *ss, SECItem *data, PRBool first, if (first && !ss->sec.isServer) { rv = ssl3_HandleExtensions(ss, &extensionsData.data, &extensionsData.len, - certificate); + ssl_hs_certificate); if (rv != SECSuccess) { return SECFailure; } @@ -2351,6 +2860,11 @@ tls13_HandleCertificate(sslSocket *ss, PRUint8 *b, PRUint32 length) if (rv != SECSuccess) return SECFailure; + /* We can ignore any other cleartext from the client. */ + if (ss->sec.isServer && IS_DTLS(ss)) { + ssl_CipherSpecReleaseByEpoch(ss, CipherSpecRead, TrafficKeyClearText); + dtls_ReceivedFirstMessageInFlight(ss); + } /* Process the context string */ rv = ssl3_ConsumeHandshakeVariable(ss, &context, 1, &b, &length); if (rv != SECSuccess) @@ -2445,32 +2959,6 @@ tls13_HandleCertificate(sslSocket *ss, PRUint8 *b, PRUint32 length) return ssl3_AuthCertificate(ss); /* sets ss->ssl3.hs.ws */ } -void -tls13_CipherSpecAddRef(ssl3CipherSpec *spec) -{ - ++spec->refCt; - SSL_TRC(10, ("%d: TLS13[-]: Increment ref ct for spec %d. new ct = %d", - SSL_GETPID(), spec, spec->refCt)); -} - -/* This function is never called on a spec which is on the - * cipherSpecs list. */ -void -tls13_CipherSpecRelease(ssl3CipherSpec *spec) -{ - PORT_Assert(spec->refCt > 0); - --spec->refCt; - SSL_TRC(10, ("%d: TLS13[-]: decrement refct for spec %d. phase=%s new ct = %d", - SSL_GETPID(), spec, spec->phase, spec->refCt)); - if (!spec->refCt) { - SSL_TRC(10, ("%d: TLS13[-]: Freeing spec %d. phase=%s", - SSL_GETPID(), spec, spec->phase)); - PR_REMOVE_LINK(&spec->link); - ssl3_DestroyCipherSpec(spec, PR_TRUE); - PORT_Free(spec); - } -} - /* Add context to the hash functions as described in [draft-ietf-tls-tls13; Section 4.9.1] */ SECStatus @@ -2539,15 +3027,56 @@ loser: * HKDF-Expand-Label(Secret, Label, * Hash(Messages) + Hash(resumption_context), L)) */ -static SECStatus +SECStatus tls13_DeriveSecret(sslSocket *ss, PK11SymKey *key, - const char *prefix, - const char *suffix, + const char *label, + unsigned int labelLen, const SSL3Hashes *hashes, PK11SymKey **dest) { SECStatus rv; - SSL3Hashes hashesTmp; + + rv = tls13_HkdfExpandLabel(key, tls13_GetHash(ss), + hashes->u.raw, hashes->len, + label, labelLen, + tls13_GetHkdfMechanism(ss), + tls13_GetHashSize(ss), dest); + if (rv != SECSuccess) { + LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + return SECSuccess; +} + +/* Convenience wrapper for the empty hash. */ +SECStatus +tls13_DeriveSecretNullHash(sslSocket *ss, PK11SymKey *key, + const char *label, + unsigned int labelLen, + PK11SymKey **dest) +{ + SSL3Hashes hashes; + SECStatus rv; + PRUint8 buf[] = { 0 }; + + rv = tls13_ComputeHash(ss, &hashes, buf, 0); + if (rv != SECSuccess) { + return SECFailure; + } + + return tls13_DeriveSecret(ss, key, label, labelLen, &hashes, dest); +} + +/* Convenience wrapper that lets us supply a separate prefix and suffix. */ +static SECStatus +tls13_DeriveSecretWrap(sslSocket *ss, PK11SymKey *key, + const char *prefix, + const char *suffix, + const char *keylogLabel, + PK11SymKey **dest) +{ + SECStatus rv; + SSL3Hashes hashes; char buf[100]; const char *label; @@ -2566,25 +3095,22 @@ tls13_DeriveSecret(sslSocket *ss, PK11SymKey *key, SSL_TRC(3, ("%d: TLS13[%d]: deriving secret '%s'", SSL_GETPID(), ss->fd, label)); - if (!hashes) { - rv = tls13_ComputeHandshakeHashes(ss, &hashesTmp); - if (rv != SECSuccess) { - PORT_Assert(0); /* Should never fail */ - ssl_MapLowLevelError(SEC_ERROR_LIBRARY_FAILURE); - return SECFailure; - } - hashes = &hashesTmp; + rv = tls13_ComputeHandshakeHashes(ss, &hashes); + if (rv != SECSuccess) { + PORT_Assert(0); /* Should never fail */ + ssl_MapLowLevelError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; } - rv = tls13_HkdfExpandLabel(key, tls13_GetHash(ss), - hashes->u.raw, hashes->len, - label, strlen(label), - tls13_GetHkdfMechanism(ss), - tls13_GetHashSize(ss), dest); + rv = tls13_DeriveSecret(ss, key, label, strlen(label), + &hashes, dest); if (rv != SECSuccess) { - LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE); return SECFailure; } + + if (keylogLabel) { + ssl3_RecordKeyLog(ss, keylogLabel, *dest); + } return SECSuccess; } @@ -2592,49 +3118,41 @@ tls13_DeriveSecret(sslSocket *ss, PK11SymKey *key, static SECStatus tls13_DeriveTrafficKeys(sslSocket *ss, ssl3CipherSpec *spec, TrafficKeyType type, - CipherSpecDirection direction, PRBool deleteSecret) { - size_t keySize = spec->cipher_def->key_size; - size_t ivSize = spec->cipher_def->iv_size + - spec->cipher_def->explicit_nonce_size; /* This isn't always going to - * work, but it does for - * AES-GCM */ - CK_MECHANISM_TYPE bulkAlgorithm = ssl3_Alg2Mech(spec->cipher_def->calg); + size_t keySize = spec->cipherDef->key_size; + size_t ivSize = spec->cipherDef->iv_size + + spec->cipherDef->explicit_nonce_size; /* This isn't always going to + * work, but it does for + * AES-GCM */ + CK_MECHANISM_TYPE bulkAlgorithm = ssl3_Alg2Mech(spec->cipherDef->calg); PK11SymKey **prkp = NULL; PK11SymKey *prk = NULL; - PRBool clientKey; - ssl3KeyMaterial *target; - const char *phase; + PRBool clientSecret; SECStatus rv; /* These labels are just used for debugging. */ static const char kHkdfPhaseEarlyApplicationDataKeys[] = "early application data"; static const char kHkdfPhaseHandshakeKeys[] = "handshake data"; static const char kHkdfPhaseApplicationDataKeys[] = "application data"; - if (ss->sec.isServer ^ (direction == CipherSpecWrite)) { - clientKey = PR_TRUE; - target = &spec->client; - } else { - clientKey = PR_FALSE; - target = &spec->server; - } - PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); + clientSecret = !tls13_UseServerSecret(ss, spec->direction); switch (type) { case TrafficKeyEarlyApplicationData: - PORT_Assert(clientKey); - phase = kHkdfPhaseEarlyApplicationDataKeys; + PORT_Assert(clientSecret); prkp = &ss->ssl3.hs.clientEarlyTrafficSecret; + spec->phase = kHkdfPhaseEarlyApplicationDataKeys; break; case TrafficKeyHandshake: - phase = kHkdfPhaseHandshakeKeys; - prkp = clientKey ? &ss->ssl3.hs.clientHsTrafficSecret : &ss->ssl3.hs.serverHsTrafficSecret; + prkp = clientSecret ? &ss->ssl3.hs.clientHsTrafficSecret + : &ss->ssl3.hs.serverHsTrafficSecret; + spec->phase = kHkdfPhaseHandshakeKeys; break; case TrafficKeyApplicationData: - phase = kHkdfPhaseApplicationDataKeys; - prkp = clientKey ? &ss->ssl3.hs.clientTrafficSecret : &ss->ssl3.hs.serverTrafficSecret; + prkp = clientSecret ? &ss->ssl3.hs.clientTrafficSecret + : &ss->ssl3.hs.serverTrafficSecret; + spec->phase = kHkdfPhaseApplicationDataKeys; break; default: LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE); @@ -2644,17 +3162,15 @@ tls13_DeriveTrafficKeys(sslSocket *ss, ssl3CipherSpec *spec, PORT_Assert(prkp != NULL); prk = *prkp; - SSL_TRC(3, ("%d: TLS13[%d]: deriving %s traffic keys phase='%s'", - SSL_GETPID(), ss->fd, - (direction == CipherSpecWrite) ? "write" : "read", phase)); - PORT_Assert(phase); - spec->phase = phase; + SSL_TRC(3, ("%d: TLS13[%d]: deriving %s traffic keys epoch=%d (%s)", + SSL_GETPID(), ss->fd, SPEC_DIR(spec), + spec->epoch, spec->phase)); rv = tls13_HkdfExpandLabel(prk, tls13_GetHash(ss), NULL, 0, kHkdfPurposeKey, strlen(kHkdfPurposeKey), bulkAlgorithm, keySize, - &target->write_key); + &spec->keyMaterial.key); if (rv != SECSuccess) { LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE); PORT_Assert(0); @@ -2664,7 +3180,7 @@ tls13_DeriveTrafficKeys(sslSocket *ss, ssl3CipherSpec *spec, rv = tls13_HkdfExpandLabelRaw(prk, tls13_GetHash(ss), NULL, 0, kHkdfPurposeIv, strlen(kHkdfPurposeIv), - target->write_iv, ivSize); + spec->keyMaterial.iv, ivSize); if (rv != SECSuccess) { LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE); PORT_Assert(0); @@ -2681,38 +3197,111 @@ loser: return SECFailure; } +void +tls13_SetSpecRecordVersion(sslSocket *ss, ssl3CipherSpec *spec) +{ + /* Set the record version to pretend to be (D)TLS 1.2. */ + if (IS_DTLS(ss)) { + spec->recordVersion = SSL_LIBRARY_VERSION_DTLS_1_2_WIRE; + } else { + spec->recordVersion = SSL_LIBRARY_VERSION_TLS_1_2; + } + SSL_TRC(10, ("%d: TLS13[%d]: set spec=%d record version to 0x%04x", + SSL_GETPID(), ss->fd, spec, spec->recordVersion)); +} + static SECStatus -tls13_SetupPendingCipherSpec(sslSocket *ss) +tls13_SetupPendingCipherSpec(sslSocket *ss, ssl3CipherSpec *spec) { - ssl3CipherSpec *pSpec; ssl3CipherSuite suite = ss->ssl3.hs.cipher_suite; - const ssl3BulkCipherDef *bulk = ssl_GetBulkCipherDef( - ssl_LookupCipherSuiteDef(suite)); PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); + PORT_Assert(spec->epoch); - ssl_GetSpecWriteLock(ss); /*******************************/ - - pSpec = ss->ssl3.pwSpec; /* Version isn't set when we send 0-RTT data. */ - pSpec->version = PR_MAX(SSL_LIBRARY_VERSION_TLS_1_3, ss->version); + spec->version = PR_MAX(SSL_LIBRARY_VERSION_TLS_1_3, ss->version); + + ssl_SaveCipherSpec(ss, spec); + /* We want to keep read cipher specs around longer because + * there are cases where we might get either epoch N or + * epoch N+1. */ + if (IS_DTLS(ss) && spec->direction == CipherSpecRead) { + ssl_CipherSpecAddRef(spec); + } SSL_TRC(3, ("%d: TLS13[%d]: Set Pending Cipher Suite to 0x%04x", SSL_GETPID(), ss->fd, suite)); - pSpec->cipher_def = bulk; - ssl_ReleaseSpecWriteLock(ss); /*******************************/ + spec->cipherDef = ssl_GetBulkCipherDef(ssl_LookupCipherSuiteDef(suite)); + switch (spec->cipherDef->calg) { + case ssl_calg_aes_gcm: + spec->aead = tls13_AESGCM; + break; + case ssl_calg_chacha20: + spec->aead = tls13_ChaCha20Poly1305; + break; + default: + PORT_Assert(0); + return SECFailure; + } + + if (spec->epoch == TrafficKeyEarlyApplicationData) { + spec->earlyDataRemaining = + ss->sec.ci.sid->u.ssl3.locked.sessionTicket.max_early_data_size; + } + + tls13_SetSpecRecordVersion(ss, spec); + return SECSuccess; +} + +/* + * Called before sending alerts to set up the right key on the client. + * We might encounter errors during the handshake where the current + * key is ClearText or EarlyApplicationData. This + * function switches to the Handshake key if possible. + */ +SECStatus +tls13_SetAlertCipherSpec(sslSocket *ss) +{ + SECStatus rv; + + if (ss->sec.isServer) { + return SECSuccess; + } + if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) { + return SECSuccess; + } + if (TLS13_IN_HS_STATE(ss, wait_server_hello)) { + return SECSuccess; + } + if ((ss->ssl3.cwSpec->epoch != TrafficKeyClearText) && + (ss->ssl3.cwSpec->epoch != TrafficKeyEarlyApplicationData)) { + return SECSuccess; + } + + rv = tls13_SetCipherSpec(ss, TrafficKeyHandshake, + CipherSpecWrite, PR_FALSE); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } return SECSuccess; } -/* Install a new cipher spec for this direction. */ +/* Install a new cipher spec for this direction. + * + * During the handshake, the values for |epoch| take values from the + * TrafficKeyType enum. Afterwards, key update increments them. + */ static SECStatus -tls13_SetCipherSpec(sslSocket *ss, TrafficKeyType type, +tls13_SetCipherSpec(sslSocket *ss, PRUint16 epoch, CipherSpecDirection direction, PRBool deleteSecret) { + TrafficKeyType type; SECStatus rv; ssl3CipherSpec *spec = NULL; - ssl3CipherSpec **specp = (direction == CipherSpecRead) ? &ss->ssl3.crSpec : &ss->ssl3.cwSpec; + ssl3CipherSpec **specp; + /* Flush out old handshake data. */ ssl_GetXmitBufLock(ss); rv = ssl3_FlushHandshake(ss, ssl_SEND_FLAG_FORCE_INTO_BUFFER); @@ -2722,81 +3311,52 @@ tls13_SetCipherSpec(sslSocket *ss, TrafficKeyType type, } /* Create the new spec. */ - spec = PORT_ZNew(ssl3CipherSpec); + spec = ssl_CreateCipherSpec(ss, direction); if (!spec) { - PORT_SetError(SEC_ERROR_NO_MEMORY); return SECFailure; } - spec->refCt = 1; - PR_APPEND_LINK(&spec->link, &ss->ssl3.hs.cipherSpecs); - ss->ssl3.pwSpec = ss->ssl3.prSpec = spec; - - rv = tls13_SetupPendingCipherSpec(ss); - if (rv != SECSuccess) - return SECFailure; - - switch (spec->cipher_def->calg) { - case calg_aes_gcm: - spec->aead = tls13_AESGCM; - break; - case calg_chacha20: - spec->aead = tls13_ChaCha20Poly1305; - break; - default: - PORT_Assert(0); - return SECFailure; - break; + spec->epoch = epoch; + spec->seqNum = 0; + if (IS_DTLS(ss)) { + dtls_InitRecvdRecords(&spec->recvdRecords); } - rv = tls13_DeriveTrafficKeys(ss, spec, type, direction, - deleteSecret); + /* This depends on spec having a valid direction and epoch. */ + rv = tls13_SetupPendingCipherSpec(ss, spec); if (rv != SECSuccess) { - return SECFailure; - } - - /* We use the epoch for cipher suite identification, so increment - * it in both TLS and DTLS. */ - if ((*specp)->epoch == PR_UINT16_MAX) { - return SECFailure; - } - spec->epoch = (PRUint16)type; - - if (!IS_DTLS(ss)) { - spec->read_seq_num = spec->write_seq_num = 0; - } else { - /* The sequence number has the high 16 bits as the epoch. */ - spec->read_seq_num = spec->write_seq_num = - (sslSequenceNumber)spec->epoch << 48; - - dtls_InitRecvdRecords(&spec->recvdRecords); + goto loser; } - if (type == TrafficKeyEarlyApplicationData) { - spec->earlyDataRemaining = - ss->sec.ci.sid->u.ssl3.locked.sessionTicket.max_early_data_size; + type = (TrafficKeyType)PR_MIN(TrafficKeyApplicationData, epoch); + rv = tls13_DeriveTrafficKeys(ss, spec, type, deleteSecret); + if (rv != SECSuccess) { + goto loser; } /* Now that we've set almost everything up, finally cut over. */ + specp = (direction == CipherSpecRead) ? &ss->ssl3.crSpec : &ss->ssl3.cwSpec; ssl_GetSpecWriteLock(ss); - tls13_CipherSpecRelease(*specp); /* May delete old cipher. */ - *specp = spec; /* Overwrite. */ + ssl_CipherSpecRelease(*specp); /* May delete old cipher. */ + *specp = spec; /* Overwrite. */ ssl_ReleaseSpecWriteLock(ss); - SSL_TRC(3, ("%d: TLS13[%d]: %s installed key for phase='%s'.%d dir=%s", - SSL_GETPID(), ss->fd, SSL_ROLE(ss), - spec->phase, spec->epoch, - direction == CipherSpecRead ? "read" : "write")); + SSL_TRC(3, ("%d: TLS13[%d]: %s installed key for epoch=%d (%s) dir=%s", + SSL_GETPID(), ss->fd, SSL_ROLE(ss), spec->epoch, + spec->phase, SPEC_DIR(spec))); if (ss->ssl3.changedCipherSpecFunc) { ss->ssl3.changedCipherSpecFunc(ss->ssl3.changedCipherSpecArg, direction == CipherSpecWrite, spec); } return SECSuccess; + +loser: + ssl_CipherSpecRelease(spec); + return SECFailure; } -static SECStatus -tls13_ComputeHandshakeHashes(sslSocket *ss, - SSL3Hashes *hashes) +SECStatus +tls13_ComputeHandshakeHashes(sslSocket *ss, SSL3Hashes *hashes) { SECStatus rv; PK11Context *ctx = NULL; @@ -2816,7 +3376,7 @@ tls13_ComputeHandshakeHashes(sslSocket *ss, goto loser; } - PRINT_BUF(10, (NULL, "Handshake hash computed over saved messages", + PRINT_BUF(10, (ss, "Handshake hash computed over saved messages", ss->ssl3.hs.messages.buf, ss->ssl3.hs.messages.len)); @@ -2841,6 +3401,8 @@ tls13_ComputeHandshakeHashes(sslSocket *ss, ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE); goto loser; } + + PRINT_BUF(10, (ss, "Handshake hash", hashes->u.raw, hashes->len)); PORT_Assert(hashes->len == tls13_GetHashSize(ss)); PK11_DestroyContext(ctx, PR_TRUE); @@ -2890,19 +3452,6 @@ tls13_DestroyEarlyData(PRCList *list) } } -void -tls13_DestroyCipherSpecs(PRCList *list) -{ - PRCList *cur_p; - - while (!PR_CLIST_IS_EMPTY(list)) { - cur_p = PR_LIST_TAIL(list); - PR_REMOVE_LINK(cur_p); - ssl3_DestroyCipherSpec((ssl3CipherSpec *)cur_p, PR_FALSE); - PORT_Free(cur_p); - } -} - /* draft-ietf-tls-tls13 Section 5.2.2 specifies the following * nonce algorithm: * @@ -2932,7 +3481,7 @@ tls13_WriteNonce(ssl3KeyMaterial *keys, size_t i; PORT_Assert(nonceLen == 12); - memcpy(nonce, keys->write_iv, 12); + memcpy(nonce, keys->iv, 12); /* XOR the last 8 bytes of the IV with the sequence number. */ PORT_Assert(seqNumLen == 8); @@ -2962,10 +3511,10 @@ tls13_AEAD(ssl3KeyMaterial *keys, PRBool doDecrypt, }; if (doDecrypt) { - rv = PK11_Decrypt(keys->write_key, mechanism, ¶m, + rv = PK11_Decrypt(keys->key, mechanism, ¶m, out, &uOutLen, maxout, in, inlen); } else { - rv = PK11_Encrypt(keys->write_key, mechanism, ¶m, + rv = PK11_Encrypt(keys->key, mechanism, ¶m, out, &uOutLen, maxout, in, inlen); } *outlen = (int)uOutLen; @@ -3062,7 +3611,7 @@ tls13_HandleEncryptedExtensions(sslSocket *ss, PRUint8 *b, PRUint32 length) ss->xtnData.nextProto.data = NULL; ss->xtnData.nextProtoState = SSL_NEXT_PROTO_NO_SUPPORT; } - rv = ssl3_HandleExtensions(ss, &b, &length, encrypted_extensions); + rv = ssl3_HandleExtensions(ss, &b, &length, ssl_hs_encrypted_extensions); if (rv != SECSuccess) { return SECFailure; /* Error code set below */ } @@ -3114,10 +3663,8 @@ tls13_HandleEncryptedExtensions(sslSocket *ss, PRUint8 *b, PRUint32 length) static SECStatus tls13_SendEncryptedExtensions(sslSocket *ss) { + sslBuffer extensions = SSL_BUFFER_EMPTY; SECStatus rv; - PRInt32 extensions_len = 0; - PRInt32 sent_len = 0; - PRUint32 maxBytes = 65535; SSL_TRC(3, ("%d: TLS13[%d]: send encrypted extensions handshake", SSL_GETPID(), ss->fd)); @@ -3125,31 +3672,28 @@ tls13_SendEncryptedExtensions(sslSocket *ss) PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); - extensions_len = ssl3_CallHelloExtensionSenders( - ss, PR_FALSE, maxBytes, &ss->xtnData.encryptedExtensionsSenders[0]); - - rv = ssl3_AppendHandshakeHeader(ss, encrypted_extensions, - extensions_len + 2); + rv = ssl_ConstructExtensions(ss, &extensions, ssl_hs_encrypted_extensions); if (rv != SECSuccess) { - LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE); return SECFailure; } - rv = ssl3_AppendHandshakeNumber(ss, extensions_len, 2); + + rv = ssl3_AppendHandshakeHeader(ss, ssl_hs_encrypted_extensions, + SSL_BUFFER_LEN(&extensions) + 2); if (rv != SECSuccess) { LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE); - return SECFailure; + goto loser; } - sent_len = ssl3_CallHelloExtensionSenders( - ss, PR_TRUE, extensions_len, - &ss->xtnData.encryptedExtensionsSenders[0]); - PORT_Assert(sent_len == extensions_len); - if (sent_len != extensions_len) { + rv = ssl3_AppendBufferToHandshakeVariable(ss, &extensions, 2); + if (rv != SECSuccess) { LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE); - PORT_Assert(sent_len == 0); - return SECFailure; + goto loser; } - + sslBuffer_Clear(&extensions); return SECSuccess; + +loser: + sslBuffer_Clear(&extensions); + return SECFailure; } SECStatus @@ -3210,7 +3754,7 @@ tls13_SendCertificateVerify(sslSocket *ss, SECKEYPrivateKey *privKey) len = buf.len + 2 + 2; - rv = ssl3_AppendHandshakeHeader(ss, certificate_verify, len); + rv = ssl3_AppendHandshakeHeader(ss, ssl_hs_certificate_verify, len); if (rv != SECSuccess) { goto done; /* error code set by AppendHandshake */ } @@ -3238,14 +3782,14 @@ done: * Caller must hold Handshake and RecvBuf locks. */ SECStatus -tls13_HandleCertificateVerify(sslSocket *ss, PRUint8 *b, PRUint32 length, - SSL3Hashes *hashes) +tls13_HandleCertificateVerify(sslSocket *ss, PRUint8 *b, PRUint32 length) { SECItem signed_hash = { siBuffer, NULL, 0 }; SECStatus rv; SSLSignatureScheme sigScheme; SSLHashType hashAlg; SSL3Hashes tbsHash; + SSL3Hashes hashes; SSL_TRC(3, ("%d: TLS13[%d]: handle certificate_verify handshake", SSL_GETPID(), ss->fd)); @@ -3257,7 +3801,17 @@ tls13_HandleCertificateVerify(sslSocket *ss, PRUint8 *b, PRUint32 length, if (rv != SECSuccess) { return SECFailure; } - PORT_Assert(hashes); + + rv = tls13_ComputeHandshakeHashes(ss, &hashes); + if (rv != SECSuccess) { + return SECFailure; + } + + rv = ssl_HashHandshakeMessage(ss, ssl_hs_certificate_verify, b, length); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } rv = ssl_ConsumeSignatureScheme(ss, &b, &length, &sigScheme); if (rv != SECSuccess) { @@ -3272,7 +3826,7 @@ tls13_HandleCertificateVerify(sslSocket *ss, PRUint8 *b, PRUint32 length, } hashAlg = ssl_SignatureSchemeToHashType(sigScheme); - rv = tls13_AddContextToHashes(ss, hashes, hashAlg, PR_FALSE, &tbsHash); + rv = tls13_AddContextToHashes(ss, &hashes, hashAlg, PR_FALSE, &tbsHash); if (rv != SECSuccess) { FATAL_ERROR(ss, SSL_ERROR_DIGEST_FAILURE, internal_error); return SECFailure; @@ -3301,13 +3855,11 @@ tls13_HandleCertificateVerify(sslSocket *ss, PRUint8 *b, PRUint32 length, } /* Request a client certificate now if one was requested. */ - if (ss->ssl3.hs.certificateRequest) { - TLS13CertificateRequest *req = ss->ssl3.hs.certificateRequest; - + if (ss->ssl3.hs.clientCertRequested) { PORT_Assert(!ss->sec.isServer); - rv = ssl3_CompleteHandleCertificateRequest(ss, req->signatureSchemes, - req->signatureSchemeCount, - &req->ca_list); + rv = ssl3_CompleteHandleCertificateRequest( + ss, ss->xtnData.sigSchemes, ss->xtnData.numSigSchemes, + &ss->xtnData.certReqAuthorities); if (rv != SECSuccess) { FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error); return rv; @@ -3320,7 +3872,7 @@ tls13_HandleCertificateVerify(sslSocket *ss, PRUint8 *b, PRUint32 length, } static SECStatus -tls13_ComputePskBinderHash(sslSocket *ss, unsigned long prefixLength, +tls13_ComputePskBinderHash(sslSocket *ss, unsigned int prefixLength, SSL3Hashes *hashes) { SECStatus rv; @@ -3332,38 +3884,75 @@ tls13_ComputePskBinderHash(sslSocket *ss, unsigned long prefixLength, PRINT_BUF(10, (NULL, "Handshake hash computed over ClientHello prefix", ss->ssl3.hs.messages.buf, prefixLength)); rv = PK11_HashBuf(ssl3_HashTypeToOID(tls13_GetHash(ss)), - hashes->u.raw, - ss->ssl3.hs.messages.buf, prefixLength); + hashes->u.raw, ss->ssl3.hs.messages.buf, prefixLength); if (rv != SECSuccess) { ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE); - goto loser; + return SECFailure; } - hashes->len = tls13_GetHashSize(ss); - PRINT_BUF(10, (NULL, "PSK Binder hash", - hashes->u.raw, hashes->len)); + hashes->len = tls13_GetHashSize(ss); + PRINT_BUF(10, (NULL, "PSK Binder hash", hashes->u.raw, hashes->len)); return SECSuccess; - -loser: - return SECFailure; } -/* Compute the PSK Binder This is kind of sneaky.*/ + +/* Compute and inject the PSK Binder for sending. + * + * When sending a ClientHello, we construct all the extensions with a dummy + * value for the binder. To construct the binder, we commit the entire message + * up to the point where the binders start. Then we calculate the hash using + * the saved message (in ss->ssl3.hs.messages). This is written over the dummy + * binder, after which we write the remainder of the binder extension. */ SECStatus -tls13_ComputePskBinder(sslSocket *ss, PRBool sending, - unsigned int prefixLength, - PRUint8 *output, unsigned int *outputLen, - unsigned int maxOutputLen) +tls13_WriteExtensionsWithBinder(sslSocket *ss, sslBuffer *extensions) { SSL3Hashes hashes; SECStatus rv; + unsigned int size = tls13_GetHashSize(ss); + unsigned int prefixLen = extensions->len - size - 3; + unsigned int finishedLen; - rv = tls13_ComputePskBinderHash(ss, prefixLength, &hashes); - if (rv != SECSuccess) + PORT_Assert(extensions->len >= size + 3); + + rv = ssl3_AppendHandshakeNumber(ss, extensions->len, 2); + if (rv != SECSuccess) { return SECFailure; + } - return tls13_ComputeFinished(ss, ss->ssl3.hs.pskBinderKey, &hashes, - sending, output, outputLen, maxOutputLen); + /* Only write the extension up to the point before the binders. Assume that + * the pre_shared_key extension is at the end of the buffer. Don't write + * the binder, or the lengths that precede it (a 2 octet length for the list + * of all binders, plus a 1 octet length for the binder length). */ + rv = ssl3_AppendHandshake(ss, extensions->buf, prefixLen); + if (rv != SECSuccess) { + return SECFailure; + } + + /* Calculate the binder based on what has been written out. */ + rv = tls13_ComputePskBinderHash(ss, ss->ssl3.hs.messages.len, &hashes); + if (rv != SECSuccess) { + return SECFailure; + } + + /* Write the binder into the extensions buffer, over the zeros we reserved + * previously. This avoids an allocation and means that we don't need a + * separate write for the extra bits that precede the binder. */ + rv = tls13_ComputeFinished(ss, ss->ssl3.hs.pskBinderKey, &hashes, PR_TRUE, + extensions->buf + extensions->len - size, + &finishedLen, size); + if (rv != SECSuccess) { + return SECFailure; + } + PORT_Assert(finishedLen == size); + + /* Write out the remainder of the extension. */ + rv = ssl3_AppendHandshake(ss, extensions->buf + prefixLen, + extensions->len - prefixLen); + if (rv != SECSuccess) { + return SECFailure; + } + + return SECSuccess; } static SECStatus @@ -3462,7 +4051,7 @@ tls13_SendFinished(sslSocket *ss, PK11SymKey *baseKey) return SECFailure; } - rv = ssl3_AppendHandshakeHeader(ss, finished, finishedLen); + rv = ssl3_AppendHandshakeHeader(ss, ssl_hs_finished, finishedLen); if (rv != SECSuccess) { return SECFailure; /* Error code already set. */ } @@ -3477,7 +4066,7 @@ tls13_SendFinished(sslSocket *ss, PK11SymKey *baseKey) } static SECStatus -tls13_VerifyFinished(sslSocket *ss, SSL3HandshakeType message, +tls13_VerifyFinished(sslSocket *ss, SSLHandshakeType message, PK11SymKey *secret, PRUint8 *b, PRUint32 length, const SSL3Hashes *hashes) @@ -3500,7 +4089,7 @@ tls13_VerifyFinished(sslSocket *ss, SSL3HandshakeType message, if (length != finishedLen) { #ifndef UNSAFE_FUZZER_MODE - FATAL_ERROR(ss, message == finished ? SSL_ERROR_RX_MALFORMED_FINISHED : SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, illegal_parameter); + FATAL_ERROR(ss, message == ssl_hs_finished ? SSL_ERROR_RX_MALFORMED_FINISHED : SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, illegal_parameter); return SECFailure; #endif } @@ -3517,8 +4106,37 @@ tls13_VerifyFinished(sslSocket *ss, SSL3HandshakeType message, } static SECStatus -tls13_ClientHandleFinished(sslSocket *ss, PRUint8 *b, PRUint32 length, - const SSL3Hashes *hashes) +tls13_CommonHandleFinished(sslSocket *ss, PK11SymKey *key, + PRUint8 *b, PRUint32 length) +{ + SECStatus rv; + SSL3Hashes hashes; + + rv = TLS13_CHECK_HS_STATE(ss, SSL_ERROR_RX_UNEXPECTED_FINISHED, + wait_finished); + if (rv != SECSuccess) { + return SECFailure; + } + ss->ssl3.hs.endOfFlight = PR_TRUE; + + rv = tls13_ComputeHandshakeHashes(ss, &hashes); + if (rv != SECSuccess) { + LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + + rv = ssl_HashHandshakeMessage(ss, ssl_hs_finished, b, length); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + + return tls13_VerifyFinished(ss, ssl_hs_finished, + key, b, length, &hashes); +} + +static SECStatus +tls13_ClientHandleFinished(sslSocket *ss, PRUint8 *b, PRUint32 length) { SECStatus rv; @@ -3528,27 +4146,19 @@ tls13_ClientHandleFinished(sslSocket *ss, PRUint8 *b, PRUint32 length, SSL_TRC(3, ("%d: TLS13[%d]: client handle finished handshake", SSL_GETPID(), ss->fd)); - rv = TLS13_CHECK_HS_STATE(ss, SSL_ERROR_RX_UNEXPECTED_FINISHED, - wait_finished); + rv = tls13_CommonHandleFinished(ss, ss->ssl3.hs.serverHsTrafficSecret, + b, length); if (rv != SECSuccess) { return SECFailure; } - rv = tls13_VerifyFinished(ss, finished, - ss->ssl3.hs.serverHsTrafficSecret, - b, length, hashes); - if (rv != SECSuccess) - return SECFailure; - return tls13_SendClientSecondRound(ss); } static SECStatus -tls13_ServerHandleFinished(sslSocket *ss, PRUint8 *b, PRUint32 length, - const SSL3Hashes *hashes) +tls13_ServerHandleFinished(sslSocket *ss, PRUint8 *b, PRUint32 length) { SECStatus rv; - PK11SymKey *secret; PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss)); PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); @@ -3556,61 +4166,68 @@ tls13_ServerHandleFinished(sslSocket *ss, PRUint8 *b, PRUint32 length, SSL_TRC(3, ("%d: TLS13[%d]: server handle finished handshake", SSL_GETPID(), ss->fd)); - rv = TLS13_CHECK_HS_STATE(ss, SSL_ERROR_RX_UNEXPECTED_FINISHED, wait_finished); + rv = tls13_CommonHandleFinished(ss, ss->ssl3.hs.clientHsTrafficSecret, + b, length); if (rv != SECSuccess) { return SECFailure; } - if (TLS13_IN_HS_STATE(ss, wait_finished)) { - secret = ss->ssl3.hs.clientHsTrafficSecret; - } else { - secret = ss->ssl3.hs.clientEarlyTrafficSecret; + if (!ss->opt.requestCertificate && + (ss->ssl3.hs.zeroRttState != ssl_0rtt_done)) { + dtls_ReceivedFirstMessageInFlight(ss); } - rv = tls13_VerifyFinished(ss, finished, secret, b, length, hashes); - if (rv != SECSuccess) - return SECFailure; - rv = tls13_SetCipherSpec(ss, TrafficKeyApplicationData, - CipherSpecRead, PR_TRUE); + CipherSpecRead, PR_FALSE); if (rv != SECSuccess) { FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error); return SECFailure; } - rv = tls13_FinishHandshake(ss); + if (IS_DTLS(ss)) { + ssl_CipherSpecReleaseByEpoch(ss, CipherSpecRead, TrafficKeyClearText); + /* We need to keep the handshake cipher spec so we can + * read re-transmitted client Finished. */ + rv = dtls_StartTimer(ss, ss->ssl3.hs.hdTimer, + DTLS_RETRANSMIT_FINISHED_MS, + dtls13_HolddownTimerCb); + if (rv != SECSuccess) { + return SECFailure; + } + } + + rv = tls13_ComputeFinalSecrets(ss); if (rv != SECSuccess) { - return SECFailure; /* Error code and alerts handled below */ + return SECFailure; } + ssl_GetXmitBufLock(ss); if (ss->opt.enableSessionTickets) { - rv = tls13_SendNewSessionTicket(ss); + rv = tls13_SendNewSessionTicket(ss, NULL, 0); if (rv != SECSuccess) { - ssl_ReleaseXmitBufLock(ss); - return SECFailure; /* Error code and alerts handled below */ + goto loser; } rv = ssl3_FlushHandshake(ss, 0); + if (rv != SECSuccess) { + goto loser; + } } ssl_ReleaseXmitBufLock(ss); - if (rv != SECSuccess) - return SECFailure; - return SECSuccess; + return tls13_FinishHandshake(ss); + +loser: + ssl_ReleaseXmitBufLock(ss); + return SECFailure; } static SECStatus tls13_FinishHandshake(sslSocket *ss) { - SECStatus rv; - PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss)); PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); PORT_Assert(ss->ssl3.hs.restartTarget == NULL); - rv = tls13_ComputeFinalSecrets(ss); - if (rv != SECSuccess) - return SECFailure; - /* The first handshake is now completed. */ ss->handshake = NULL; @@ -3652,9 +4269,15 @@ tls13_SendClientSecondFlight(sslSocket *ss, PRBool sendClientCert, return SECFailure; /* error code is set. */ } } - if (ss->ssl3.hs.certificateRequest) { - PORT_FreeArena(ss->ssl3.hs.certificateRequest->arena, PR_FALSE); - ss->ssl3.hs.certificateRequest = NULL; + if (ss->ssl3.hs.clientCertRequested) { + SECITEM_FreeItem(&ss->xtnData.certReqContext, PR_FALSE); + if (ss->xtnData.certReqAuthorities.arena) { + PORT_FreeArena(ss->xtnData.certReqAuthorities.arena, PR_FALSE); + ss->xtnData.certReqAuthorities.arena = NULL; + } + PORT_Memset(&ss->xtnData.certReqAuthorities, 0, + sizeof(ss->xtnData.certReqAuthorities)); + ss->ssl3.hs.clientCertRequested = PR_FALSE; } if (sendClientCert) { @@ -3670,7 +4293,7 @@ tls13_SendClientSecondFlight(sslSocket *ss, PRBool sendClientCert, if (rv != SECSuccess) { return SECFailure; /* err code was set. */ } - rv = ssl3_FlushHandshake(ss, IS_DTLS(ss) ? ssl_SEND_FLAG_NO_RETRANSMIT : 0); + rv = ssl3_FlushHandshake(ss, 0); if (rv != SECSuccess) { /* No point in sending an alert here because we're not going to * be able to send it if we couldn't flush the handshake. */ @@ -3678,11 +4301,6 @@ tls13_SendClientSecondFlight(sslSocket *ss, PRBool sendClientCert, return SECFailure; } - rv = dtls_StartHolddownTimer(ss); - if (rv != SECSuccess) { - return SECFailure; /* err code was set. */ - } - return SECSuccess; } @@ -3717,11 +4335,28 @@ tls13_SendClientSecondRound(sslSocket *ss) return SECWouldBlock; } + rv = tls13_ComputeApplicationSecrets(ss); + if (rv != SECSuccess) { + FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error); + return SECFailure; + } + if (ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted) { + ssl_GetXmitBufLock(ss); /*******************************/ rv = tls13_SendEndOfEarlyData(ss); + ssl_ReleaseXmitBufLock(ss); /*******************************/ if (rv != SECSuccess) { return SECFailure; /* Error code already set. */ } + } else if (ss->opt.enableTls13CompatMode && !IS_DTLS(ss) && + ss->ssl3.hs.zeroRttState == ssl_0rtt_none && + !ss->ssl3.hs.helloRetry) { + ssl_GetXmitBufLock(ss); /*******************************/ + rv = ssl3_SendChangeCipherSpecsInt(ss); + ssl_ReleaseXmitBufLock(ss); /*******************************/ + if (rv != SECSuccess) { + return rv; + } } rv = tls13_SetCipherSpec(ss, TrafficKeyHandshake, @@ -3731,12 +4366,6 @@ tls13_SendClientSecondRound(sslSocket *ss) return SECFailure; } - rv = tls13_ComputeApplicationSecrets(ss); - if (rv != SECSuccess) { - FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error); - return SECFailure; - } - rv = tls13_SetCipherSpec(ss, TrafficKeyApplicationData, CipherSpecRead, PR_FALSE); if (rv != SECSuccess) { @@ -3756,12 +4385,17 @@ tls13_SendClientSecondRound(sslSocket *ss) return SECFailure; } rv = tls13_SetCipherSpec(ss, TrafficKeyApplicationData, - CipherSpecWrite, PR_TRUE); + CipherSpecWrite, PR_FALSE); if (rv != SECSuccess) { PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); return SECFailure; } + rv = tls13_ComputeFinalSecrets(ss); + if (rv != SECSuccess) { + return SECFailure; + } + /* The handshake is now finished */ return tls13_FinishHandshake(ss); } @@ -3777,21 +4411,28 @@ tls13_SendClientSecondRound(sslSocket *ss) * struct { * uint32 ticket_lifetime; * uint32 ticket_age_add; + * opaque ticket_nonce<1..255>; * opaque ticket<1..2^16-1>; * TicketExtension extensions<0..2^16-2>; * } NewSessionTicket; */ -PRUint32 ssl_max_early_data_size = (2 << 16); /* Arbitrary limit. */ - -SECStatus -tls13_SendNewSessionTicket(sslSocket *ss) +static SECStatus +tls13_SendNewSessionTicket(sslSocket *ss, const PRUint8 *appToken, + unsigned int appTokenLen) { PRUint16 message_length; + PK11SymKey *secret; SECItem ticket_data = { 0, NULL, 0 }; SECStatus rv; NewSessionTicket ticket = { 0 }; PRUint32 max_early_data_size_len = 0; + PRUint8 ticketNonce[sizeof(ss->ssl3.hs.ticketNonce)]; + sslBuffer ticketNonceBuf = SSL_BUFFER(ticketNonce); + + SSL_TRC(3, ("%d: TLS13[%d]: send new session ticket message %d", + SSL_GETPID(), ss->fd, ss->ssl3.hs.ticketNonce)); + ticket.flags = 0; if (ss->opt.enable0RttData) { ticket.flags |= ticket_allow_early_data; @@ -3799,18 +4440,44 @@ tls13_SendNewSessionTicket(sslSocket *ss) } ticket.ticket_lifetime_hint = ssl_ticket_lifetime; - rv = ssl3_EncodeSessionTicket(ss, &ticket, &ticket_data); + /* The ticket age obfuscator. */ + rv = PK11_GenerateRandom((PRUint8 *)&ticket.ticket_age_add, + sizeof(ticket.ticket_age_add)); + if (rv != SECSuccess) + goto loser; + + rv = sslBuffer_AppendNumber(&ticketNonceBuf, ss->ssl3.hs.ticketNonce, + sizeof(ticketNonce)); + if (rv != SECSuccess) { + goto loser; + } + ++ss->ssl3.hs.ticketNonce; + rv = tls13_HkdfExpandLabel(ss->ssl3.hs.resumptionMasterSecret, + tls13_GetHash(ss), + ticketNonce, sizeof(ticketNonce), + kHkdfLabelResumption, + strlen(kHkdfLabelResumption), + tls13_GetHkdfMechanism(ss), + tls13_GetHashSize(ss), &secret); + if (rv != SECSuccess) { + goto loser; + } + + rv = ssl3_EncodeSessionTicket(ss, &ticket, appToken, appTokenLen, + secret, &ticket_data); + PK11_FreeSymKey(secret); if (rv != SECSuccess) goto loser; message_length = 4 + /* lifetime */ 4 + /* ticket_age_add */ + 1 + sizeof(ticketNonce) + /* ticket_nonce */ 2 + max_early_data_size_len + /* max_early_data_size_len */ 2 + /* ticket length */ ticket_data.len; - rv = ssl3_AppendHandshakeHeader(ss, new_session_ticket, + rv = ssl3_AppendHandshakeHeader(ss, ssl_hs_new_session_ticket, message_length); if (rv != SECSuccess) goto loser; @@ -3820,13 +4487,12 @@ tls13_SendNewSessionTicket(sslSocket *ss) if (rv != SECSuccess) goto loser; - /* The ticket age obfuscator. */ - rv = PK11_GenerateRandom((PRUint8 *)&ticket.ticket_age_add, - sizeof(ticket.ticket_age_add)); + rv = ssl3_AppendHandshakeNumber(ss, ticket.ticket_age_add, 4); if (rv != SECSuccess) goto loser; - rv = ssl3_AppendHandshakeNumber(ss, ticket.ticket_age_add, 4); + /* The ticket nonce. */ + rv = ssl3_AppendHandshakeVariable(ss, ticketNonce, sizeof(ticketNonce), 1); if (rv != SECSuccess) goto loser; @@ -3843,7 +4509,7 @@ tls13_SendNewSessionTicket(sslSocket *ss) if (max_early_data_size_len) { rv = ssl3_AppendHandshakeNumber( - ss, ssl_tls13_ticket_early_data_info_xtn, 2); + ss, ssl_tls13_early_data_xtn, 2); if (rv != SECSuccess) goto loser; @@ -3852,7 +4518,7 @@ tls13_SendNewSessionTicket(sslSocket *ss) if (rv != SECSuccess) goto loser; - rv = ssl3_AppendHandshakeNumber(ss, ssl_max_early_data_size, 4); + rv = ssl3_AppendHandshakeNumber(ss, ss->opt.maxEarlyDataSize, 4); if (rv != SECSuccess) goto loser; } @@ -3867,6 +4533,42 @@ loser: return SECFailure; } +SECStatus +SSLExp_SendSessionTicket(PRFileDesc *fd, const PRUint8 *token, + unsigned int tokenLen) +{ + sslSocket *ss; + SECStatus rv; + + ss = ssl_FindSocket(fd); + if (!ss) { + return SECFailure; + } + + if (IS_DTLS(ss)) { + PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_VERSION); + return SECFailure; + } + + if (!ss->sec.isServer || !ss->firstHsDone || + ss->version < SSL_LIBRARY_VERSION_TLS_1_3 || + tokenLen > 0xffff) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + + ssl_GetSSL3HandshakeLock(ss); + ssl_GetXmitBufLock(ss); + rv = tls13_SendNewSessionTicket(ss, token, tokenLen); + if (rv == SECSuccess) { + rv = ssl3_FlushHandshake(ss, 0); + } + ssl_ReleaseXmitBufLock(ss); + ssl_ReleaseSSL3HandshakeLock(ss); + + return rv; +} + static SECStatus tls13_HandleNewSessionTicket(sslSocket *ss, PRUint8 *b, PRUint32 length) { @@ -3874,6 +4576,7 @@ tls13_HandleNewSessionTicket(sslSocket *ss, PRUint8 *b, PRUint32 length) PRUint32 utmp; NewSessionTicket ticket = { 0 }; SECItem data; + SECItem ticket_nonce; SECItem ticket_data; SSL_TRC(3, ("%d: TLS13[%d]: handle new session ticket message", @@ -3890,7 +4593,7 @@ tls13_HandleNewSessionTicket(sslSocket *ss, PRUint8 *b, PRUint32 length) return SECFailure; } - ticket.received_timestamp = PR_Now(); + ticket.received_timestamp = ssl_TimeUsec(); rv = ssl3_ConsumeHandshakeNumber(ss, &ticket.ticket_lifetime_hint, 4, &b, &length); if (rv != SECSuccess) { @@ -3908,6 +4611,14 @@ tls13_HandleNewSessionTicket(sslSocket *ss, PRUint8 *b, PRUint32 length) } ticket.ticket_age_add = PR_ntohl(utmp); + /* The nonce. */ + rv = ssl3_ConsumeHandshakeVariable(ss, &ticket_nonce, 1, &b, &length); + if (rv != SECSuccess) { + FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_NEW_SESSION_TICKET, + decode_error); + return SECFailure; + } + /* Get the ticket value. */ rv = ssl3_ConsumeHandshakeVariable(ss, &ticket_data, 2, &b, &length); if (rv != SECSuccess || !ticket_data.len) { @@ -3918,14 +4629,14 @@ tls13_HandleNewSessionTicket(sslSocket *ss, PRUint8 *b, PRUint32 length) /* Parse extensions. */ rv = ssl3_ConsumeHandshakeVariable(ss, &data, 2, &b, &length); - if (rv != SECSuccess) { + if (rv != SECSuccess || length) { FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_NEW_SESSION_TICKET, decode_error); return SECFailure; } rv = ssl3_HandleExtensions(ss, &data.data, - &data.len, new_session_ticket); + &data.len, ssl_hs_new_session_ticket); if (rv != SECSuccess) { FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_NEW_SESSION_TICKET, decode_error); @@ -3936,13 +4647,9 @@ tls13_HandleNewSessionTicket(sslSocket *ss, PRUint8 *b, PRUint32 length) ticket.max_early_data_size = ss->xtnData.max_early_data_size; } - if (length != 0) { - FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_NEW_SESSION_TICKET, - decode_error); - return SECFailure; - } - if (!ss->opt.noCache) { + PK11SymKey *secret; + PORT_Assert(ss->sec.ci.sid); rv = SECITEM_CopyItem(NULL, &ticket.ticket, &ticket_data); if (rv != SECSuccess) { @@ -3971,7 +4678,7 @@ tls13_HandleNewSessionTicket(sslSocket *ss, PRUint8 *b, PRUint32 length) } /* Destroy the old SID. */ - ss->sec.uncache(ss->sec.ci.sid); + ssl_UncacheSessionID(ss); ssl_FreeSID(ss->sec.ci.sid); ss->sec.ci.sid = sid; } @@ -3979,122 +4686,124 @@ tls13_HandleNewSessionTicket(sslSocket *ss, PRUint8 *b, PRUint32 length) ssl3_SetSIDSessionTicket(ss->sec.ci.sid, &ticket); PORT_Assert(!ticket.ticket.data); - rv = ssl3_FillInCachedSID(ss, ss->sec.ci.sid); - if (rv != SECSuccess) + rv = tls13_HkdfExpandLabel(ss->ssl3.hs.resumptionMasterSecret, + tls13_GetHash(ss), + ticket_nonce.data, ticket_nonce.len, + kHkdfLabelResumption, + strlen(kHkdfLabelResumption), + tls13_GetHkdfMechanism(ss), + tls13_GetHashSize(ss), &secret); + if (rv != SECSuccess) { return SECFailure; + } + + rv = ssl3_FillInCachedSID(ss, ss->sec.ci.sid, secret); + PK11_FreeSymKey(secret); + if (rv != SECSuccess) { + return SECFailure; + } /* Cache the session. */ - ss->sec.cache(ss->sec.ci.sid); + ssl_CacheSessionID(ss); } return SECSuccess; } -typedef enum { - ExtensionNotUsed, - ExtensionClientOnly, - ExtensionSendClear, - ExtensionSendClearOrHrr, - ExtensionSendHrr, - ExtensionSendEncrypted, - ExtensionSendCertificate, - ExtensionNewSessionTicket -} Tls13ExtensionStatus; +#define _M(a) (1 << PR_MIN(a, 31)) +#define _M1(a) (_M(ssl_hs_##a)) +#define _M2(a, b) (_M1(a) | _M1(b)) +#define _M3(a, b, c) (_M1(a) | _M2(b, c)) static const struct { PRUint16 ex_value; - Tls13ExtensionStatus status; + PRUint32 messages; } KnownExtensions[] = { - { ssl_server_name_xtn, ExtensionSendEncrypted }, - { ssl_supported_groups_xtn, ExtensionSendEncrypted }, - { ssl_ec_point_formats_xtn, ExtensionNotUsed }, - { ssl_signature_algorithms_xtn, ExtensionClientOnly }, - { ssl_use_srtp_xtn, ExtensionSendEncrypted }, - { ssl_app_layer_protocol_xtn, ExtensionSendEncrypted }, - { ssl_padding_xtn, ExtensionNotUsed }, - { ssl_extended_master_secret_xtn, ExtensionNotUsed }, - { ssl_session_ticket_xtn, ExtensionClientOnly }, - { ssl_tls13_key_share_xtn, ExtensionSendClearOrHrr }, - { ssl_tls13_pre_shared_key_xtn, ExtensionSendClear }, - { ssl_tls13_early_data_xtn, ExtensionSendEncrypted }, - { ssl_next_proto_nego_xtn, ExtensionNotUsed }, - { ssl_renegotiation_info_xtn, ExtensionNotUsed }, - { ssl_signed_cert_timestamp_xtn, ExtensionSendCertificate }, - { ssl_cert_status_xtn, ExtensionSendCertificate }, - { ssl_tls13_ticket_early_data_info_xtn, ExtensionNewSessionTicket }, - { ssl_tls13_cookie_xtn, ExtensionSendHrr }, - { ssl_tls13_short_header_xtn, ExtensionSendClear } + { ssl_server_name_xtn, _M2(client_hello, encrypted_extensions) }, + { ssl_supported_groups_xtn, _M2(client_hello, encrypted_extensions) }, + { ssl_signature_algorithms_xtn, _M2(client_hello, certificate_request) }, + { ssl_signature_algorithms_cert_xtn, _M2(client_hello, + certificate_request) }, + { ssl_use_srtp_xtn, _M2(client_hello, encrypted_extensions) }, + { ssl_app_layer_protocol_xtn, _M2(client_hello, encrypted_extensions) }, + { ssl_padding_xtn, _M1(client_hello) }, + { ssl_tls13_key_share_xtn, _M3(client_hello, server_hello, + hello_retry_request) }, + { ssl_tls13_pre_shared_key_xtn, _M2(client_hello, server_hello) }, + { ssl_tls13_psk_key_exchange_modes_xtn, _M1(client_hello) }, + { ssl_tls13_early_data_xtn, _M3(client_hello, encrypted_extensions, + new_session_ticket) }, + { ssl_signed_cert_timestamp_xtn, _M3(client_hello, certificate_request, + certificate) }, + { ssl_cert_status_xtn, _M3(client_hello, certificate_request, + certificate) }, + { 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) } }; -PRBool -tls13_ExtensionAllowed(PRUint16 extension, SSL3HandshakeType message) +tls13ExtensionStatus +tls13_ExtensionStatus(PRUint16 extension, SSLHandshakeType message) { unsigned int i; - PORT_Assert((message == client_hello) || - (message == server_hello) || - (message == hello_retry_request) || - (message == encrypted_extensions) || - (message == new_session_ticket) || - (message == certificate) || - (message == certificate_request)); + PORT_Assert((message == ssl_hs_client_hello) || + (message == ssl_hs_server_hello) || + (message == ssl_hs_hello_retry_request) || + (message == ssl_hs_encrypted_extensions) || + (message == ssl_hs_new_session_ticket) || + (message == ssl_hs_certificate) || + (message == ssl_hs_certificate_request)); for (i = 0; i < PR_ARRAY_SIZE(KnownExtensions); i++) { - if (KnownExtensions[i].ex_value == extension) + /* Hacky check for message numbers > 30. */ + PORT_Assert(!(KnownExtensions[i].messages & (1U << 31))); + if (KnownExtensions[i].ex_value == extension) { break; + } } - if (i == PR_ARRAY_SIZE(KnownExtensions)) { - /* We have never heard of this extension which is OK - * in client_hello and new_session_ticket. */ - return (message == client_hello) || - (message == new_session_ticket); - } - - switch (KnownExtensions[i].status) { - case ExtensionNotUsed: - return PR_FALSE; - case ExtensionClientOnly: - return message == client_hello; - case ExtensionSendClear: - return message == client_hello || - message == server_hello; - case ExtensionSendClearOrHrr: - return message == client_hello || - message == server_hello || - message == hello_retry_request; - case ExtensionSendHrr: - return message == client_hello || - message == hello_retry_request; - case ExtensionSendEncrypted: - return message == client_hello || - message == encrypted_extensions; - case ExtensionNewSessionTicket: - return message == new_session_ticket; - case ExtensionSendCertificate: - return message == client_hello || - message == certificate; + if (i >= PR_ARRAY_SIZE(KnownExtensions)) { + return tls13_extension_unknown; } - PORT_Assert(0); + /* Return "disallowed" if the message mask bit isn't set. */ + if (!(_M(message) & KnownExtensions[i].messages)) { + return tls13_extension_disallowed; + } - /* Not reached */ - return PR_TRUE; + return tls13_extension_allowed; } +#undef _M +#undef _M1 +#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. */ -static void -tls13_FormatAdditionalData(PRUint8 *aad, unsigned int length, - sslSequenceNumber seqNum) +static SECStatus +tls13_FormatAdditionalData(sslSocket *ss, PRUint8 *aad, unsigned int length, + DTLSEpoch epoch, sslSequenceNumber seqNum) { - PRUint8 *ptr = aad; + SECStatus rv; + sslBuffer buf = SSL_BUFFER_FIXED(aad, length); PORT_Assert(length == 8); - ptr = ssl_EncodeUintX(seqNum, 8, ptr); - PORT_Assert((ptr - aad) == length); + if (IS_DTLS(ss)) { + rv = sslBuffer_AppendNumber(&buf, epoch, 2); + if (rv != SECSuccess) { + return SECFailure; + } + } + rv = sslBuffer_AppendNumber(&buf, seqNum, IS_DTLS(ss) ? 6 : 8); + if (rv != SECSuccess) { + return SECFailure; + } + return SECSuccess; } PRInt32 @@ -4127,13 +4836,14 @@ tls13_ProtectRecord(sslSocket *ss, PRUint32 contentLen, sslBuffer *wrBuf) { - const ssl3BulkCipherDef *cipher_def = cwSpec->cipher_def; + const ssl3BulkCipherDef *cipher_def = cwSpec->cipherDef; const int tagLen = cipher_def->tag_size; SECStatus rv; - SSL_TRC(3, ("%d: TLS13[%d]: spec=%d (%s) protect record 0x%0llx len=%u", - SSL_GETPID(), ss->fd, cwSpec, cwSpec->phase, - cwSpec->write_seq_num, contentLen)); + 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)); if (contentLen + 1 + tagLen > wrBuf->space) { PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); @@ -4154,15 +4864,18 @@ tls13_ProtectRecord(sslSocket *ss, /* Add the content type at the end. */ wrBuf->buf[contentLen] = type; - tls13_FormatAdditionalData(aad, sizeof(aad), cwSpec->write_seq_num); - rv = cwSpec->aead( - ss->sec.isServer ? &cwSpec->server : &cwSpec->client, - PR_FALSE, /* do encrypt */ - wrBuf->buf, /* output */ - (int *)&wrBuf->len, /* out len */ - wrBuf->space, /* max out */ - wrBuf->buf, contentLen + 1, /* input */ - aad, sizeof(aad)); + rv = tls13_FormatAdditionalData(ss, aad, sizeof(aad), cwSpec->epoch, + cwSpec->seqNum); + 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)); if (rv != SECSuccess) { PORT_SetError(SSL_ERROR_ENCRYPTION_FAILURE); return SECFailure; @@ -4182,19 +4895,27 @@ tls13_ProtectRecord(sslSocket *ss, * 2. Call PORT_SetError() witn an appropriate code. */ SECStatus -tls13_UnprotectRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *plaintext, +tls13_UnprotectRecord(sslSocket *ss, + ssl3CipherSpec *spec, + SSL3Ciphertext *cText, sslBuffer *plaintext, SSL3AlertDescription *alert) { - ssl3CipherSpec *crSpec = ss->ssl3.crSpec; - const ssl3BulkCipherDef *cipher_def = crSpec->cipher_def; + const ssl3BulkCipherDef *cipher_def = spec->cipherDef; + sslSequenceNumber seqNum; PRUint8 aad[8]; SECStatus rv; *alert = bad_record_mac; /* Default alert for most issues. */ - SSL_TRC(3, ("%d: TLS13[%d]: spec=%d (%s) unprotect record 0x%0llx len=%u", - SSL_GETPID(), ss->fd, crSpec, crSpec->phase, - crSpec->read_seq_num, cText->buf->len)); + 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)); /* We can perform this test in variable time because the record's total * length and the ciphersuite are both public knowledge. */ @@ -4216,9 +4937,8 @@ tls13_UnprotectRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *plaintext return SECFailure; } - /* Check the version number in the record */ - if ((IS_DTLS(ss) && cText->version != kDtlsRecordVersion) || - (!IS_DTLS(ss) && cText->version != kTlsRecordVersion)) { + /* 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", @@ -4228,18 +4948,18 @@ tls13_UnprotectRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *plaintext /* Decrypt */ PORT_Assert(cipher_def->type == type_aead); - tls13_FormatAdditionalData(aad, sizeof(aad), - IS_DTLS(ss) ? cText->seq_num - : crSpec->read_seq_num); - rv = crSpec->aead( - ss->sec.isServer ? &crSpec->client : &crSpec->server, - PR_TRUE, /* do decrypt */ - plaintext->buf, /* out */ - (int *)&plaintext->len, /* outlen */ - plaintext->space, /* maxout */ - cText->buf->buf, /* in */ - cText->buf->len, /* inlen */ - aad, sizeof(aad)); + rv = tls13_FormatAdditionalData(ss, aad, sizeof(aad), spec->epoch, seqNum); + if (rv != SECSuccess) { + return SECFailure; + } + rv = spec->aead(&spec->keyMaterial, + PR_TRUE, /* do decrypt */ + plaintext->buf, /* out */ + (int *)&plaintext->len, /* outlen */ + plaintext->space, /* maxout */ + cText->buf->buf, /* in */ + cText->buf->len, /* inlen */ + aad, sizeof(aad)); if (rv != SECSuccess) { SSL_TRC(3, ("%d: TLS13[%d]: record has bogus MAC", @@ -4271,14 +4991,14 @@ tls13_UnprotectRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *plaintext --plaintext->len; /* Check that we haven't received too much 0-RTT data. */ - if (crSpec->epoch == TrafficKeyEarlyApplicationData && + if (spec->epoch == TrafficKeyEarlyApplicationData && cText->type == content_application_data) { - if (plaintext->len > crSpec->earlyDataRemaining) { + if (plaintext->len > spec->earlyDataRemaining) { *alert = unexpected_message; PORT_SetError(SSL_ERROR_TOO_MUCH_EARLY_DATA); return SECFailure; } - crSpec->earlyDataRemaining -= plaintext->len; + spec->earlyDataRemaining -= plaintext->len; } SSL_TRC(10, @@ -4326,7 +5046,7 @@ tls13_MaybeDo0RTTHandshake(sslSocket *ss) /* Don't do anything if there is no early_data xtn, which means we're * not doing early data. */ - if (!ssl3_ClientExtensionAdvertised(ss, ssl_tls13_early_data_xtn)) { + if (!ssl3_ExtensionAdvertised(ss, ssl_tls13_early_data_xtn)) { return SECSuccess; } @@ -4341,25 +5061,41 @@ tls13_MaybeDo0RTTHandshake(sslSocket *ss) ss->xtnData.nextProtoState = SSL_NEXT_PROTO_EARLY_VALUE; rv = SECITEM_CopyItem(NULL, &ss->xtnData.nextProto, &ss->sec.ci.sid->u.ssl3.alpnSelection); - if (rv != SECSuccess) - return rv; + if (rv != SECSuccess) { + return SECFailure; + } + } + + if (ss->opt.enableTls13CompatMode && !IS_DTLS(ss)) { + /* Pretend that this is a proper ChangeCipherSpec even though it is sent + * before receiving the ServerHello. */ + ssl_GetSpecWriteLock(ss); + tls13_SetSpecRecordVersion(ss, ss->ssl3.cwSpec); + ssl_ReleaseSpecWriteLock(ss); + ssl_GetXmitBufLock(ss); + rv = ssl3_SendChangeCipherSpecsInt(ss); + ssl_ReleaseXmitBufLock(ss); + if (rv != SECSuccess) { + return SECFailure; + } } /* Cipher suite already set in tls13_SetupClientHello. */ ss->ssl3.hs.preliminaryInfo = 0; - rv = tls13_DeriveSecret(ss, ss->ssl3.hs.currentSecret, - kHkdfLabelClient, - kHkdfLabelEarlyTrafficSecret, - NULL, - &ss->ssl3.hs.clientEarlyTrafficSecret); - if (rv != SECSuccess) + rv = tls13_DeriveEarlySecrets(ss); + if (rv != SECSuccess) { return SECFailure; + } + + /* Save cwSpec in case we get a HelloRetryRequest and have to send another + * ClientHello. */ + ssl_CipherSpecAddRef(ss->ssl3.cwSpec); rv = tls13_SetCipherSpec(ss, TrafficKeyEarlyApplicationData, CipherSpecWrite, PR_TRUE); if (rv != SECSuccess) { - return rv; + return SECFailure; } return SECSuccess; @@ -4392,32 +5128,45 @@ tls13_SendEndOfEarlyData(sslSocket *ss) { SECStatus rv; - SSL_TRC(3, ("%d: TLS13[%d]: send end_of_early_data extension", - SSL_GETPID(), ss->fd)); + SSL_TRC(3, ("%d: TLS13[%d]: send EndOfEarlyData", SSL_GETPID(), ss->fd)); + PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); - rv = SSL3_SendAlert(ss, alert_warning, end_of_early_data); + rv = ssl3_AppendHandshakeHeader(ss, ssl_hs_end_of_early_data, 0); if (rv != SECSuccess) { - FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error); - return SECFailure; + return rv; /* err set by AppendHandshake. */ } ss->ssl3.hs.zeroRttState = ssl_0rtt_done; return SECSuccess; } -SECStatus -tls13_HandleEndOfEarlyData(sslSocket *ss) +static SECStatus +tls13_HandleEndOfEarlyData(sslSocket *ss, PRUint8 *b, PRUint32 length) { SECStatus rv; - if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3 || - ss->ssl3.hs.zeroRttState != ssl_0rtt_accepted) { - (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message); - PORT_SetError(SSL_ERROR_END_OF_EARLY_DATA_ALERT); + PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_TLS_1_3); + + rv = TLS13_CHECK_HS_STATE(ss, SSL_ERROR_RX_UNEXPECTED_END_OF_EARLY_DATA, + wait_end_of_early_data); + if (rv != SECSuccess) { return SECFailure; } - PORT_Assert(TLS13_IN_HS_STATE(ss, ss->opt.requestCertificate ? wait_client_cert : wait_finished)); + /* We shouldn't be getting any more early data, and if we do, + * it is because of reordering and we drop it. */ + if (IS_DTLS(ss)) { + ssl_CipherSpecReleaseByEpoch(ss, CipherSpecRead, + TrafficKeyEarlyApplicationData); + dtls_ReceivedFirstMessageInFlight(ss); + } + + PORT_Assert(ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted); + + if (length) { + FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_END_OF_EARLY_DATA, decode_error); + return SECFailure; + } rv = tls13_SetCipherSpec(ss, TrafficKeyHandshake, CipherSpecRead, PR_FALSE); @@ -4427,6 +5176,9 @@ tls13_HandleEndOfEarlyData(sslSocket *ss) } ss->ssl3.hs.zeroRttState = ssl_0rtt_done; + TLS13_SET_HS_STATE(ss, + ss->opt.requestCertificate ? wait_client_cert + : wait_finished); return SECSuccess; } @@ -4477,11 +5229,11 @@ tls13_EncodeDraftVersion(SSL3ProtocolVersion version) /* Pick the highest version we support that is also advertised. */ SECStatus -tls13_NegotiateVersion(sslSocket *ss, const TLSExtension *supported_versions) +tls13_NegotiateVersion(sslSocket *ss, const TLSExtension *supportedVersions) { PRUint16 version; - /* Make a copy so we're nondestructive*/ - SECItem data = supported_versions->data; + /* Make a copy so we're nondestructive. */ + SECItem data = supportedVersions->data; SECItem versions; SECStatus rv; @@ -4511,3 +5263,22 @@ tls13_NegotiateVersion(sslSocket *ss, const TLSExtension *supported_versions) FATAL_ERROR(ss, SSL_ERROR_UNSUPPORTED_VERSION, protocol_version); return SECFailure; } + +/* This is TLS 1.3 or might negotiate to it. */ +PRBool +tls13_MaybeTls13(sslSocket *ss) +{ + if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) { + return PR_TRUE; + } + + if (ss->vrange.max < SSL_LIBRARY_VERSION_TLS_1_3) { + return PR_FALSE; + } + + if (!(ss->ssl3.hs.preliminaryInfo & ssl_preinfo_version)) { + return PR_TRUE; + } + + return PR_FALSE; +} diff --git a/security/nss/lib/ssl/tls13con.h b/security/nss/lib/ssl/tls13con.h index 92eb545b0..1aaffb651 100644 --- a/security/nss/lib/ssl/tls13con.h +++ b/security/nss/lib/ssl/tls13con.h @@ -9,15 +9,25 @@ #ifndef __tls13con_h_ #define __tls13con_h_ +#include "sslexp.h" +#include "sslspec.h" + +typedef enum { + tls13_extension_allowed, + tls13_extension_disallowed, + tls13_extension_unknown +} tls13ExtensionStatus; + typedef enum { - StaticSharedSecret, - EphemeralSharedSecret -} SharedSecretType; + update_not_requested = 0, + update_requested = 1 +} tls13KeyUpdateRequest; #define TLS13_MAX_FINISHED_SIZE 64 SECStatus tls13_UnprotectRecord( - sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *plaintext, + sslSocket *ss, ssl3CipherSpec *spec, + SSL3Ciphertext *cText, sslBuffer *plaintext, SSL3AlertDescription *alert); #if defined(WIN32) @@ -41,6 +51,14 @@ SSLHashType tls13_GetHash(const sslSocket *ss); unsigned int tls13_GetHashSizeForHash(SSLHashType hash); unsigned int tls13_GetHashSize(const sslSocket *ss); CK_MECHANISM_TYPE tls13_GetHkdfMechanism(sslSocket *ss); +SECStatus tls13_ComputeHash(sslSocket *ss, SSL3Hashes *hashes, + const PRUint8 *buf, unsigned int len); +SECStatus tls13_ComputeHandshakeHashes(sslSocket *ss, + SSL3Hashes *hashes); +SECStatus tls13_DeriveSecretNullHash(sslSocket *ss, PK11SymKey *key, + const char *label, + unsigned int labelLen, + PK11SymKey **dest); void tls13_FatalError(sslSocket *ss, PRErrorCode prError, SSL3AlertDescription desc); SECStatus tls13_SetupClientHello(sslSocket *ss); @@ -49,27 +67,30 @@ PRInt32 tls13_LimitEarlyData(sslSocket *ss, SSL3ContentType type, PRInt32 toSend PRBool tls13_AllowPskCipher(const sslSocket *ss, const ssl3CipherSuiteDef *cipher_def); PRBool tls13_PskSuiteEnabled(sslSocket *ss); -SECStatus tls13_ComputePskBinder(sslSocket *ss, PRBool sending, - unsigned int prefixLength, - PRUint8 *output, unsigned int *outputLen, - unsigned int maxOutputLen); +SECStatus tls13_WriteExtensionsWithBinder(sslSocket *ss, sslBuffer *extensions); SECStatus tls13_HandleClientHelloPart2(sslSocket *ss, const SECItem *suites, - sslSessionID *sid); + sslSessionID *sid, + const PRUint8 *msg, + unsigned int len); SECStatus tls13_HandleServerHelloPart2(sslSocket *ss); SECStatus tls13_HandlePostHelloHandshakeMessage(sslSocket *ss, PRUint8 *b, - PRUint32 length, - SSL3Hashes *hashesPtr); -SECStatus tls13_HandleHelloRetryRequest(sslSocket *ss, PRUint8 *b, + PRUint32 length); +SECStatus tls13_ConstructHelloRetryRequest(sslSocket *ss, + ssl3CipherSuite cipherSuite, + const sslNamedGroupDef *selectedGroup, + PRUint8 *cookie, + unsigned int cookieLen, + sslBuffer *buffer); +SECStatus tls13_HandleHelloRetryRequest(sslSocket *ss, const PRUint8 *b, PRUint32 length); void tls13_DestroyKeyShareEntry(TLS13KeyShareEntry *entry); void tls13_DestroyKeyShares(PRCList *list); SECStatus tls13_CreateKeyShare(sslSocket *ss, const sslNamedGroupDef *groupDef); void tls13_DestroyEarlyData(PRCList *list); -void tls13_CipherSpecAddRef(ssl3CipherSpec *spec); -void tls13_CipherSpecRelease(ssl3CipherSpec *spec); -void tls13_DestroyCipherSpecs(PRCList *list); -PRBool tls13_ExtensionAllowed(PRUint16 extension, SSL3HandshakeType message); +SECStatus tls13_SetAlertCipherSpec(sslSocket *ss); +tls13ExtensionStatus tls13_ExtensionStatus(PRUint16 extension, + SSLHandshakeType message); SECStatus tls13_ProtectRecord(sslSocket *ss, ssl3CipherSpec *cwSpec, SSL3ContentType type, @@ -77,13 +98,25 @@ SECStatus tls13_ProtectRecord(sslSocket *ss, PRUint32 contentLen, sslBuffer *wrBuf); PRInt32 tls13_Read0RttData(sslSocket *ss, void *buf, PRInt32 len); -SECStatus tls13_HandleEndOfEarlyData(sslSocket *ss); SECStatus tls13_HandleEarlyApplicationData(sslSocket *ss, sslBuffer *origBuf); PRBool tls13_ClientAllow0Rtt(const sslSocket *ss, const sslSessionID *sid); PRUint16 tls13_EncodeDraftVersion(SSL3ProtocolVersion version); -PRUint16 tls13_DecodeDraftVersion(PRUint16 version); SECStatus tls13_NegotiateVersion(sslSocket *ss, const TLSExtension *supported_versions); -SECStatus tls13_SendNewSessionTicket(sslSocket *ss); + +PRBool tls13_IsReplay(const sslSocket *ss, const sslSessionID *sid); +void tls13_AntiReplayRollover(PRTime now); + +SECStatus SSLExp_SetupAntiReplay(PRTime window, unsigned int k, + unsigned int bits); + +SECStatus SSLExp_HelloRetryRequestCallback(PRFileDesc *fd, + SSLHelloRetryRequestCallback cb, + void *arg); +SECStatus tls13_SendKeyUpdate(sslSocket *ss, tls13KeyUpdateRequest request, + PRBool buffer); +SECStatus SSLExp_KeyUpdate(PRFileDesc *fd, PRBool requestUpdate); +PRBool tls13_MaybeTls13(sslSocket *ss); +void tls13_SetSpecRecordVersion(sslSocket *ss, ssl3CipherSpec *spec); #endif /* __tls13con_h_ */ diff --git a/security/nss/lib/ssl/tls13err.h b/security/nss/lib/ssl/tls13err.h new file mode 100644 index 000000000..8cdeb12eb --- /dev/null +++ b/security/nss/lib/ssl/tls13err.h @@ -0,0 +1,28 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is PRIVATE to SSL. + * + * 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 __tls13err_h_ +#define __tls13err_h_ + +/* Use this instead of FATAL_ERROR when an alert isn't possible. */ +#define LOG_ERROR(ss, prError) \ + do { \ + SSL_TRC(3, ("%d: TLS13[%d]: fatal error %d in %s (%s:%d)", \ + SSL_GETPID(), ss->fd, prError, __func__, __FILE__, __LINE__)); \ + PORT_SetError(prError); \ + } while (0) + +/* Log an error and generate an alert because something is irreparably wrong. */ +#define FATAL_ERROR(ss, prError, desc) \ + do { \ + LOG_ERROR(ss, prError); \ + tls13_FatalError(ss, prError, desc); \ + } while (0) + +void tls13_FatalError(sslSocket *ss, PRErrorCode prError, SSL3AlertDescription desc); +#endif diff --git a/security/nss/lib/ssl/tls13exthandle.c b/security/nss/lib/ssl/tls13exthandle.c index c2ce390ff..899f23827 100644 --- a/security/nss/lib/ssl/tls13exthandle.c +++ b/security/nss/lib/ssl/tls13exthandle.c @@ -14,50 +14,35 @@ #include "ssl3exthandle.h" #include "tls13exthandle.h" -PRInt32 -tls13_ServerSendStatusRequestXtn( - const sslSocket *ss, - TLSExtensionData *xtnData, - PRBool append, - PRUint32 maxBytes) +SECStatus +tls13_ServerSendStatusRequestXtn(const sslSocket *ss, TLSExtensionData *xtnData, + sslBuffer *buf, PRBool *added) { - PRInt32 extension_length; const sslServerCert *serverCert = ss->sec.serverCert; const SECItem *item; SECStatus rv; if (!serverCert->certStatusArray || !serverCert->certStatusArray->len) { - return 0; + return SECSuccess; } item = &serverCert->certStatusArray->items[0]; /* Only send the first entry. */ - extension_length = 2 + 2 + 1 /* status_type */ + 3 + item->len; - if (maxBytes < (PRUint32)extension_length) { - return 0; + /* status_type == ocsp */ + rv = sslBuffer_AppendNumber(buf, 1 /*ocsp*/, 1); + if (rv != SECSuccess) { + return SECFailure; } - if (append) { - /* extension_type */ - rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_cert_status_xtn, 2); - if (rv != SECSuccess) - return -1; - /* length of extension_data */ - rv = ssl3_ExtAppendHandshakeNumber(ss, extension_length - 4, 2); - if (rv != SECSuccess) - return -1; - /* status_type == ocsp */ - rv = ssl3_ExtAppendHandshakeNumber(ss, 1 /*ocsp*/, 1); - if (rv != SECSuccess) - return rv; /* err set by AppendHandshake. */ - /* opaque OCSPResponse<1..2^24-1> */ - rv = ssl3_ExtAppendHandshakeVariable(ss, item->data, item->len, 3); - if (rv != SECSuccess) - return rv; /* err set by AppendHandshake. */ + /* opaque OCSPResponse<1..2^24-1> */ + rv = sslBuffer_AppendVariable(buf, item->data, item->len, 3); + if (rv != SECSuccess) { + return SECFailure; } - return extension_length; + *added = PR_TRUE; + return SECSuccess; } /* @@ -101,41 +86,27 @@ tls13_SizeOfKeyShareEntry(const SECKEYPublicKey *pubKey) return 0; } -static PRUint32 -tls13_SizeOfClientKeyShareExtension(const sslSocket *ss) -{ - PRCList *cursor; - /* Size is: extension(2) + extension_len(2) + client_shares(2) */ - PRUint32 size = 2 + 2 + 2; - for (cursor = PR_NEXT_LINK(&ss->ephemeralKeyPairs); - cursor != &ss->ephemeralKeyPairs; - cursor = PR_NEXT_LINK(cursor)) { - sslEphemeralKeyPair *keyPair = (sslEphemeralKeyPair *)cursor; - size += tls13_SizeOfKeyShareEntry(keyPair->keys->pubKey); - } - return size; -} - static SECStatus -tls13_EncodeKeyShareEntry(const sslSocket *ss, const sslEphemeralKeyPair *keyPair) +tls13_EncodeKeyShareEntry(sslBuffer *buf, const sslEphemeralKeyPair *keyPair) { SECStatus rv; SECKEYPublicKey *pubKey = keyPair->keys->pubKey; unsigned int size = tls13_SizeOfKeyShareEntry(pubKey); - rv = ssl3_ExtAppendHandshakeNumber(ss, keyPair->group->name, 2); + rv = sslBuffer_AppendNumber(buf, keyPair->group->name, 2); if (rv != SECSuccess) return rv; - rv = ssl3_ExtAppendHandshakeNumber(ss, size - 4, 2); + rv = sslBuffer_AppendNumber(buf, size - 4, 2); if (rv != SECSuccess) return rv; switch (pubKey->keyType) { case ecKey: - rv = tls13_EncodeECDHEKeyShareKEX(ss, pubKey); + rv = sslBuffer_Append(buf, pubKey->u.ec.publicValue.data, + pubKey->u.ec.publicValue.len); break; case dhKey: - rv = ssl_AppendPaddedDHKeyShare(ss, pubKey, PR_FALSE); + rv = ssl_AppendPaddedDHKeyShare(buf, pubKey, PR_FALSE); break; default: PORT_Assert(0); @@ -146,14 +117,16 @@ tls13_EncodeKeyShareEntry(const sslSocket *ss, const sslEphemeralKeyPair *keyPai return rv; } -PRInt32 -tls13_ClientSendKeyShareXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, - PRUint32 maxBytes) +SECStatus +tls13_ClientSendKeyShareXtn(const sslSocket *ss, TLSExtensionData *xtnData, + sslBuffer *buf, PRBool *added) { - PRUint32 extension_length; + SECStatus rv; + PRCList *cursor; + unsigned int lengthOffset; if (ss->vrange.max < SSL_LIBRARY_VERSION_TLS_1_3) { - return 0; + return SECSuccess; } /* Optimistically try to send an ECDHE key using the @@ -161,47 +134,28 @@ tls13_ClientSendKeyShareXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBo SSL_TRC(3, ("%d: TLS13[%d]: send client key share xtn", SSL_GETPID(), ss->fd)); - extension_length = tls13_SizeOfClientKeyShareExtension(ss); - if (maxBytes < extension_length) { - PORT_Assert(0); - return 0; + /* Save the offset to the length. */ + rv = sslBuffer_Skip(buf, 2, &lengthOffset); + if (rv != SECSuccess) { + return SECFailure; } - if (append) { - SECStatus rv; - PRCList *cursor; - - rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_tls13_key_share_xtn, 2); - if (rv != SECSuccess) - goto loser; - - /* The extension length */ - rv = ssl3_ExtAppendHandshakeNumber(ss, extension_length - 4, 2); - if (rv != SECSuccess) - goto loser; - - /* The length of KeyShares */ - rv = ssl3_ExtAppendHandshakeNumber(ss, extension_length - 6, 2); - if (rv != SECSuccess) - goto loser; - - for (cursor = PR_NEXT_LINK(&ss->ephemeralKeyPairs); - cursor != &ss->ephemeralKeyPairs; - cursor = PR_NEXT_LINK(cursor)) { - sslEphemeralKeyPair *keyPair = (sslEphemeralKeyPair *)cursor; - rv = tls13_EncodeKeyShareEntry(ss, keyPair); - if (rv != SECSuccess) - goto loser; + for (cursor = PR_NEXT_LINK(&ss->ephemeralKeyPairs); + cursor != &ss->ephemeralKeyPairs; + cursor = PR_NEXT_LINK(cursor)) { + sslEphemeralKeyPair *keyPair = (sslEphemeralKeyPair *)cursor; + rv = tls13_EncodeKeyShareEntry(buf, keyPair); + if (rv != SECSuccess) { + return SECFailure; } - - xtnData->advertised[xtnData->numAdvertised++] = - ssl_tls13_key_share_xtn; + } + rv = sslBuffer_InsertLength(buf, lengthOffset, 2); + if (rv != SECSuccess) { + return SECFailure; } - return extension_length; - -loser: - return -1; + *added = PR_TRUE; + return SECSuccess; } static SECStatus @@ -250,7 +204,8 @@ loser: * |xtnData->remoteKeyShares| for future use. The key * share is processed in tls13_HandleServerKeyShare(). */ SECStatus -tls13_ClientHandleKeyShareXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data) +tls13_ClientHandleKeyShareXtn(const sslSocket *ss, TLSExtensionData *xtnData, + SECItem *data) { SECStatus rv; PORT_Assert(PR_CLIST_IS_EMPTY(&xtnData->remoteKeyShares)); @@ -281,7 +236,8 @@ tls13_ClientHandleKeyShareXtn(const sslSocket *ss, TLSExtensionData *xtnData, PR } SECStatus -tls13_ClientHandleKeyShareXtnHrr(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data) +tls13_ClientHandleKeyShareXtnHrr(const sslSocket *ss, TLSExtensionData *xtnData, + SECItem *data) { SECStatus rv; PRUint32 tmp; @@ -331,7 +287,8 @@ tls13_ClientHandleKeyShareXtnHrr(const sslSocket *ss, TLSExtensionData *xtnData, * |xtnData->remoteKeyShares| for future use. The key * share is processed in tls13_HandleClientKeyShare(). */ SECStatus -tls13_ServerHandleKeyShareXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data) +tls13_ServerHandleKeyShareXtn(const sslSocket *ss, TLSExtensionData *xtnData, + SECItem *data) { SECStatus rv; PRUint32 length; @@ -364,16 +321,6 @@ tls13_ServerHandleKeyShareXtn(const sslSocket *ss, TLSExtensionData *xtnData, PR goto loser; } - /* Check that the client only offered one share if this is - * after HRR. */ - if (ss->ssl3.hs.helloRetry) { - if (PR_PREV_LINK(&xtnData->remoteKeyShares) != - PR_NEXT_LINK(&xtnData->remoteKeyShares)) { - PORT_SetError(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO); - goto loser; - } - } - return SECSuccess; loser: @@ -381,12 +328,10 @@ loser: return SECFailure; } -PRInt32 -tls13_ServerSendKeyShareXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, - PRUint32 maxBytes) +SECStatus +tls13_ServerSendKeyShareXtn(const sslSocket *ss, TLSExtensionData *xtnData, + sslBuffer *buf, PRBool *added) { - PRUint32 extension_length; - PRUint32 entry_length; SECStatus rv; sslEphemeralKeyPair *keyPair; @@ -397,31 +342,13 @@ tls13_ServerSendKeyShareXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBo keyPair = (sslEphemeralKeyPair *)PR_NEXT_LINK(&ss->ephemeralKeyPairs); - entry_length = tls13_SizeOfKeyShareEntry(keyPair->keys->pubKey); - extension_length = 2 + 2 + entry_length; /* Type + length + entry_length */ - if (maxBytes < extension_length) { - PORT_Assert(0); - return 0; - } - - if (append) { - rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_tls13_key_share_xtn, 2); - if (rv != SECSuccess) - goto loser; - - rv = ssl3_ExtAppendHandshakeNumber(ss, entry_length, 2); - if (rv != SECSuccess) - goto loser; - - rv = tls13_EncodeKeyShareEntry(ss, keyPair); - if (rv != SECSuccess) - goto loser; + rv = tls13_EncodeKeyShareEntry(buf, keyPair); + if (rv != SECSuccess) { + return SECFailure; } - return extension_length; - -loser: - return -1; + *added = PR_TRUE; + return SECSuccess; } /* Called by clients. @@ -448,113 +375,83 @@ loser: * Presently the only way to get a PSK is by resumption, so this is * really a ticket label and there will be at most one. */ -PRInt32 +SECStatus tls13_ClientSendPreSharedKeyXtn(const sslSocket *ss, TLSExtensionData *xtnData, - PRBool append, - PRUint32 maxBytes) + sslBuffer *buf, PRBool *added) { - PRInt32 extension_length; - PRInt32 identities_length; - PRInt32 binders_length; NewSessionTicket *session_ticket; + PRTime age; + const static PRUint8 binder[TLS13_MAX_FINISHED_SIZE] = { 0 }; + unsigned int binderLen; + SECStatus rv; /* We only set statelessResume on the client in TLS 1.3 code. */ - if (!ss->statelessResume) - return 0; + if (!ss->statelessResume) { + return SECSuccess; + } + + /* Save where this extension starts so that if we have to add padding, it + * can be inserted before this extension. */ + PORT_Assert(buf->len >= 4); + xtnData->lastXtnOffset = buf->len - 4; PORT_Assert(ss->vrange.max >= SSL_LIBRARY_VERSION_TLS_1_3); - /* The length computations are simplified by the fact that there - * is just one ticket at most. */ + /* Send a single ticket identity. */ session_ticket = &ss->sec.ci.sid->u.ssl3.locked.sessionTicket; - identities_length = - 2 + /* vector length */ - 2 + session_ticket->ticket.len + /* identity length + ticket len */ - 4; /* obfuscated_ticket_age */ - binders_length = - 2 + /* vector length */ - 1 + tls13_GetHashSizeForHash( - tls13_GetHashForCipherSuite(ss->sec.ci.sid->u.ssl3.cipherSuite)); - extension_length = - 2 + 2 + /* Type + length */ - identities_length + binders_length; - - if (maxBytes < (PRUint32)extension_length) { - PORT_Assert(0); - return 0; - } - - if (append) { - SECStatus rv; - PRTime age; - unsigned int prefixLength; - PRUint8 binder[TLS13_MAX_FINISHED_SIZE]; - unsigned int binderLen; - - /* extension_type */ - rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_tls13_pre_shared_key_xtn, 2); - if (rv != SECSuccess) - goto loser; - rv = ssl3_ExtAppendHandshakeNumber(ss, extension_length - 4, 2); - if (rv != SECSuccess) - goto loser; - rv = ssl3_ExtAppendHandshakeNumber(ss, identities_length - 2, 2); - if (rv != SECSuccess) - goto loser; - rv = ssl3_ExtAppendHandshakeVariable(ss, session_ticket->ticket.data, - session_ticket->ticket.len, 2); - if (rv != SECSuccess) - goto loser; + rv = sslBuffer_AppendNumber(buf, 2 + /* identity length */ + session_ticket->ticket.len + /* ticket */ + 4 /* obfuscated_ticket_age */, + 2); + if (rv != SECSuccess) + goto loser; + rv = sslBuffer_AppendVariable(buf, session_ticket->ticket.data, + session_ticket->ticket.len, 2); + if (rv != SECSuccess) + goto loser; - /* Obfuscated age. */ - age = PR_Now() - session_ticket->received_timestamp; - age /= PR_USEC_PER_MSEC; - age += session_ticket->ticket_age_add; - rv = ssl3_ExtAppendHandshakeNumber(ss, age, 4); - if (rv != SECSuccess) - goto loser; + /* Obfuscated age. */ + age = ssl_TimeUsec() - session_ticket->received_timestamp; + age /= PR_USEC_PER_MSEC; + age += session_ticket->ticket_age_add; + rv = sslBuffer_AppendNumber(buf, age, 4); + if (rv != SECSuccess) + goto loser; - /* Now the binders. */ - prefixLength = ss->ssl3.hs.messages.len; - rv = tls13_ComputePskBinder(CONST_CAST(sslSocket, ss), PR_TRUE, - prefixLength, binder, &binderLen, - sizeof(binder)); - if (rv != SECSuccess) - goto loser; - PORT_Assert(binderLen == tls13_GetHashSize(ss)); - rv = ssl3_ExtAppendHandshakeNumber(ss, binders_length - 2, 2); - if (rv != SECSuccess) - goto loser; - rv = ssl3_ExtAppendHandshakeVariable(ss, - binder, binderLen, 1); - if (rv != SECSuccess) - goto loser; + /* Write out the binder list length. */ + binderLen = tls13_GetHashSize(ss); + rv = sslBuffer_AppendNumber(buf, binderLen + 1, 2); + if (rv != SECSuccess) + goto loser; + /* Write zeroes for the binder for the moment. */ + rv = sslBuffer_AppendVariable(buf, binder, binderLen, 1); + if (rv != SECSuccess) + goto loser; - PRINT_BUF(50, (ss, "Sending PreSharedKey value", - session_ticket->ticket.data, - session_ticket->ticket.len)); + PRINT_BUF(50, (ss, "Sending PreSharedKey value", + session_ticket->ticket.data, + session_ticket->ticket.len)); - xtnData->sentSessionTicketInClientHello = PR_TRUE; - xtnData->advertised[xtnData->numAdvertised++] = - ssl_tls13_pre_shared_key_xtn; - } - return extension_length; + xtnData->sentSessionTicketInClientHello = PR_TRUE; + *added = PR_TRUE; + return SECSuccess; loser: xtnData->ticketTimestampVerified = PR_FALSE; - return -1; + return SECFailure; } /* Handle a TLS 1.3 PreSharedKey Extension. We only accept PSKs * that contain session tickets. */ SECStatus -tls13_ServerHandlePreSharedKeyXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, +tls13_ServerHandlePreSharedKeyXtn(const sslSocket *ss, TLSExtensionData *xtnData, SECItem *data) { SECItem inner; SECStatus rv; unsigned int numIdentities = 0; unsigned int numBinders = 0; + SECItem *appToken; SSL_TRC(3, ("%d: SSL3[%d]: handle pre_shared_key extension", SSL_GETPID(), ss->fd)); @@ -564,16 +461,26 @@ tls13_ServerHandlePreSharedKeyXtn(const sslSocket *ss, TLSExtensionData *xtnData return SECSuccess; } + /* The application token is set via the cookie extension if this is the + * second ClientHello. Don't set it twice. The cookie extension handler + * sets |helloRetry| and that will have been called already because this + * extension always comes last. */ + if (!ss->ssl3.hs.helloRetry) { + appToken = &xtnData->applicationToken; + } else { + appToken = NULL; + } + /* Parse the identities list. */ - rv = ssl3_ExtConsumeHandshakeVariable(ss, - &inner, 2, &data->data, &data->len); + rv = ssl3_ExtConsumeHandshakeVariable(ss, &inner, 2, + &data->data, &data->len); if (rv != SECSuccess) { return SECFailure; } while (inner.len) { SECItem label; - PRUint32 utmp; + PRUint32 obfuscatedAge; rv = ssl3_ExtConsumeHandshakeVariable(ss, &label, 2, &inner.data, &inner.len); @@ -583,9 +490,8 @@ tls13_ServerHandlePreSharedKeyXtn(const sslSocket *ss, TLSExtensionData *xtnData goto alert_loser; } - /* Read and discard session ticket age. Bug 1295163 */ - rv = ssl3_ExtConsumeHandshake(ss, &utmp, 4, - &inner.data, &inner.len); + rv = ssl3_ExtConsumeHandshakeNumber(ss, &obfuscatedAge, 4, + &inner.data, &inner.len); if (rv != SECSuccess) return rv; @@ -593,17 +499,29 @@ tls13_ServerHandlePreSharedKeyXtn(const sslSocket *ss, TLSExtensionData *xtnData PRINT_BUF(50, (ss, "Handling PreSharedKey value", label.data, label.len)); rv = ssl3_ProcessSessionTicketCommon( - CONST_CAST(sslSocket, ss), &label); + CONST_CAST(sslSocket, ss), &label, appToken); /* This only happens if we have an internal error, not * a malformed ticket. Bogus tickets just don't resume * and return SECSuccess. */ if (rv != SECSuccess) return SECFailure; + + if (ss->sec.ci.sid) { + /* xtnData->ticketAge contains the baseline we use for + * calculating the ticket age (i.e., our RTT estimate less the + * value of ticket_age_add). + * + * Add that to the obfuscated ticket age to recover the client's + * view of the ticket age plus the estimated RTT. + * + * See ssl3_EncodeSessionTicket() for details. */ + xtnData->ticketAge += obfuscatedAge; + } } ++numIdentities; } - xtnData->pskBinderPrefixLen = ss->ssl3.hs.messages.len - data->len; + xtnData->pskBindersLen = data->len; /* Parse the binders list. */ rv = ssl3_ExtConsumeHandshakeVariable(ss, @@ -635,7 +553,7 @@ tls13_ServerHandlePreSharedKeyXtn(const sslSocket *ss, TLSExtensionData *xtnData /* Keep track of negotiated extensions. Note that this does not * mean we are resuming. */ - xtnData->negotiated[xtnData->numNegotiated++] = ex_type; + xtnData->negotiated[xtnData->numNegotiated++] = ssl_tls13_pre_shared_key_xtn; return SECSuccess; @@ -645,43 +563,27 @@ alert_loser: return SECFailure; } -PRInt32 +SECStatus tls13_ServerSendPreSharedKeyXtn(const sslSocket *ss, TLSExtensionData *xtnData, - PRBool append, - PRUint32 maxBytes) + sslBuffer *buf, PRBool *added) { - PRInt32 extension_length = - 2 + 2 + 2; /* type + len + index */ SECStatus rv; - if (maxBytes < (PRUint32)extension_length) { - PORT_Assert(0); - return 0; - } - - if (append) { - rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_tls13_pre_shared_key_xtn, 2); - if (rv != SECSuccess) - return -1; - - rv = ssl3_ExtAppendHandshakeNumber(ss, 2, 2); - if (rv != SECSuccess) - return -1; - - /* We only process the first session ticket the client sends, - * so the index is always 0. */ - rv = ssl3_ExtAppendHandshakeNumber(ss, 0, 2); - if (rv != SECSuccess) - return -1; + /* We only process the first session ticket the client sends, + * so the index is always 0. */ + rv = sslBuffer_AppendNumber(buf, 0, 2); + if (rv != SECSuccess) { + return SECFailure; } - return extension_length; + *added = PR_TRUE; + return SECSuccess; } /* Handle a TLS 1.3 PreSharedKey Extension. We only accept PSKs * that contain session tickets. */ SECStatus -tls13_ClientHandlePreSharedKeyXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, +tls13_ClientHandlePreSharedKeyXtn(const sslSocket *ss, TLSExtensionData *xtnData, SECItem *data) { PRUint32 index; @@ -713,7 +615,7 @@ tls13_ClientHandlePreSharedKeyXtn(const sslSocket *ss, TLSExtensionData *xtnData } /* Keep track of negotiated extensions. */ - xtnData->negotiated[xtnData->numNegotiated++] = ex_type; + xtnData->negotiated[xtnData->numNegotiated++] = ssl_tls13_pre_shared_key_xtn; return SECSuccess; } @@ -721,43 +623,20 @@ tls13_ClientHandlePreSharedKeyXtn(const sslSocket *ss, TLSExtensionData *xtnData /* * struct { } EarlyDataIndication; */ -PRInt32 +SECStatus tls13_ClientSendEarlyDataXtn(const sslSocket *ss, TLSExtensionData *xtnData, - PRBool append, - PRUint32 maxBytes) + sslBuffer *buf, PRBool *added) { - SECStatus rv; - PRInt32 extension_length; - - if (!tls13_ClientAllow0Rtt(ss, ss->sec.ci.sid)) - return 0; - - /* type + length */ - extension_length = 2 + 2; - - if (maxBytes < (PRUint32)extension_length) { - PORT_Assert(0); - return 0; - } - - if (append) { - rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_tls13_early_data_xtn, 2); - if (rv != SECSuccess) - return -1; - - rv = ssl3_ExtAppendHandshakeNumber(ss, 0, 2); - if (rv != SECSuccess) - return -1; - - xtnData->advertised[xtnData->numAdvertised++] = - ssl_tls13_early_data_xtn; + if (!tls13_ClientAllow0Rtt(ss, ss->sec.ci.sid)) { + return SECSuccess; } - return extension_length; + *added = PR_TRUE; + return SECSuccess; } SECStatus -tls13_ServerHandleEarlyDataXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, +tls13_ServerHandleEarlyDataXtn(const sslSocket *ss, TLSExtensionData *xtnData, SECItem *data) { SSL_TRC(3, ("%d: TLS13[%d]: handle early_data extension", @@ -779,44 +658,14 @@ tls13_ServerHandleEarlyDataXtn(const sslSocket *ss, TLSExtensionData *xtnData, P return SECFailure; } - xtnData->negotiated[xtnData->numNegotiated++] = ex_type; + xtnData->negotiated[xtnData->numNegotiated++] = ssl_tls13_early_data_xtn; return SECSuccess; } -/* This is only registered if we are sending it. */ -PRInt32 -tls13_ServerSendEarlyDataXtn(const sslSocket *ss, TLSExtensionData *xtnData, - PRBool append, - PRUint32 maxBytes) -{ - SSL_TRC(3, ("%d: TLS13[%d]: send early_data extension", - SSL_GETPID(), ss->fd)); - - PORT_Assert(ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted); - if (maxBytes < 4) { - PORT_Assert(0); - return 0; - } - - if (append) { - SECStatus rv; - - rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_tls13_early_data_xtn, 2); - if (rv != SECSuccess) - return -1; - - rv = ssl3_ExtAppendHandshakeNumber(ss, 0, 2); - if (rv != SECSuccess) - return -1; - } - - return 4; -} - /* This will only be called if we also offered the extension. */ SECStatus -tls13_ClientHandleEarlyDataXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, +tls13_ClientHandleEarlyDataXtn(const sslSocket *ss, TLSExtensionData *xtnData, SECItem *data) { SSL_TRC(3, ("%d: TLS13[%d]: handle early_data extension", @@ -834,19 +683,19 @@ tls13_ClientHandleEarlyDataXtn(const sslSocket *ss, TLSExtensionData *xtnData, P } /* Keep track of negotiated extensions. */ - xtnData->negotiated[xtnData->numNegotiated++] = ex_type; + xtnData->negotiated[xtnData->numNegotiated++] = ssl_tls13_early_data_xtn; return SECSuccess; } SECStatus -tls13_ClientHandleTicketEarlyDataInfoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, - SECItem *data) +tls13_ClientHandleTicketEarlyDataXtn(const sslSocket *ss, TLSExtensionData *xtnData, + SECItem *data) { PRUint32 utmp; SECStatus rv; - SSL_TRC(3, ("%d: TLS13[%d]: handle early_data_info extension", + SSL_TRC(3, ("%d: TLS13[%d]: handle ticket early_data extension", SSL_GETPID(), ss->fd)); /* The server must not send this extension when negotiating < TLS 1.3. */ @@ -873,59 +722,71 @@ tls13_ClientHandleTicketEarlyDataInfoXtn(const sslSocket *ss, TLSExtensionData * /* * struct { + * select (Handshake.msg_type) { + * case client_hello: * ProtocolVersion versions<2..254>; + * case server_hello: + * ProtocolVersion version; + * }; * } SupportedVersions; */ -PRInt32 -tls13_ClientSendSupportedVersionsXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, - PRUint32 maxBytes) +SECStatus +tls13_ClientSendSupportedVersionsXtn(const sslSocket *ss, TLSExtensionData *xtnData, + sslBuffer *buf, PRBool *added) { - PRInt32 extensions_len; PRUint16 version; + unsigned int lengthOffset; SECStatus rv; if (ss->vrange.max < SSL_LIBRARY_VERSION_TLS_1_3) { - return 0; + return SECSuccess; } - SSL_TRC(3, ("%d: TLS13[%d]: send supported_versions extension", + SSL_TRC(3, ("%d: TLS13[%d]: client send supported_versions extension", SSL_GETPID(), ss->fd)); - /* Extension type, extension len fiels, vector len field, - * length of the values. */ - extensions_len = 2 + 2 + 1 + - 2 * (ss->vrange.max - ss->vrange.min + 1); + rv = sslBuffer_Skip(buf, 1, &lengthOffset); + if (rv != SECSuccess) { + return SECFailure; + } - if (maxBytes < (PRUint32)extensions_len) { - PORT_Assert(0); - return 0; + for (version = ss->vrange.max; version >= ss->vrange.min; --version) { + rv = sslBuffer_AppendNumber(buf, tls13_EncodeDraftVersion(version), 2); + if (rv != SECSuccess) { + return SECFailure; + } } - if (append) { - rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_tls13_supported_versions_xtn, 2); - if (rv != SECSuccess) - return -1; + rv = sslBuffer_InsertLength(buf, lengthOffset, 1); + if (rv != SECSuccess) { + return SECFailure; + } - rv = ssl3_ExtAppendHandshakeNumber(ss, extensions_len - 4, 2); - if (rv != SECSuccess) - return -1; + *added = PR_TRUE; + return SECSuccess; +} - rv = ssl3_ExtAppendHandshakeNumber(ss, extensions_len - 5, 1); - if (rv != SECSuccess) - return -1; +SECStatus +tls13_ServerSendSupportedVersionsXtn(const sslSocket *ss, TLSExtensionData *xtnData, + sslBuffer *buf, PRBool *added) +{ + SECStatus rv; - for (version = ss->vrange.max; version >= ss->vrange.min; --version) { - rv = ssl3_ExtAppendHandshakeNumber( - ss, tls13_EncodeDraftVersion(version), 2); - if (rv != SECSuccess) - return -1; - } + if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) { + return SECSuccess; + } + + SSL_TRC(3, ("%d: TLS13[%d]: server send supported_versions extension", + SSL_GETPID(), ss->fd)); - xtnData->advertised[xtnData->numAdvertised++] = - ssl_tls13_supported_versions_xtn; + rv = sslBuffer_AppendNumber( + buf, tls13_EncodeDraftVersion(SSL_LIBRARY_VERSION_TLS_1_3), 2); + if (rv != SECSuccess) { + return SECFailure; } - return extensions_len; + *added = PR_TRUE; + return SECSuccess; } /* @@ -934,7 +795,8 @@ tls13_ClientSendSupportedVersionsXtn(const sslSocket *ss, TLSExtensionData *xtnD * } Cookie; */ SECStatus -tls13_ClientHandleHrrCookie(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data) +tls13_ClientHandleHrrCookie(const sslSocket *ss, TLSExtensionData *xtnData, + SECItem *data) { SECStatus rv; @@ -960,41 +822,57 @@ tls13_ClientHandleHrrCookie(const sslSocket *ss, TLSExtensionData *xtnData, PRUi return SECSuccess; } -PRInt32 -tls13_ClientSendHrrCookieXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes) +SECStatus +tls13_ClientSendHrrCookieXtn(const sslSocket *ss, TLSExtensionData *xtnData, + sslBuffer *buf, PRBool *added) { - PRInt32 extension_len; + SECStatus rv; if (ss->vrange.max < SSL_LIBRARY_VERSION_TLS_1_3 || !ss->ssl3.hs.cookie.len) { - return 0; + return SECSuccess; } SSL_TRC(3, ("%d: TLS13[%d]: send cookie extension", SSL_GETPID(), ss->fd)); + rv = sslBuffer_AppendVariable(buf, ss->ssl3.hs.cookie.data, + ss->ssl3.hs.cookie.len, 2); + if (rv != SECSuccess) { + return SECFailure; + } - /* Extension type, length, cookie length, cookie value. */ - extension_len = 2 + 2 + 2 + ss->ssl3.hs.cookie.len; + *added = PR_TRUE; + return SECSuccess; +} - if (maxBytes < (PRUint32)extension_len) { - PORT_Assert(0); - return 0; - } +SECStatus +tls13_ServerHandleCookieXtn(const sslSocket *ss, TLSExtensionData *xtnData, + SECItem *data) +{ + SECStatus rv; - if (append) { - SECStatus rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_tls13_cookie_xtn, 2); - if (rv != SECSuccess) - return -1; + SSL_TRC(3, ("%d: TLS13[%d]: handle cookie extension", + SSL_GETPID(), ss->fd)); - rv = ssl3_ExtAppendHandshakeNumber(ss, extension_len - 4, 2); - if (rv != SECSuccess) - return -1; + rv = ssl3_ExtConsumeHandshakeVariable(ss, &xtnData->cookie, 2, + &data->data, &data->len); + if (rv != SECSuccess) { + return SECFailure; + } - rv = ssl3_ExtAppendHandshakeVariable(ss, ss->ssl3.hs.cookie.data, - ss->ssl3.hs.cookie.len, 2); - if (rv != SECSuccess) - return -1; + if (xtnData->cookie.len == 0) { + PORT_SetError(SSL_ERROR_RX_MALFORMED_SERVER_HELLO); + return SECFailure; } - return extension_len; + + if (data->len) { + PORT_SetError(SSL_ERROR_RX_MALFORMED_SERVER_HELLO); + return SECFailure; + } + + /* Keep track of negotiated extensions. */ + xtnData->negotiated[xtnData->numNegotiated++] = ssl_tls13_cookie_xtn; + + return SECSuccess; } /* @@ -1004,54 +882,33 @@ tls13_ClientSendHrrCookieXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRB * PskKeyExchangeMode ke_modes<1..255>; * } PskKeyExchangeModes; */ -PRInt32 -tls13_ClientSendPskKeyExchangeModesXtn(const sslSocket *ss, - TLSExtensionData *xtnData, - PRBool append, PRUint32 maxBytes) +SECStatus +tls13_ClientSendPskModesXtn(const sslSocket *ss, TLSExtensionData *xtnData, + sslBuffer *buf, PRBool *added) { static const PRUint8 ke_modes[] = { tls13_psk_dh_ke }; - static const unsigned long ke_modes_len = sizeof(ke_modes); - PRInt32 extension_len; + SECStatus rv; if (ss->vrange.max < SSL_LIBRARY_VERSION_TLS_1_3 || ss->opt.noCache) { - return 0; + return SECSuccess; } - extension_len = - 2 + 2 + /* Type + length */ - 1 + ke_modes_len; /* key exchange modes vector */ - SSL_TRC(3, ("%d: TLS13[%d]: send psk key exchange modes extension", SSL_GETPID(), ss->fd)); - if (maxBytes < (PRUint32)extension_len) { - PORT_Assert(0); - return 0; + rv = sslBuffer_AppendVariable(buf, ke_modes, sizeof(ke_modes), 1); + if (rv != SECSuccess) { + return SECFailure; } - if (append) { - SECStatus rv = ssl3_ExtAppendHandshakeNumber( - ss, ssl_tls13_psk_key_exchange_modes_xtn, 2); - if (rv != SECSuccess) - return -1; - - rv = ssl3_ExtAppendHandshakeNumber(ss, extension_len - 4, 2); - if (rv != SECSuccess) - return -1; - - rv = ssl3_ExtAppendHandshakeVariable( - ss, ke_modes, ke_modes_len, 1); - if (rv != SECSuccess) - return -1; - } - return extension_len; + *added = PR_TRUE; + return SECSuccess; } SECStatus -tls13_ServerHandlePskKeyExchangeModesXtn(const sslSocket *ss, - TLSExtensionData *xtnData, - PRUint16 ex_type, SECItem *data) +tls13_ServerHandlePskModesXtn(const sslSocket *ss, TLSExtensionData *xtnData, + SECItem *data) { SECStatus rv; @@ -1076,112 +933,126 @@ tls13_ServerHandlePskKeyExchangeModesXtn(const sslSocket *ss, } /* Keep track of negotiated extensions. */ - xtnData->negotiated[xtnData->numNegotiated++] = ex_type; + xtnData->negotiated[xtnData->numNegotiated++] = + ssl_tls13_psk_key_exchange_modes_xtn; return SECSuccess; } -PRInt32 -tls13_SendShortHeaderXtn(const sslSocket *ss, - TLSExtensionData *xtnData, - PRBool append, PRUint32 maxBytes) +SECStatus +tls13_SendCertAuthoritiesXtn(const sslSocket *ss, TLSExtensionData *xtnData, + sslBuffer *buf, PRBool *added) { - PRUint32 extension_len = 2 + 2; /* Type + length (0). */ + unsigned int calen; + const SECItem *name; + unsigned int nnames; + SECStatus rv; - if (!ss->opt.enableShortHeaders) { - return 0; - } + PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_TLS_1_3); - /* Presently this is incompatible with 0-RTT. We will fix if - * it becomes more than an experiment. */ - if (ss->opt.enable0RttData) { - return 0; + rv = ssl_GetCertificateRequestCAs(ss, &calen, &name, &nnames); + if (rv != SECSuccess) { + return SECFailure; } - if (IS_DTLS(ss)) { - return 0; + if (!calen) { + return SECSuccess; } - /* Don't send this if TLS 1.3 isn't at least possible. */ - if (ss->vrange.max < SSL_LIBRARY_VERSION_TLS_1_3) { - /* This should only happen on the client. */ - PORT_Assert(!ss->sec.isServer); - return 0; + rv = sslBuffer_AppendNumber(buf, calen, 2); + if (rv != SECSuccess) { + return SECFailure; } - SSL_TRC(3, ("%d: TLS13[%d]: send short_header extension", - SSL_GETPID(), ss->fd)); - - if (maxBytes < extension_len) { - PORT_Assert(0); - return 0; + while (nnames) { + rv = sslBuffer_AppendVariable(buf, name->data, name->len, 2); + if (rv != SECSuccess) { + return SECFailure; + } + ++name; + --nnames; } - if (append) { - SECStatus rv; + *added = PR_TRUE; + return SECSuccess; +} - rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_tls13_short_header_xtn, 2); - if (rv != SECSuccess) - return -1; +SECStatus +tls13_ClientHandleCertAuthoritiesXtn(const sslSocket *ss, + TLSExtensionData *xtnData, + SECItem *data) +{ + SECStatus rv; + PLArenaPool *arena; - rv = ssl3_ExtAppendHandshakeNumber(ss, 0, 2); - if (rv != SECSuccess) - return -1; + if (!data->len) { + ssl3_ExtSendAlert(ss, alert_fatal, decode_error); + PORT_SetError(SSL_ERROR_RX_MALFORMED_CERT_REQUEST); + return SECFailure; + } + + arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); + if (!arena) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } - xtnData->advertised[xtnData->numAdvertised++] = - ssl_tls13_short_header_xtn; + xtnData->certReqAuthorities.arena = arena; + rv = ssl3_ParseCertificateRequestCAs((sslSocket *)ss, + &data->data, &data->len, + &xtnData->certReqAuthorities); + if (rv != SECSuccess) { + goto loser; } + if (data->len) { + ssl3_ExtSendAlert(ss, alert_fatal, decode_error); + PORT_SetError(SSL_ERROR_RX_MALFORMED_CERT_REQUEST); + goto loser; + } + return SECSuccess; - return extension_len; +loser: + PORT_FreeArena(arena, PR_FALSE); + xtnData->certReqAuthorities.arena = NULL; + return SECFailure; } SECStatus -tls13_HandleShortHeaderXtn( - const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, - SECItem *data) +tls13_ServerSendHrrKeyShareXtn(const sslSocket *ss, TLSExtensionData *xtnData, + sslBuffer *buf, PRBool *added) { - SSL_TRC(3, ("%d: TLS13[%d]: handle short_header extension", - SSL_GETPID(), ss->fd)); + SECStatus rv; - /* The client might have asked for this, but we didn't negotiate TLS 1.3. */ - if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) { - return SECSuccess; - } + PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_TLS_1_3); - /* Presently this is incompatible with 0-RTT. We will fix if - * it becomes more than an experiment. */ - if (ss->opt.enable0RttData) { + if (!xtnData->selectedGroup) { return SECSuccess; } - if (IS_DTLS(ss)) { - PORT_SetError(SSL_ERROR_EXTENSION_DISALLOWED_FOR_VERSION); - return SECFailure; - } - - if (data->len) { - PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE); + rv = sslBuffer_AppendNumber(buf, xtnData->selectedGroup->name, 2); + if (rv != SECSuccess) { return SECFailure; } - if (!ss->opt.enableShortHeaders) { - /* Ignore. */ - return SECSuccess; - } + *added = PR_TRUE; + return SECSuccess; +} - /* Keep track of negotiated extensions. */ - xtnData->negotiated[xtnData->numNegotiated++] = ex_type; +SECStatus +tls13_ServerSendHrrCookieXtn(const sslSocket *ss, TLSExtensionData *xtnData, + sslBuffer *buf, PRBool *added) +{ + SECStatus rv; - if (ss->sec.isServer) { - SECStatus rv; + PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_TLS_1_3); + PORT_Assert(xtnData->cookie.len > 0); - rv = ssl3_RegisterExtensionSender(ss, xtnData, - ssl_tls13_short_header_xtn, - tls13_SendShortHeaderXtn); - if (rv != SECSuccess) { - return SECFailure; - } + rv = sslBuffer_AppendVariable(buf, + xtnData->cookie.data, xtnData->cookie.len, 2); + if (rv != SECSuccess) { + return SECFailure; } + *added = PR_TRUE; return SECSuccess; } diff --git a/security/nss/lib/ssl/tls13exthandle.h b/security/nss/lib/ssl/tls13exthandle.h index b798c6b55..edce94d83 100644 --- a/security/nss/lib/ssl/tls13exthandle.h +++ b/security/nss/lib/ssl/tls13exthandle.h @@ -9,66 +9,80 @@ #ifndef __tls13exthandle_h_ #define __tls13exthandle_h_ -PRInt32 tls13_ServerSendStatusRequestXtn(const sslSocket *ss, TLSExtensionData *xtnData, - PRBool append, PRUint32 maxBytes); -PRInt32 tls13_ClientSendKeyShareXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, - PRUint32 maxBytes); -SECStatus tls13_ClientHandleKeyShareXtn(const sslSocket *ss, TLSExtensionData *xtnData, - PRUint16 ex_type, +SECStatus tls13_ServerSendStatusRequestXtn(const sslSocket *ss, + TLSExtensionData *xtnData, + sslBuffer *buf, PRBool *append); +SECStatus tls13_ClientSendKeyShareXtn(const sslSocket *ss, + TLSExtensionData *xtnData, + sslBuffer *buf, PRBool *append); +SECStatus tls13_ClientHandleKeyShareXtn(const sslSocket *ss, + TLSExtensionData *xtnData, SECItem *data); -SECStatus tls13_ClientHandleKeyShareXtnHrr(const sslSocket *ss, TLSExtensionData *xtnData, - PRUint16 ex_type, +SECStatus tls13_ClientHandleKeyShareXtnHrr(const sslSocket *ss, + TLSExtensionData *xtnData, SECItem *data); -SECStatus tls13_ServerHandleKeyShareXtn(const sslSocket *ss, TLSExtensionData *xtnData, - PRUint16 ex_type, +SECStatus tls13_ServerHandleKeyShareXtn(const sslSocket *ss, + TLSExtensionData *xtnData, SECItem *data); -PRInt32 tls13_ServerSendKeyShareXtn(const sslSocket *ss, - TLSExtensionData *xtnData, - PRBool append, - PRUint32 maxBytes); -PRInt32 tls13_ClientSendPreSharedKeyXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, - PRUint32 maxBytes); -SECStatus tls13_ServerHandlePreSharedKeyXtn(const sslSocket *ss, TLSExtensionData *xtnData, - PRUint16 ex_type, +SECStatus tls13_ServerSendKeyShareXtn(const sslSocket *ss, + TLSExtensionData *xtnData, + sslBuffer *buf, PRBool *append); +SECStatus tls13_ClientSendPreSharedKeyXtn(const sslSocket *ss, + TLSExtensionData *xtnData, + sslBuffer *buf, PRBool *append); +SECStatus tls13_ServerHandlePreSharedKeyXtn(const sslSocket *ss, + TLSExtensionData *xtnData, SECItem *data); -SECStatus tls13_ClientHandlePreSharedKeyXtn(const sslSocket *ss, TLSExtensionData *xtnData, - PRUint16 ex_type, +SECStatus tls13_ClientHandlePreSharedKeyXtn(const sslSocket *ss, + TLSExtensionData *xtnData, SECItem *data); -PRInt32 tls13_ServerSendPreSharedKeyXtn(const sslSocket *ss, TLSExtensionData *xtnData, - PRBool append, - PRUint32 maxBytes); -PRInt32 tls13_ClientSendEarlyDataXtn(const sslSocket *ss, TLSExtensionData *xtnData, - PRBool append, - PRUint32 maxBytes); -SECStatus tls13_ServerHandleEarlyDataXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, +SECStatus tls13_ServerSendPreSharedKeyXtn(const sslSocket *ss, + TLSExtensionData *xtnData, + sslBuffer *buf, PRBool *append); +SECStatus tls13_ClientSendEarlyDataXtn(const sslSocket *ss, + TLSExtensionData *xtnData, + sslBuffer *buf, PRBool *append); +SECStatus tls13_ServerHandleEarlyDataXtn(const sslSocket *ss, + TLSExtensionData *xtnData, SECItem *data); -SECStatus tls13_ClientHandleEarlyDataXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, +SECStatus tls13_ClientHandleEarlyDataXtn(const sslSocket *ss, + TLSExtensionData *xtnData, SECItem *data); -PRInt32 tls13_ServerSendEarlyDataXtn(const sslSocket *ss, TLSExtensionData *xtnData, - PRBool append, - PRUint32 maxBytes); -SECStatus tls13_ClientHandleTicketEarlyDataInfoXtn( - const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, - SECItem *data); -PRInt32 tls13_ClientSendSupportedVersionsXtn(const sslSocket *ss, TLSExtensionData *xtnData, - PRBool append, - PRUint32 maxBytes); -SECStatus tls13_ClientHandleHrrCookie(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, +SECStatus tls13_ClientHandleTicketEarlyDataXtn(const sslSocket *ss, + TLSExtensionData *xtnData, + SECItem *data); +SECStatus tls13_ClientSendSupportedVersionsXtn(const sslSocket *ss, + TLSExtensionData *xtnData, + sslBuffer *buf, PRBool *append); +SECStatus tls13_ServerSendSupportedVersionsXtn(const sslSocket *ss, + TLSExtensionData *xtnData, + sslBuffer *buf, PRBool *added); +SECStatus tls13_ClientHandleHrrCookie(const sslSocket *ss, + TLSExtensionData *xtnData, SECItem *data); -PRInt32 tls13_ClientSendHrrCookieXtn(const sslSocket *ss, TLSExtensionData *xtnData, - PRBool append, - PRUint32 maxBytes); -PRInt32 tls13_ClientSendPskKeyExchangeModesXtn(const sslSocket *ss, +SECStatus tls13_ClientSendHrrCookieXtn(const sslSocket *ss, + TLSExtensionData *xtnData, + sslBuffer *buf, PRBool *append); +SECStatus tls13_ClientSendPskModesXtn(const sslSocket *ss, + TLSExtensionData *xtnData, + sslBuffer *buf, PRBool *append); +SECStatus tls13_ServerHandlePskModesXtn(const sslSocket *ss, + TLSExtensionData *xtnData, + SECItem *data); +SECStatus tls13_SendCertAuthoritiesXtn(const sslSocket *ss, + TLSExtensionData *xtnData, + sslBuffer *buf, PRBool *append); +SECStatus tls13_ClientHandleCertAuthoritiesXtn(const sslSocket *ss, TLSExtensionData *xtnData, - PRBool append, PRUint32 maxBytes); -SECStatus tls13_ServerHandlePskKeyExchangeModesXtn(const sslSocket *ss, - TLSExtensionData *xtnData, - PRUint16 ex_type, SECItem *data); -PRInt32 tls13_SendShortHeaderXtn(const sslSocket *ss, - TLSExtensionData *xtnData, - PRBool append, PRUint32 maxBytes); -SECStatus tls13_HandleShortHeaderXtn( - const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, - SECItem *data); + SECItem *data); +SECStatus tls13_ServerHandleCookieXtn(const sslSocket *ss, + TLSExtensionData *xtnData, + SECItem *data); +SECStatus tls13_ServerSendHrrKeyShareXtn(const sslSocket *ss, + TLSExtensionData *xtnData, + sslBuffer *buf, PRBool *added); +SECStatus tls13_ServerSendHrrCookieXtn(const sslSocket *ss, + TLSExtensionData *xtnData, + sslBuffer *buf, PRBool *added); #endif diff --git a/security/nss/lib/ssl/tls13hashstate.c b/security/nss/lib/ssl/tls13hashstate.c new file mode 100644 index 000000000..cc0ed286b --- /dev/null +++ b/security/nss/lib/ssl/tls13hashstate.c @@ -0,0 +1,185 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is PRIVATE to SSL. + * + * 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 "pk11func.h" +#include "ssl.h" +#include "sslt.h" +#include "sslimpl.h" +#include "selfencrypt.h" +#include "tls13con.h" +#include "tls13err.h" +#include "tls13hashstate.h" + +/* + * The cookie is structured as a self-encrypted structure with the + * inner value being. + * + * struct { + * uint8 indicator = 0xff; // To disambiguate from tickets. + * uint16 cipherSuite; // Selected cipher suite. + * uint16 keyShare; // Requested key share group (0=none) + * opaque applicationToken<0..65535>; // Application token + * opaque ch_hash[rest_of_buffer]; // H(ClientHello) + * } CookieInner; + */ +SECStatus +tls13_MakeHrrCookie(sslSocket *ss, const sslNamedGroupDef *selectedGroup, + const PRUint8 *appToken, unsigned int appTokenLen, + PRUint8 *buf, unsigned int *len, unsigned int maxlen) +{ + SECStatus rv; + SSL3Hashes hashes; + PRUint8 cookie[1024]; + sslBuffer cookieBuf = SSL_BUFFER(cookie); + static const PRUint8 indicator = 0xff; + + /* Encode header. */ + rv = sslBuffer_Append(&cookieBuf, &indicator, 1); + if (rv != SECSuccess) { + return SECFailure; + } + rv = sslBuffer_AppendNumber(&cookieBuf, ss->ssl3.hs.cipher_suite, 2); + if (rv != SECSuccess) { + return SECFailure; + } + rv = sslBuffer_AppendNumber(&cookieBuf, + selectedGroup ? selectedGroup->name : 0, 2); + if (rv != SECSuccess) { + return SECFailure; + } + + /* Application token. */ + rv = sslBuffer_AppendVariable(&cookieBuf, appToken, appTokenLen, 2); + if (rv != SECSuccess) { + return SECFailure; + } + + /* Compute and encode hashes. */ + rv = tls13_ComputeHandshakeHashes(ss, &hashes); + if (rv != SECSuccess) { + return SECFailure; + } + rv = sslBuffer_Append(&cookieBuf, hashes.u.raw, hashes.len); + if (rv != SECSuccess) { + return SECFailure; + } + + /* Encrypt right into the buffer. */ + rv = ssl_SelfEncryptProtect(ss, cookieBuf.buf, cookieBuf.len, + buf, len, maxlen); + if (rv != SECSuccess) { + return SECFailure; + } + + return SECSuccess; +} + +/* Recover the hash state from the cookie. */ +SECStatus +tls13_RecoverHashState(sslSocket *ss, + unsigned char *cookie, unsigned int cookieLen, + ssl3CipherSuite *previousCipherSuite, + const sslNamedGroupDef **previousGroup) +{ + SECStatus rv; + unsigned char plaintext[1024]; + unsigned int plaintextLen = 0; + sslBuffer messageBuf = SSL_BUFFER_EMPTY; + PRUint64 sentinel; + PRUint64 cipherSuite; + PRUint64 group; + const sslNamedGroupDef *selectedGroup; + PRUint64 appTokenLen; + + rv = ssl_SelfEncryptUnprotect(ss, cookie, cookieLen, + plaintext, &plaintextLen, sizeof(plaintext)); + if (rv != SECSuccess) { + return SECFailure; + } + + sslReader reader = SSL_READER(plaintext, plaintextLen); + + /* Should start with 0xff. */ + rv = sslRead_ReadNumber(&reader, 1, &sentinel); + if ((rv != SECSuccess) || (sentinel != 0xff)) { + FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, illegal_parameter); + return SECFailure; + } + /* The cipher suite should be the same or there are some shenanigans. */ + rv = sslRead_ReadNumber(&reader, 2, &cipherSuite); + if (rv != SECSuccess) { + FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, illegal_parameter); + return SECFailure; + } + + /* The named group, if any. */ + rv = sslRead_ReadNumber(&reader, 2, &group); + if (rv != SECSuccess) { + FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, illegal_parameter); + return SECFailure; + } + selectedGroup = ssl_LookupNamedGroup(group); + + /* Application token. */ + PORT_Assert(ss->xtnData.applicationToken.len == 0); + rv = sslRead_ReadNumber(&reader, 2, &appTokenLen); + if (rv != SECSuccess) { + FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, illegal_parameter); + return SECFailure; + } + if (SECITEM_AllocItem(NULL, &ss->xtnData.applicationToken, + appTokenLen) == NULL) { + FATAL_ERROR(ss, PORT_GetError(), internal_error); + return SECFailure; + } + ss->xtnData.applicationToken.len = appTokenLen; + sslReadBuffer appTokenReader = { 0 }; + rv = sslRead_Read(&reader, appTokenLen, &appTokenReader); + if (rv != SECSuccess) { + FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, illegal_parameter); + return SECFailure; + } + PORT_Assert(appTokenReader.len == appTokenLen); + PORT_Memcpy(ss->xtnData.applicationToken.data, appTokenReader.buf, appTokenLen); + + /* The remainder is the hash. */ + unsigned int hashLen = SSL_READER_REMAINING(&reader); + if (hashLen != tls13_GetHashSize(ss)) { + FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, illegal_parameter); + return SECFailure; + } + + /* Now reinject the message. */ + SSL_ASSERT_HASHES_EMPTY(ss); + rv = ssl_HashHandshakeMessageInt(ss, ssl_hs_message_hash, 0, + SSL_READER_CURRENT(&reader), hashLen); + if (rv != SECSuccess) { + return SECFailure; + } + + /* And finally reinject the HRR. */ + rv = tls13_ConstructHelloRetryRequest(ss, cipherSuite, + selectedGroup, + cookie, cookieLen, + &messageBuf); + if (rv != SECSuccess) { + return SECFailure; + } + + rv = ssl_HashHandshakeMessageInt(ss, ssl_hs_server_hello, 0, + SSL_BUFFER_BASE(&messageBuf), + SSL_BUFFER_LEN(&messageBuf)); + sslBuffer_Clear(&messageBuf); + if (rv != SECSuccess) { + return SECFailure; + } + + *previousCipherSuite = cipherSuite; + *previousGroup = selectedGroup; + return SECSuccess; +} diff --git a/security/nss/lib/ssl/tls13hashstate.h b/security/nss/lib/ssl/tls13hashstate.h new file mode 100644 index 000000000..e9a4aa84f --- /dev/null +++ b/security/nss/lib/ssl/tls13hashstate.h @@ -0,0 +1,25 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is PRIVATE to SSL. + * + * 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 __tls13hashstate_h_ +#define __tls13hashstate_h_ + +#include "ssl.h" +#include "sslt.h" +#include "sslimpl.h" + +SECStatus tls13_MakeHrrCookie(sslSocket *ss, const sslNamedGroupDef *selectedGroup, + const PRUint8 *appToken, unsigned int appTokenLen, + PRUint8 *buf, unsigned int *len, unsigned int maxlen); +SECStatus tls13_GetHrrCookieLength(sslSocket *ss, unsigned int *length); +SECStatus tls13_RecoverHashState(sslSocket *ss, + unsigned char *cookie, + unsigned int cookieLen, + ssl3CipherSuite *previousCipherSuite, + const sslNamedGroupDef **previousGroup); +#endif diff --git a/security/nss/lib/ssl/tls13hkdf.c b/security/nss/lib/ssl/tls13hkdf.c index 7e69bb882..8fa3375c6 100644 --- a/security/nss/lib/ssl/tls13hkdf.c +++ b/security/nss/lib/ssl/tls13hkdf.c @@ -134,10 +134,10 @@ tls13_HkdfExpandLabel(PK11SymKey *prk, SSLHashType baseHash, * Label, plus HandshakeHash. If it's ever to small, the code will abort. */ PRUint8 info[256]; - PRUint8 *ptr = info; - unsigned int infoLen; + sslBuffer infoBuf = SSL_BUFFER(info); PK11SymKey *derived; - const char *kLabelPrefix = "TLS 1.3, "; + SECStatus rv; + const char *kLabelPrefix = "tls13 "; const unsigned int kLabelPrefixLen = strlen(kLabelPrefix); if (handshakeHash) { @@ -170,29 +170,31 @@ tls13_HkdfExpandLabel(PK11SymKey *prk, SSLHashType baseHash, * - HkdfLabel.label is "TLS 1.3, " + Label * */ - infoLen = 2 + 1 + kLabelPrefixLen + labelLen + 1 + handshakeHashLen; - if (infoLen > sizeof(info)) { - PORT_Assert(0); - goto abort; + rv = sslBuffer_AppendNumber(&infoBuf, keySize, 2); + if (rv != SECSuccess) { + return SECFailure; } - - ptr = ssl_EncodeUintX(keySize, 2, ptr); - ptr = ssl_EncodeUintX(labelLen + kLabelPrefixLen, 1, ptr); - PORT_Memcpy(ptr, kLabelPrefix, kLabelPrefixLen); - ptr += kLabelPrefixLen; - PORT_Memcpy(ptr, label, labelLen); - ptr += labelLen; - ptr = ssl_EncodeUintX(handshakeHashLen, 1, ptr); - if (handshakeHash) { - PORT_Memcpy(ptr, handshakeHash, handshakeHashLen); - ptr += handshakeHashLen; + rv = sslBuffer_AppendNumber(&infoBuf, labelLen + kLabelPrefixLen, 1); + if (rv != SECSuccess) { + return SECFailure; + } + rv = sslBuffer_Append(&infoBuf, kLabelPrefix, kLabelPrefixLen); + if (rv != SECSuccess) { + return SECFailure; + } + rv = sslBuffer_Append(&infoBuf, label, labelLen); + if (rv != SECSuccess) { + return SECFailure; + } + rv = sslBuffer_AppendVariable(&infoBuf, handshakeHash, handshakeHashLen, 1); + if (rv != SECSuccess) { + return SECFailure; } - PORT_Assert((ptr - info) == infoLen); params.bExtract = CK_FALSE; params.bExpand = CK_TRUE; - params.pInfo = info; - params.ulInfoLen = infoLen; + params.pInfo = SSL_BUFFER_BASE(&infoBuf); + params.ulInfoLen = SSL_BUFFER_LEN(&infoBuf); paramsi.data = (unsigned char *)¶ms; paramsi.len = sizeof(params); @@ -211,20 +213,17 @@ tls13_HkdfExpandLabel(PK11SymKey *prk, SSLHashType baseHash, char labelStr[100]; PORT_Memcpy(labelStr, label, labelLen); labelStr[labelLen] = 0; - SSL_TRC(50, ("HKDF Expand: label=[TLS 1.3, ] + '%s',requested length=%d", + SSL_TRC(50, ("HKDF Expand: label='tls13 %s',requested length=%d", labelStr, keySize)); } PRINT_KEY(50, (NULL, "PRK", prk)); PRINT_BUF(50, (NULL, "Hash", handshakeHash, handshakeHashLen)); - PRINT_BUF(50, (NULL, "Info", info, infoLen)); + PRINT_BUF(50, (NULL, "Info", SSL_BUFFER_BASE(&infoBuf), + SSL_BUFFER_LEN(&infoBuf))); PRINT_KEY(50, (NULL, "Derived key", derived)); #endif return SECSuccess; - -abort: - PORT_SetError(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE); - return SECFailure; } SECStatus diff --git a/security/nss/lib/ssl/tls13replay.c b/security/nss/lib/ssl/tls13replay.c new file mode 100644 index 000000000..b090f9bca --- /dev/null +++ b/security/nss/lib/ssl/tls13replay.c @@ -0,0 +1,276 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * Anti-replay measures for TLS 1.3. + * + * 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 "nss.h" /* for NSS_RegisterShutdown */ +#include "nssilock.h" /* for PZMonitor */ +#include "pk11pub.h" +#include "prinit.h" /* for PR_CallOnce */ +#include "prmon.h" +#include "prtime.h" +#include "secerr.h" +#include "ssl.h" +#include "sslbloom.h" +#include "sslimpl.h" +#include "tls13hkdf.h" + +static struct { + /* Used to ensure that we only initialize the cleanup function once. */ + PRCallOnceType init; + /* Used to serialize access to the filters. */ + PZMonitor *lock; + /* The filters, use of which alternates. */ + sslBloomFilter filters[2]; + /* Which of the two filters is active (0 or 1). */ + PRUint8 current; + /* The time that we will next update. */ + PRTime nextUpdate; + /* The width of the window; i.e., the period of updates. */ + PRTime window; + /* This key ensures that the bloom filter index is unpredictable. */ + PK11SymKey *key; +} ssl_anti_replay; + +/* Clear the current state and free any resources we allocated. The signature + * here is odd to allow this to be called during shutdown. */ +static SECStatus +tls13_AntiReplayReset(void *appData, void *nssData) +{ + if (ssl_anti_replay.key) { + PK11_FreeSymKey(ssl_anti_replay.key); + ssl_anti_replay.key = NULL; + } + if (ssl_anti_replay.lock) { + PZ_DestroyMonitor(ssl_anti_replay.lock); + ssl_anti_replay.lock = NULL; + } + sslBloom_Destroy(&ssl_anti_replay.filters[0]); + sslBloom_Destroy(&ssl_anti_replay.filters[1]); + return SECSuccess; +} + +static PRStatus +tls13_AntiReplayInit(void) +{ + SECStatus rv = NSS_RegisterShutdown(tls13_AntiReplayReset, NULL); + if (rv != SECSuccess) { + return PR_FAILURE; + } + return PR_SUCCESS; +} + +static SECStatus +tls13_AntiReplayKeyGen() +{ + PRUint8 buf[32]; + SECItem keyItem = { siBuffer, buf, sizeof(buf) }; + PK11SlotInfo *slot; + SECStatus rv; + + slot = PK11_GetInternalSlot(); + if (!slot) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + rv = PK11_GenerateRandomOnSlot(slot, buf, sizeof(buf)); + if (rv != SECSuccess) { + goto loser; + } + + ssl_anti_replay.key = PK11_ImportSymKey(slot, CKM_NSS_HKDF_SHA256, + PK11_OriginUnwrap, CKA_DERIVE, + &keyItem, NULL); + if (!ssl_anti_replay.key) { + goto loser; + } + + PK11_FreeSlot(slot); + return SECSuccess; + +loser: + PK11_FreeSlot(slot); + return SECFailure; +} + +/* Set a limit on the combination of number of hashes and bits in each hash. */ +#define SSL_MAX_BLOOM_FILTER_SIZE 64 + +/* + * The structures created by this function can be called concurrently on + * multiple threads if the server is multi-threaded. A monitor is used to + * ensure that only one thread can access the structures that change over time, + * but no such guarantee is provided for configuration data. + * + * Functions that read from static configuration data depend on there being a + * memory barrier between the setup and use of this function. + */ +SECStatus +SSLExp_SetupAntiReplay(PRTime window, unsigned int k, unsigned int bits) +{ + SECStatus rv; + + if (k == 0 || bits == 0) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + if ((k * (bits + 7) / 8) > SSL_MAX_BLOOM_FILTER_SIZE) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + + if (PR_SUCCESS != PR_CallOnce(&ssl_anti_replay.init, + tls13_AntiReplayInit)) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + + (void)tls13_AntiReplayReset(NULL, NULL); + + ssl_anti_replay.lock = PZ_NewMonitor(nssILockSSL); + if (!ssl_anti_replay.lock) { + goto loser; /* Code already set. */ + } + + rv = tls13_AntiReplayKeyGen(); + if (rv != SECSuccess) { + goto loser; /* Code already set. */ + } + + rv = sslBloom_Init(&ssl_anti_replay.filters[0], k, bits); + if (rv != SECSuccess) { + goto loser; /* Code already set. */ + } + rv = sslBloom_Init(&ssl_anti_replay.filters[1], k, bits); + if (rv != SECSuccess) { + goto loser; /* Code already set. */ + } + /* When starting out, ensure that 0-RTT is not accepted until the window is + * updated. A ClientHello might have been accepted prior to a restart. */ + sslBloom_Fill(&ssl_anti_replay.filters[1]); + + ssl_anti_replay.current = 0; + ssl_anti_replay.nextUpdate = ssl_TimeUsec() + window; + ssl_anti_replay.window = window; + return SECSuccess; + +loser: + (void)tls13_AntiReplayReset(NULL, NULL); + return SECFailure; +} + +/* This is exposed to tests. Though it could, this doesn't take the lock on the + * basis that those tests use thread confinement. */ +void +tls13_AntiReplayRollover(PRTime now) +{ + ssl_anti_replay.current ^= 1; + ssl_anti_replay.nextUpdate = now + ssl_anti_replay.window; + sslBloom_Zero(ssl_anti_replay.filters + ssl_anti_replay.current); +} + +static void +tls13_AntiReplayUpdate() +{ + PRTime now; + + PR_ASSERT_CURRENT_THREAD_IN_MONITOR(ssl_anti_replay.lock); + + now = ssl_TimeUsec(); + if (now < ssl_anti_replay.nextUpdate) { + return; + } + + tls13_AntiReplayRollover(now); +} + +PRBool +tls13_InWindow(const sslSocket *ss, const sslSessionID *sid) +{ + PRInt32 timeDelta; + + /* Calculate the difference between the client's view of the age of the + * ticket (in |ss->xtnData.ticketAge|) and the server's view, which we now + * calculate. The result should be close to zero. timeDelta is signed to + * make the comparisons below easier. */ + timeDelta = ss->xtnData.ticketAge - + ((ssl_TimeUsec() - sid->creationTime) / PR_USEC_PER_MSEC); + + /* Only allow the time delta to be at most half of our window. This is + * symmetrical, though it doesn't need to be; this assumes that clock errors + * on server and client will tend to cancel each other out. + * + * There are two anti-replay filters that roll over each window. In the + * worst case, immediately after a rollover of the filters, we only have a + * single window worth of recorded 0-RTT attempts. Thus, the period in + * which we can accept 0-RTT is at most one window wide. This uses PR_ABS() + * and half the window so that the first attempt can be up to half a window + * early and then replays will be caught until the attempts are half a + * window late. + * + * For example, a 0-RTT attempt arrives early, but near the end of window 1. + * The attempt is then recorded in window 1. Rollover to window 2 could + * occur immediately afterwards. Window 1 is still checked for new 0-RTT + * attempts for the remainder of window 2. Therefore, attempts to replay + * are detected because the value is recorded in window 1. When rollover + * occurs again, window 1 is erased and window 3 instated. If we allowed an + * attempt to be late by more than half a window, then this check would not + * prevent the same 0-RTT attempt from being accepted during window 1 and + * later window 3. + */ + return PR_ABS(timeDelta) < (ssl_anti_replay.window / 2); +} + +/* Checks for a duplicate in the two filters we have. Performs maintenance on + * the filters as a side-effect. This only detects a probable replay, it's + * possible that this will return true when the 0-RTT attempt is not genuinely a + * replay. In that case, we reject 0-RTT unnecessarily, but that's OK because + * no client expects 0-RTT to work every time. */ +PRBool +tls13_IsReplay(const sslSocket *ss, const sslSessionID *sid) +{ + PRBool replay; + unsigned int size; + PRUint8 index; + SECStatus rv; + static const char *label = "tls13 anti-replay"; + PRUint8 buf[SSL_MAX_BLOOM_FILTER_SIZE]; + + /* If SSL_SetupAntiReplay hasn't been called, then treat all attempts at + * 0-RTT as a replay. */ + if (!ssl_anti_replay.init.initialized) { + return PR_TRUE; + } + + if (!tls13_InWindow(ss, sid)) { + return PR_TRUE; + } + + size = ssl_anti_replay.filters[0].k * + (ssl_anti_replay.filters[0].bits + 7) / 8; + PORT_Assert(size <= SSL_MAX_BLOOM_FILTER_SIZE); + rv = tls13_HkdfExpandLabelRaw(ssl_anti_replay.key, ssl_hash_sha256, + ss->xtnData.pskBinder.data, + ss->xtnData.pskBinder.len, + label, strlen(label), + buf, size); + if (rv != SECSuccess) { + return PR_TRUE; + } + + PZ_EnterMonitor(ssl_anti_replay.lock); + tls13_AntiReplayUpdate(); + + index = ssl_anti_replay.current; + replay = sslBloom_Add(&ssl_anti_replay.filters[index], buf); + if (!replay) { + replay = sslBloom_Check(&ssl_anti_replay.filters[index ^ 1], + buf); + } + + PZ_ExitMonitor(ssl_anti_replay.lock); + return replay; +} diff --git a/security/nss/lib/util/nssb64d.c b/security/nss/lib/util/nssb64d.c index 886ce21c0..e4bb20a3e 100644 --- a/security/nss/lib/util/nssb64d.c +++ b/security/nss/lib/util/nssb64d.c @@ -249,7 +249,7 @@ pl_base64_decode_buffer(PLBase64Decoder *data, const unsigned char *in, } i = 0; - PR_ASSERT((out - data->output_buffer + 3) <= data->output_buflen); + PR_ASSERT((PRUint32)(out - data->output_buffer + 3) <= data->output_buflen); /* * Assume we are not at the end; the following function only works diff --git a/security/nss/lib/util/nssrwlk.c b/security/nss/lib/util/nssrwlk.c index dbaeca24b..5af021762 100644 --- a/security/nss/lib/util/nssrwlk.c +++ b/security/nss/lib/util/nssrwlk.c @@ -120,6 +120,8 @@ NSSRWLock_Destroy(NSSRWLock *rwlock) { PR_ASSERT(rwlock != NULL); PR_ASSERT(rwlock->rw_waiting_readers == 0); + PR_ASSERT(rwlock->rw_writer_locks == 0); + PR_ASSERT(rwlock->rw_reader_locks == 0); /* XXX Shouldn't we lock the PZLock before destroying this?? */ diff --git a/security/nss/lib/util/nssutil.def b/security/nss/lib/util/nssutil.def index f4b9ef7ba..936455f6e 100644 --- a/security/nss/lib/util/nssutil.def +++ b/security/nss/lib/util/nssutil.def @@ -307,3 +307,19 @@ PK11URI_GetQueryAttribute; ;+ local: ;+ *; ;+}; +;+NSSUTIL_3.33 { # NSS Utilities 3.33 release +;+ global: +PORT_ZAllocAligned_Util; +PORT_ZAllocAlignedOffset_Util; +NSS_SecureMemcmpZero; +;+ local: +;+ *; +;+}; +;-NSSUTIL_3.35 { # NSS Utilities 3.35 release +;- global: +;-# private exports for softoken +_NSSUTIL_UTF8ToWide;- +_NSSUTIL_Access;- +;- local: +;- *; +;-}; diff --git a/security/nss/lib/util/nssutil.h b/security/nss/lib/util/nssutil.h index e8cb52aed..b65d4a0c9 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.32.1" +#define NSSUTIL_VERSION "3.36.4" #define NSSUTIL_VMAJOR 3 -#define NSSUTIL_VMINOR 32 -#define NSSUTIL_VPATCH 1 +#define NSSUTIL_VMINOR 36 +#define NSSUTIL_VPATCH 4 #define NSSUTIL_VBUILD 0 #define NSSUTIL_BETA PR_FALSE diff --git a/security/nss/lib/util/pkcs11uri.c b/security/nss/lib/util/pkcs11uri.c index 453440293..94b00171e 100644 --- a/security/nss/lib/util/pkcs11uri.c +++ b/security/nss/lib/util/pkcs11uri.c @@ -242,7 +242,7 @@ static int pk11uri_CompareByPosition(const char *a, const char *b, const char **attr_names, size_t num_attr_names) { - int i, j; + size_t i, j; for (i = 0; i < num_attr_names; i++) { if (strcmp(a, attr_names[i]) == 0) { diff --git a/security/nss/lib/util/quickder.c b/security/nss/lib/util/quickder.c index 1b474822e..7a6ac1c53 100644 --- a/security/nss/lib/util/quickder.c +++ b/security/nss/lib/util/quickder.c @@ -520,8 +520,7 @@ DecodeGroup(void* dest, if (SECSuccess == rv) { /* allocate room for pointer array and entries */ /* we want to allocate the array even if there is 0 entry */ - entries = (void**)PORT_ArenaZAlloc(arena, sizeof(void*) * - (totalEntries + 1) + /* the extra one is for NULL termination */ + entries = (void**)PORT_ArenaZAlloc(arena, sizeof(void*) * (totalEntries + 1) + /* the extra one is for NULL termination */ subTemplate->size * totalEntries); if (entries) { diff --git a/security/nss/lib/util/secasn1d.c b/security/nss/lib/util/secasn1d.c index e6abb5fd5..ccd97481d 100644 --- a/security/nss/lib/util/secasn1d.c +++ b/security/nss/lib/util/secasn1d.c @@ -175,7 +175,7 @@ static int /* bool */ } } } else { - sprintf(buf, " [%d]", k); + sprintf(buf, " [%lu]", k); } buf += strlen(buf); @@ -982,7 +982,7 @@ sec_asn1d_prepare_for_contents(sec_asn1d_state *state) #ifdef DEBUG_ASN1D_STATES { - printf("Found Length %d %s\n", state->contents_length, + printf("Found Length %lu %s\n", state->contents_length, state->indefinite ? "indefinite" : ""); } #endif @@ -2717,18 +2717,15 @@ dump_states(SEC_ASN1DecoderContext *cx) } i = formatKind(state->theTemplate->kind, kindBuf); - printf("%s: tmpl %08x, kind%s", + printf("%s: tmpl kind %s", (state == cx->current) ? "STATE" : "State", - state->theTemplate, kindBuf); - printf(" %s", (state->place >= 0 && state->place <= notInUse) - ? place_names[state->place] - : "(undefined)"); + printf(" %s", (state->place >= 0 && state->place <= notInUse) ? place_names[state->place] : "(undefined)"); if (!i) - printf(", expect 0x%02x", + printf(", expect 0x%02lx", state->expect_tag_number | state->expect_tag_modifiers); - printf("%s%s%s %d\n", + printf("%s%s%s %lu\n", state->indefinite ? ", indef" : "", state->missing ? ", miss" : "", state->endofcontents ? ", EOC" : "", @@ -2756,7 +2753,7 @@ SEC_ASN1DecoderUpdate(SEC_ASN1DecoderContext *cx, what = SEC_ASN1_Contents; consumed = 0; #ifdef DEBUG_ASN1D_STATES - printf("\nPLACE = %s, next byte = 0x%02x, %08x[%d]\n", + printf("\nPLACE = %s, next byte = 0x%02x, %p[%lu]\n", (state->place >= 0 && state->place <= notInUse) ? place_names[state->place] : "(undefined)", len ? (unsigned int)((unsigned char *)buf)[consumed] : 0, buf, consumed); @@ -2979,7 +2976,7 @@ SEC_ASN1DecoderFinish(SEC_ASN1DecoderContext *cx) { SECStatus rv; - if (cx->status == needBytes) { + if (!cx || cx->status == needBytes) { PORT_SetError(SEC_ERROR_BAD_DER); rv = SECFailure; } else { diff --git a/security/nss/lib/util/secoid.c b/security/nss/lib/util/secoid.c index da03b7c06..a05621c59 100644 --- a/security/nss/lib/util/secoid.c +++ b/security/nss/lib/util/secoid.c @@ -1841,13 +1841,11 @@ secoid_FindDynamic(const SECItem *key) { SECOidData *ret = NULL; + NSSRWLock_LockRead(dynOidLock); if (dynOidHash) { - NSSRWLock_LockRead(dynOidLock); - if (dynOidHash) { /* must check it again with lock held. */ - ret = (SECOidData *)PL_HashTableLookup(dynOidHash, key); - } - NSSRWLock_UnlockRead(dynOidLock); + ret = (SECOidData *)PL_HashTableLookup(dynOidHash, key); } + NSSRWLock_UnlockRead(dynOidLock); if (ret == NULL) { PORT_SetError(SEC_ERROR_UNRECOGNIZED_OID); } @@ -1866,14 +1864,12 @@ secoid_FindDynamicByTag(SECOidTag tagnum) } tagNumDiff = tagnum - SEC_OID_TOTAL; - if (dynOidTable) { - NSSRWLock_LockRead(dynOidLock); - if (dynOidTable != NULL && /* must check it again with lock held. */ - tagNumDiff < dynOidEntriesUsed) { - dxo = dynOidTable[tagNumDiff]; - } - NSSRWLock_UnlockRead(dynOidLock); + NSSRWLock_LockRead(dynOidLock); + if (dynOidTable != NULL && + tagNumDiff < dynOidEntriesUsed) { + dxo = dynOidTable[tagNumDiff]; } + NSSRWLock_UnlockRead(dynOidLock); if (dxo == NULL) { PORT_SetError(SEC_ERROR_UNRECOGNIZED_OID); } diff --git a/security/nss/lib/util/secport.c b/security/nss/lib/util/secport.c index 01a7d0834..e5bd4c1bb 100644 --- a/security/nss/lib/util/secport.c +++ b/security/nss/lib/util/secport.c @@ -21,6 +21,8 @@ #include "prenv.h" #include "prinit.h" +#include <stdint.h> + #ifdef DEBUG #define THREADMARK #endif /* DEBUG */ @@ -119,6 +121,51 @@ PORT_ZAlloc(size_t bytes) return rv; } +/* aligned_alloc is C11. This is an alternative to get aligned memory. */ +void * +PORT_ZAllocAligned(size_t bytes, size_t alignment, void **mem) +{ + size_t x = alignment - 1; + + /* This only works if alignment is a power of 2. */ + if ((alignment == 0) || (alignment & (alignment - 1))) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return NULL; + } + + if (!mem) { + return NULL; + } + + /* Always allocate a non-zero amount of bytes */ + *mem = PORT_ZAlloc((bytes ? bytes : 1) + x); + if (!*mem) { + PORT_SetError(SEC_ERROR_NO_MEMORY); + return NULL; + } + + return (void *)(((uintptr_t)*mem + x) & ~(uintptr_t)x); +} + +void * +PORT_ZAllocAlignedOffset(size_t size, size_t alignment, size_t offset) +{ + PORT_Assert(offset < size); + if (offset > size) { + return NULL; + } + + void *mem = NULL; + void *v = PORT_ZAllocAligned(size, alignment, &mem); + if (!v) { + return NULL; + } + + PORT_Assert(mem); + *((void **)((uintptr_t)v + offset)) = mem; + return v; +} + void PORT_Free(void *ptr) { @@ -733,3 +780,18 @@ NSS_SecureMemcmp(const void *ia, const void *ib, size_t n) return r; } + +/* + * Perform a constant-time check if a memory region is all 0. The return value + * is 0 if the memory region is all zero. + */ +unsigned int +NSS_SecureMemcmpZero(const void *mem, size_t n) +{ + PRUint8 zero = 0; + size_t i; + for (i = 0; i < n; ++i) { + zero |= *(PRUint8 *)((uintptr_t)mem + i); + } + return zero; +} diff --git a/security/nss/lib/util/secport.h b/security/nss/lib/util/secport.h index fb9ff4ebb..f1665a2f5 100644 --- a/security/nss/lib/util/secport.h +++ b/security/nss/lib/util/secport.h @@ -45,6 +45,7 @@ #include <string.h> #include <stddef.h> #include <stdlib.h> +#include <stdint.h> #include "prtypes.h" #include "prlog.h" /* for PR_ASSERT */ #include "plarena.h" @@ -88,6 +89,9 @@ SEC_BEGIN_PROTOS extern void *PORT_Alloc(size_t len); extern void *PORT_Realloc(void *old, size_t len); extern void *PORT_ZAlloc(size_t len); +extern void *PORT_ZAllocAligned(size_t bytes, size_t alignment, void **mem); +extern void *PORT_ZAllocAlignedOffset(size_t bytes, size_t alignment, + size_t offset); extern void PORT_Free(void *ptr); extern void PORT_ZFree(void *ptr, size_t len); extern char *PORT_Strdup(const char *s); @@ -131,6 +135,8 @@ SEC_END_PROTOS #define PORT_CheckSuccess(f) (f) #endif #define PORT_ZNew(type) (type *)PORT_ZAlloc(sizeof(type)) +#define PORT_ZNewAligned(type, alignment, mem) \ + (type *)PORT_ZAllocAlignedOffset(sizeof(type), alignment, offsetof(type, mem)) #define PORT_New(type) (type *)PORT_Alloc(sizeof(type)) #define PORT_ArenaNew(poolp, type) \ (type *)PORT_ArenaAlloc(poolp, sizeof(type)) @@ -246,6 +252,7 @@ sec_port_iso88591_utf8_conversion_function( extern int NSS_PutEnv(const char *envVarName, const char *envValue); extern int NSS_SecureMemcmp(const void *a, const void *b, size_t n); +extern unsigned int NSS_SecureMemcmpZero(const void *mem, size_t n); /* * Load a shared library called "newShLibName" in the same directory as diff --git a/security/nss/lib/util/utilmod.c b/security/nss/lib/util/utilmod.c index 971b6c1dc..7d3fcda81 100644 --- a/security/nss/lib/util/utilmod.c +++ b/security/nss/lib/util/utilmod.c @@ -24,6 +24,7 @@ #if defined(_WIN32) #include <io.h> +#include <windows.h> #endif #ifdef XP_UNIX #include <unistd.h> @@ -34,15 +35,184 @@ #include <fcntl.h> #if defined(_WIN32) -#define os_open _open #define os_fdopen _fdopen -#define os_stat _stat #define os_truncate_open_flags _O_CREAT | _O_RDWR | _O_TRUNC #define os_append_open_flags _O_CREAT | _O_RDWR | _O_APPEND #define os_open_permissions_type int #define os_open_permissions_default _S_IREAD | _S_IWRITE #define os_stat_type struct _stat + +/* + * Convert a UTF8 string to Unicode wide character + */ +LPWSTR +_NSSUTIL_UTF8ToWide(const char *buf) +{ + DWORD size; + LPWSTR wide; + + if (!buf) { + return NULL; + } + + size = MultiByteToWideChar(CP_UTF8, 0, buf, -1, NULL, 0); + if (size == 0) { + return NULL; + } + wide = PORT_Alloc(sizeof(WCHAR) * size); + if (!wide) { + return NULL; + } + size = MultiByteToWideChar(CP_UTF8, 0, buf, -1, wide, size); + if (size == 0) { + PORT_Free(wide); + return NULL; + } + return wide; +} + +static int +os_open(const char *filename, int oflag, int pmode) +{ + int fd; + + if (!filename) { + return -1; + } + + wchar_t *filenameWide = _NSSUTIL_UTF8ToWide(filename); + if (!filenameWide) { + return -1; + } + fd = _wopen(filenameWide, oflag, pmode); + PORT_Free(filenameWide); + + return fd; +} + +static int +os_stat(const char *path, os_stat_type *buffer) +{ + int result; + + if (!path) { + return -1; + } + + wchar_t *pathWide = _NSSUTIL_UTF8ToWide(path); + if (!pathWide) { + return -1; + } + result = _wstat(pathWide, buffer); + PORT_Free(pathWide); + + return result; +} + +static FILE * +os_fopen(const char *filename, const char *mode) +{ + FILE *fp; + + if (!filename || !mode) { + return NULL; + } + + wchar_t *filenameWide = _NSSUTIL_UTF8ToWide(filename); + if (!filenameWide) { + return NULL; + } + wchar_t *modeWide = _NSSUTIL_UTF8ToWide(mode); + if (!modeWide) { + PORT_Free(filenameWide); + return NULL; + } + fp = _wfopen(filenameWide, modeWide); + PORT_Free(filenameWide); + PORT_Free(modeWide); + + return fp; +} + +PRStatus +_NSSUTIL_Access(const char *path, PRAccessHow how) +{ + int result; + + if (!path) { + return PR_FAILURE; + } + + int mode; + switch (how) { + case PR_ACCESS_WRITE_OK: + mode = 2; + break; + case PR_ACCESS_READ_OK: + mode = 4; + break; + case PR_ACCESS_EXISTS: + mode = 0; + break; + default: + return PR_FAILURE; + } + + wchar_t *pathWide = _NSSUTIL_UTF8ToWide(path); + if (!pathWide) { + return PR_FAILURE; + } + result = _waccess(pathWide, mode); + PORT_Free(pathWide); + + return result < 0 ? PR_FAILURE : PR_SUCCESS; +} + +static PRStatus +nssutil_Delete(const char *name) +{ + BOOL result; + + if (!name) { + return PR_FAILURE; + } + + wchar_t *nameWide = _NSSUTIL_UTF8ToWide(name); + if (!nameWide) { + return PR_FAILURE; + } + result = DeleteFileW(nameWide); + PORT_Free(nameWide); + + return result ? PR_SUCCESS : PR_FAILURE; +} + +static PRStatus +nssutil_Rename(const char *from, const char *to) +{ + BOOL result; + + if (!from || !to) { + return PR_FAILURE; + } + + wchar_t *fromWide = _NSSUTIL_UTF8ToWide(from); + if (!fromWide) { + return PR_FAILURE; + } + wchar_t *toWide = _NSSUTIL_UTF8ToWide(to); + if (!toWide) { + PORT_Free(fromWide); + return PR_FAILURE; + } + result = MoveFileW(fromWide, toWide); + PORT_Free(fromWide); + PORT_Free(toWide); + + return result ? PR_SUCCESS : PR_FAILURE; +} #else +#define os_fopen fopen #define os_open open #define os_fdopen fdopen #define os_stat stat @@ -51,6 +221,8 @@ #define os_open_permissions_type mode_t #define os_open_permissions_default 0600 #define os_stat_type struct stat +#define nssutil_Delete PR_Delete +#define nssutil_Rename PR_Rename #endif /**************************************************************** @@ -219,7 +391,7 @@ nssutil_ReadSecmodDB(const char *appName, } /* do we really want to use streams here */ - fd = fopen(dbname, "r"); + fd = os_fopen(dbname, "r"); if (fd == NULL) goto done; @@ -403,7 +575,7 @@ done: } /* old one exists */ - status = PR_Access(olddbname, PR_ACCESS_EXISTS); + status = _NSSUTIL_Access(olddbname, PR_ACCESS_EXISTS); if (status == PR_SUCCESS) { PR_smprintf_free(olddbname); PORT_ZFree(moduleList, useCount * sizeof(char *)); @@ -532,7 +704,7 @@ nssutil_DeleteSecmodDBEntry(const char *appName, } /* do we really want to use streams here */ - fd = fopen(dbname, "r"); + fd = os_fopen(dbname, "r"); if (fd == NULL) goto loser; @@ -602,10 +774,10 @@ nssutil_DeleteSecmodDBEntry(const char *appName, fclose(fd2); if (found) { /* rename dbname2 to dbname */ - PR_Delete(dbname); - PR_Rename(dbname2, dbname); + nssutil_Delete(dbname); + nssutil_Rename(dbname2, dbname); } else { - PR_Delete(dbname2); + nssutil_Delete(dbname2); } PORT_Free(dbname2); PORT_Free(lib); @@ -621,7 +793,7 @@ loser: fclose(fd2); } if (dbname2) { - PR_Delete(dbname2); + nssutil_Delete(dbname2); PORT_Free(dbname2); } PORT_Free(lib); diff --git a/security/nss/lib/util/utilpars.c b/security/nss/lib/util/utilpars.c index 7116d26f3..e7435bfcc 100644 --- a/security/nss/lib/util/utilpars.c +++ b/security/nss/lib/util/utilpars.c @@ -589,6 +589,7 @@ struct nssutilArgSlotFlagTable { } static struct nssutilArgSlotFlagTable nssutil_argSlotFlagTable[] = { NSSUTIL_ARG_ENTRY(RSA, SECMOD_RSA_FLAG), + NSSUTIL_ARG_ENTRY(ECC, SECMOD_ECC_FLAG), NSSUTIL_ARG_ENTRY(DSA, SECMOD_RSA_FLAG), NSSUTIL_ARG_ENTRY(RC2, SECMOD_RC4_FLAG), NSSUTIL_ARG_ENTRY(RC4, SECMOD_RC2_FLAG), @@ -1110,12 +1111,8 @@ _NSSUTIL_EvaluateConfigDir(const char *configdir, NSSDBType dbType; PRBool checkEnvDefaultDB = PR_FALSE; *appName = NULL; -/* force the default */ -#ifdef NSS_DISABLE_DBM + /* force the default */ dbType = NSS_DB_TYPE_SQL; -#else - dbType = NSS_DB_TYPE_LEGACY; -#endif if (configdir == NULL) { checkEnvDefaultDB = PR_TRUE; } else if (PORT_Strncmp(configdir, MULTIACCESS, sizeof(MULTIACCESS) - 1) == 0) { diff --git a/security/nss/lib/util/utilpars.h b/security/nss/lib/util/utilpars.h index 70767263a..1b0b1ff1c 100644 --- a/security/nss/lib/util/utilpars.h +++ b/security/nss/lib/util/utilpars.h @@ -59,5 +59,11 @@ char *NSSUTIL_MkNSSString(char **slotStrings, int slotCount, PRBool internal, char *_NSSUTIL_GetSecmodName(const char *param, NSSDBType *dbType, char **appName, char **filename, PRBool *rw); const char *_NSSUTIL_EvaluateConfigDir(const char *configdir, NSSDBType *dbType, char **app); +#if defined(_WIN32) +wchar_t *_NSSUTIL_UTF8ToWide(const char *buf); +PRStatus _NSSUTIL_Access(const char *path, PRAccessHow how); +#else +#define _NSSUTIL_Access(path, how) PR_Access((path), (how)) +#endif #endif /* _UTILPARS_H_ */ diff --git a/security/nss/lib/util/utilparst.h b/security/nss/lib/util/utilparst.h index f2148e6e3..5dda09028 100644 --- a/security/nss/lib/util/utilparst.h +++ b/security/nss/lib/util/utilparst.h @@ -43,7 +43,7 @@ #define NSSUTIL_DEFAULT_INTERNAL_INIT3 \ " askpw=any timeout=30})\"" #define NSSUTIL_DEFAULT_SFTKN_FLAGS \ - "slotFlags=[RSA,DSA,DH,RC2,RC4,DES,RANDOM,SHA1,MD5,MD2,SSL,TLS,AES,Camellia,SEED,SHA256,SHA512]" + "slotFlags=[ECC,RSA,DSA,DH,RC2,RC4,DES,RANDOM,SHA1,MD5,MD2,SSL,TLS,AES,Camellia,SEED,SHA256,SHA512]" #define NSSUTIL_DEFAULT_CIPHER_ORDER 0 #define NSSUTIL_DEFAULT_TRUST_ORDER 50 diff --git a/security/nss/lib/util/utilrename.h b/security/nss/lib/util/utilrename.h index 1aea3d284..19ddba666 100644 --- a/security/nss/lib/util/utilrename.h +++ b/security/nss/lib/util/utilrename.h @@ -70,6 +70,8 @@ #define PORT_UCS2_ASCIIConversion PORT_UCS2_ASCIIConversion_Util #define PORT_UCS2_UTF8Conversion PORT_UCS2_UTF8Conversion_Util #define PORT_ZAlloc PORT_ZAlloc_Util +#define PORT_ZAllocAligned PORT_ZAllocAligned_Util +#define PORT_ZAllocAlignedOffset PORT_ZAllocAlignedOffset_Util #define PORT_ZFree PORT_ZFree_Util #define SEC_ASN1Decode SEC_ASN1Decode_Util #define SEC_ASN1DecodeInteger SEC_ASN1DecodeInteger_Util diff --git a/security/nss/mach b/security/nss/mach new file mode 100644 index 000000000..715f1a9e3 --- /dev/null +++ b/security/nss/mach @@ -0,0 +1,219 @@ +#!/usr/bin/env python +# +# 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 is a collection of helper tools to get stuff done in NSS. +# + +import sys +import argparse +import subprocess +import os +import platform +from hashlib import sha256 + +cwd = os.path.dirname(os.path.abspath(__file__)) + + +class cfAction(argparse.Action): + docker_command = ["docker"] + restorecon = None + + def __call__(self, parser, args, values, option_string=None): + if not args.noroot: + self.setDockerCommand() + + if values: + files = [os.path.relpath(os.path.abspath(x), start=cwd) for x in values] + else: + files = self.modifiedFiles() + files = [os.path.join('/home/worker/nss', x) for x in files] + + # First check if we can run docker. + try: + with open(os.devnull, "w") as f: + subprocess.check_call( + self.docker_command + ["images"], stdout=f) + except: + print("Please install docker and start the docker daemon.") + sys.exit(1) + + docker_image = 'clang-format-service:latest' + cf_docker_folder = cwd + "/automation/clang-format" + + # Build the image if necessary. + if self.filesChanged(cf_docker_folder): + self.buildImage(docker_image, cf_docker_folder) + + # Check if we have the docker image. + try: + command = self.docker_command + [ + "image", "inspect", "clang-format-service:latest" + ] + with open(os.devnull, "w") as f: + subprocess.check_call(command, stdout=f) + except: + print("I have to build the docker image first.") + self.buildImage(docker_image, cf_docker_folder) + + command = self.docker_command + [ + 'run', '-v', cwd + ':/home/worker/nss:Z', '--rm', '-ti', docker_image + ] + # The clang format script returns 1 if something's to do. We don't + # care. + subprocess.call(command + files) + if self.restorecon is not None: + subprocess.call([self.restorecon, '-R', cwd]) + + def filesChanged(self, path): + hash = sha256() + for dirname, dirnames, files in os.walk(path): + for file in files: + with open(os.path.join(dirname, file), "rb") as f: + hash.update(f.read()) + chk_file = cwd + "/.chk" + old_chk = "" + new_chk = hash.hexdigest() + if os.path.exists(chk_file): + with open(chk_file) as f: + old_chk = f.readline() + if old_chk != new_chk: + with open(chk_file, "w+") as f: + f.write(new_chk) + return True + return False + + def buildImage(self, docker_image, cf_docker_folder): + command = self.docker_command + [ + "build", "-t", docker_image, cf_docker_folder + ] + subprocess.check_call(command) + return + + def setDockerCommand(self): + if platform.system() == "Linux": + from distutils.spawn import find_executable + self.restorecon = find_executable('restorecon') + self.docker_command = ["sudo"] + self.docker_command + + def modifiedFiles(self): + files = [] + if os.path.exists(os.path.join(cwd, '.hg')): + st = subprocess.Popen(['hg', 'status', '-m', '-a'], + cwd=cwd, stdout=subprocess.PIPE) + for line in iter(st.stdout.readline, ''): + files += [line[2:].rstrip()] + elif os.path.exists(os.path.join(cwd, '.git')): + st = subprocess.Popen(['git', 'status', '--porcelain'], + cwd=cwd, stdout=subprocess.PIPE) + for line in iter(st.stdout.readline, ''): + if line[1] == 'M' or line[1] != 'D' and \ + (line[0] == 'M' or line[0] == 'A' or + line[0] == 'C' or line[0] == 'U'): + files += [line[3:].rstrip()] + elif line[0] == 'R': + files += [line[line.index(' -> ', beg=4) + 4:]] + else: + print('Warning: neither mercurial nor git detected!') + + def isFormatted(x): + return x[-2:] == '.c' or x[-3:] == '.cc' or x[-2:] == '.h' + return [x for x in files if isFormatted(x)] + + +class buildAction(argparse.Action): + + def __call__(self, parser, args, values, option_string=None): + cwd = os.path.dirname(os.path.abspath(__file__)) + subprocess.check_call([cwd + "/build.sh"] + values) + + +class testAction(argparse.Action): + + def runTest(self, test, cycles="standard"): + cwd = os.path.dirname(os.path.abspath(__file__)) + domsuf = os.getenv('DOMSUF', "localdomain") + host = os.getenv('HOST', "localhost") + env = { + "NSS_TESTS": test, + "NSS_CYCLES": cycles, + "DOMSUF": domsuf, + "HOST": host + } + os_env = os.environ + os_env.update(env) + command = cwd + "/tests/all.sh" + subprocess.check_call(command, env=os_env) + + def __call__(self, parser, args, values, option_string=None): + self.runTest(values) + + +class commandsAction(argparse.Action): + commands = [] + + def __call__(self, parser, args, values, option_string=None): + for c in commandsAction.commands: + print(c) + + +def parse_arguments(): + parser = argparse.ArgumentParser( + description='NSS helper script. ' + + 'Make sure to separate sub-command arguments with --.') + subparsers = parser.add_subparsers() + + parser_build = subparsers.add_parser( + 'build', help='All arguments are passed to build.sh') + parser_build.add_argument( + 'build_args', nargs='*', help="build arguments", action=buildAction) + + parser_cf = subparsers.add_parser( + 'clang-format', + help=""" + Run clang-format. + + By default this runs against any files that you have modified. If + there are no modified files, it checks everything. + """) + parser_cf.add_argument( + '--noroot', + help='On linux, suppress the use of \'sudo\' for running docker.', + action='store_true') + parser_cf.add_argument( + '<file/dir>', + nargs='*', + help="Specify files or directories to run clang-format on", + action=cfAction) + + parser_test = subparsers.add_parser( + 'tests', help='Run tests through tests/all.sh.') + tests = [ + "cipher", "lowhash", "chains", "cert", "dbtests", "tools", "fips", + "sdr", "crmf", "smime", "ssl", "ocsp", "merge", "pkits", "ec", + "gtests", "ssl_gtests" + ] + parser_test.add_argument( + 'test', choices=tests, help="Available tests", action=testAction) + + parser_commands = subparsers.add_parser( + 'mach-commands', + help="list commands") + parser_commands.add_argument( + 'mach-commands', + nargs='*', + action=commandsAction) + + commandsAction.commands = [c for c in subparsers.choices] + return parser.parse_args() + + +def main(): + parse_arguments() + + +if __name__ == '__main__': + main() diff --git a/security/nss/nss-tool/.clang-format b/security/nss/nss-tool/.clang-format new file mode 100644 index 000000000..06e3c5115 --- /dev/null +++ b/security/nss/nss-tool/.clang-format @@ -0,0 +1,4 @@ +--- +Language: Cpp +BasedOnStyle: Google +... diff --git a/security/nss/nss-tool/common/argparse.cc b/security/nss/nss-tool/common/argparse.cc new file mode 100644 index 000000000..3b7c73891 --- /dev/null +++ b/security/nss/nss-tool/common/argparse.cc @@ -0,0 +1,23 @@ +/* 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 "argparse.h" + +ArgParser::ArgParser(const std::vector<std::string>& arguments) { + for (size_t i = 0; i < arguments.size(); i++) { + std::string arg = arguments.at(i); + if (arg.find("--") == 0) { + // look for an option argument + if (i + 1 < arguments.size() && arguments.at(i + 1).find("--") != 0) { + programArgs_[arg] = arguments.at(i + 1); + i++; + } else { + programArgs_[arg] = ""; + } + } else { + // positional argument (e.g. required argument) + positionalArgs_.push_back(arg); + } + } +} diff --git a/security/nss/nss-tool/common/argparse.h b/security/nss/nss-tool/common/argparse.h new file mode 100644 index 000000000..8645d5aaa --- /dev/null +++ b/security/nss/nss-tool/common/argparse.h @@ -0,0 +1,30 @@ +/* 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 argparse_h__ +#define argparse_h__ + +#include <string> +#include <unordered_map> +#include <vector> + +class ArgParser { + public: + ArgParser(const std::vector<std::string>& arguments); + + bool Has(std::string arg) const { return programArgs_.count(arg) > 0; } + + std::string Get(std::string arg) const { return programArgs_.at(arg); } + + size_t GetPositionalArgumentCount() const { return positionalArgs_.size(); } + std::string GetPositionalArgument(size_t pos) const { + return positionalArgs_.at(pos); + } + + private: + std::unordered_map<std::string, std::string> programArgs_; + std::vector<std::string> positionalArgs_; +}; + +#endif // argparse_h__ diff --git a/security/nss/nss-tool/common/tool.h b/security/nss/nss-tool/common/tool.h new file mode 100644 index 000000000..17ebcac29 --- /dev/null +++ b/security/nss/nss-tool/common/tool.h @@ -0,0 +1,20 @@ +/* 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 tool_h__ +#define tool_h__ + +#include <string> +#include <vector> + +class Tool { + public: + virtual bool Run(const std::vector<std::string>& arguments) = 0; + virtual ~Tool() {} + + private: + virtual void Usage() = 0; +}; + +#endif // tool_h__ diff --git a/security/nss/nss-tool/common/util.cc b/security/nss/nss-tool/common/util.cc new file mode 100644 index 000000000..77459155a --- /dev/null +++ b/security/nss/nss-tool/common/util.cc @@ -0,0 +1,216 @@ +/* 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 "util.h" + +#include <fstream> +#include <iomanip> +#include <iostream> +#include <sstream> +#include <string> + +#include <prerror.h> + +#if defined(__unix__) || defined(__APPLE__) +#include <termios.h> +#include <unistd.h> +#elif defined(WIN32) || defined(_WIN64) +#include <Windows.h> +#endif + +static std::string GetPassword(const std::string &prompt) { + std::cout << prompt << std::endl; + +#if defined(__unix__) || defined(__APPLE__) + termios oldt; + tcgetattr(STDIN_FILENO, &oldt); + termios newt = oldt; + newt.c_lflag &= ~ECHO; + tcsetattr(STDIN_FILENO, TCSANOW, &newt); +#elif defined(WIN32) || defined(_WIN64) + HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE); + DWORD mode = 0; + GetConsoleMode(hStdin, &mode); + SetConsoleMode(hStdin, mode & (~ENABLE_ECHO_INPUT)); +#endif + + std::string pw; + std::getline(std::cin, pw); + +#if defined(__unix__) || defined(__APPLE__) + tcsetattr(STDIN_FILENO, TCSANOW, &oldt); +#elif defined(WIN32) || defined(_WIN64) + SetConsoleMode(hStdin, mode); +#endif + + return pw; +} + +static char *GetModulePassword(PK11SlotInfo *slot, int retry, void *arg) { + if (arg == nullptr) { + return nullptr; + } + + PwData *pwData = reinterpret_cast<PwData *>(arg); + + if (retry > 0) { + std::cerr << "Incorrect password/PIN entered." << std::endl; + return nullptr; + } + + switch (pwData->source) { + case PW_NONE: + case PW_FROMFILE: + std::cerr << "Password input method not supported." << std::endl; + return nullptr; + case PW_PLAINTEXT: + return PL_strdup(pwData->data); + default: + break; + } + + std::cerr << "Password check failed: No password found." << std::endl; + return nullptr; +} + +static std::vector<uint8_t> ReadFromIstream(std::istream &is) { + std::vector<uint8_t> data; + while (is) { + char buf[1024]; + is.read(buf, sizeof(buf)); + data.insert(data.end(), buf, buf + is.gcount()); + } + + return data; +} + +static std::string GetNewPasswordFromUser(void) { + std::string pw; + + while (true) { + pw = GetPassword("Enter new password: "); + if (pw == GetPassword("Re-enter password: ")) { + break; + } + + std::cerr << "Passwords do not match. Try again." << std::endl; + } + + return pw; +} + +bool InitSlotPassword(void) { + ScopedPK11SlotInfo slot(PK11_GetInternalKeySlot()); + if (slot.get() == nullptr) { + std::cerr << "Error: Init PK11SlotInfo failed!" << std::endl; + return false; + } + + std::cout << "Enter a password which will be used to encrypt your keys." + << std::endl + << std::endl; + std::string pw = GetNewPasswordFromUser(); + + SECStatus rv = PK11_InitPin(slot.get(), nullptr, pw.c_str()); + if (rv != SECSuccess) { + std::cerr << "Init db password failed." << std::endl; + return false; + } + + return true; +} + +bool ChangeSlotPassword(void) { + ScopedPK11SlotInfo slot(PK11_GetInternalKeySlot()); + if (slot.get() == nullptr) { + std::cerr << "Error: Init PK11SlotInfo failed!" << std::endl; + return false; + } + + // get old password and authenticate to db + PK11_SetPasswordFunc(&GetModulePassword); + std::string oldPw = GetPassword("Enter your current password: "); + PwData pwData = {PW_PLAINTEXT, const_cast<char *>(oldPw.c_str())}; + SECStatus rv = PK11_Authenticate(slot.get(), false /*loadCerts*/, &pwData); + if (rv != SECSuccess) { + std::cerr << "Password incorrect." << std::endl; + return false; + } + + // get new password + std::string newPw = GetNewPasswordFromUser(); + + if (PK11_ChangePW(slot.get(), oldPw.c_str(), newPw.c_str()) != SECSuccess) { + std::cerr << "Failed to change password." << std::endl; + return false; + } + + std::cout << "Password changed successfully." << std::endl; + return true; +} + +bool DBLoginIfNeeded(const ScopedPK11SlotInfo &slot) { + if (!PK11_NeedLogin(slot.get())) { + return true; + } + + PK11_SetPasswordFunc(&GetModulePassword); + std::string pw = GetPassword("Enter your password: "); + PwData pwData = {PW_PLAINTEXT, const_cast<char *>(pw.c_str())}; + SECStatus rv = PK11_Authenticate(slot.get(), true /*loadCerts*/, &pwData); + if (rv != SECSuccess) { + std::cerr << "Could not authenticate to token " + << PK11_GetTokenName(slot.get()) << ". Failed with error " + << PR_ErrorToName(PR_GetError()) << std::endl; + return false; + } + std::cout << std::endl; + + return true; +} + +std::string StringToHex(const ScopedSECItem &input) { + std::stringstream ss; + ss << "0x"; + for (size_t i = 0; i < input->len; i++) { + ss << std::hex << std::setfill('0') << std::setw(2) + << static_cast<int>(input->data[i]); + } + + return ss.str(); +} + +std::vector<uint8_t> ReadInputData(std::string dataPath) { + std::vector<uint8_t> data; + if (dataPath.empty()) { + std::cout << "No input file path given, using stdin." << std::endl; + data = ReadFromIstream(std::cin); + } else { + std::ifstream is(dataPath, std::ifstream::binary); + if (is.good()) { + data = ReadFromIstream(is); + } else { + std::cerr << "IO Error when opening " << dataPath << std::endl; + std::cerr << "Input file does not exist or you don't have permissions." + << std::endl; + } + } + + return data; +} + +std::istream &GetStreamFromFileOrStdin(std::string &path, std::ifstream &ifs) { + if (path.empty()) { + return std::cin; + } + + ifs.open(path, std::ifstream::binary); + if (!ifs.good()) { + std::cerr << "IO Error when opening " << path << std::endl; + std::cerr << "Input file does not exist or you don't have permissions." + << std::endl; + } + + return ifs; +} diff --git a/security/nss/nss-tool/common/util.h b/security/nss/nss-tool/common/util.h new file mode 100644 index 000000000..58fb05839 --- /dev/null +++ b/security/nss/nss-tool/common/util.h @@ -0,0 +1,32 @@ +/* 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 util_h__ +#define util_h__ + +#include "nspr.h" +#include "scoped_ptrs.h" + +#include <secmodt.h> +#include <string> +#include <vector> + +#ifndef PORT_Malloc +#define PORT_Malloc PR_Malloc +#endif + +enum PwDataType { PW_NONE = 0, PW_FROMFILE = 1, PW_PLAINTEXT = 2 }; +typedef struct { + PwDataType source; + char *data; +} PwData; + +bool InitSlotPassword(void); +bool ChangeSlotPassword(void); +bool DBLoginIfNeeded(const ScopedPK11SlotInfo &slot); +std::string StringToHex(const ScopedSECItem &input); +std::vector<uint8_t> ReadInputData(std::string dataPath); +std::istream &GetStreamFromFileOrStdin(std::string &path, std::ifstream &ifs); + +#endif // util_h__ diff --git a/security/nss/nss-tool/db/dbtool.cc b/security/nss/nss-tool/db/dbtool.cc new file mode 100644 index 000000000..8c369cf05 --- /dev/null +++ b/security/nss/nss-tool/db/dbtool.cc @@ -0,0 +1,497 @@ +/* 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 "dbtool.h" +#include "argparse.h" +#include "scoped_ptrs.h" +#include "util.h" + +#include <iomanip> +#include <iostream> +#include <regex> +#include <sstream> + +#include <cert.h> +#include <certdb.h> +#include <nss.h> +#include <pk11pub.h> +#include <prerror.h> +#include <prio.h> + +const std::vector<std::string> kCommandArgs( + {"--create", "--list-certs", "--import-cert", "--list-keys", "--import-key", + "--delete-cert", "--delete-key", "--change-password"}); + +static bool HasSingleCommandArgument(const ArgParser &parser) { + auto pred = [&](const std::string &cmd) { return parser.Has(cmd); }; + return std::count_if(kCommandArgs.begin(), kCommandArgs.end(), pred) == 1; +} + +static bool HasArgumentRequiringWriteAccess(const ArgParser &parser) { + return parser.Has("--create") || parser.Has("--import-cert") || + parser.Has("--import-key") || parser.Has("--delete-cert") || + parser.Has("--delete-key") || parser.Has("--change-password"); +} + +static std::string PrintFlags(unsigned int flags) { + std::stringstream ss; + if ((flags & CERTDB_VALID_CA) && !(flags & CERTDB_TRUSTED_CA) && + !(flags & CERTDB_TRUSTED_CLIENT_CA)) { + ss << "c"; + } + if ((flags & CERTDB_TERMINAL_RECORD) && !(flags & CERTDB_TRUSTED)) { + ss << "p"; + } + if (flags & CERTDB_TRUSTED_CA) { + ss << "C"; + } + if (flags & CERTDB_TRUSTED_CLIENT_CA) { + ss << "T"; + } + if (flags & CERTDB_TRUSTED) { + ss << "P"; + } + if (flags & CERTDB_USER) { + ss << "u"; + } + if (flags & CERTDB_SEND_WARN) { + ss << "w"; + } + if (flags & CERTDB_INVISIBLE_CA) { + ss << "I"; + } + if (flags & CERTDB_GOVT_APPROVED_CA) { + ss << "G"; + } + return ss.str(); +} + +static const char *const keyTypeName[] = {"null", "rsa", "dsa", "fortezza", + "dh", "kea", "ec"}; + +void DBTool::Usage() { + std::cerr << "Usage: nss db [--path <directory>]" << std::endl; + std::cerr << " --create" << std::endl; + std::cerr << " --change-password" << std::endl; + std::cerr << " --list-certs" << std::endl; + std::cerr << " --import-cert [<path>] --name <name> [--trusts <trusts>]" + << std::endl; + std::cerr << " --list-keys" << std::endl; + std::cerr << " --import-key [<path> [-- name <name>]]" << std::endl; + std::cerr << " --delete-cert <name>" << std::endl; + std::cerr << " --delete-key <name>" << std::endl; +} + +bool DBTool::Run(const std::vector<std::string> &arguments) { + ArgParser parser(arguments); + + if (!HasSingleCommandArgument(parser)) { + Usage(); + return false; + } + + PRAccessHow how = PR_ACCESS_READ_OK; + bool readOnly = true; + if (HasArgumentRequiringWriteAccess(parser)) { + how = PR_ACCESS_WRITE_OK; + readOnly = false; + } + + std::string initDir("."); + if (parser.Has("--path")) { + initDir = parser.Get("--path"); + } + if (PR_Access(initDir.c_str(), how) != PR_SUCCESS) { + std::cerr << "Directory '" << initDir + << "' does not exist or you don't have permissions!" << std::endl; + return false; + } + + std::cout << "Using database directory: " << initDir << std::endl + << std::endl; + + bool dbFilesExist = PathHasDBFiles(initDir); + if (parser.Has("--create") && dbFilesExist) { + std::cerr << "Trying to create database files in a directory where they " + "already exists. Delete the db files before creating new ones." + << std::endl; + return false; + } + if (!parser.Has("--create") && !dbFilesExist) { + std::cerr << "No db files found." << std::endl; + std::cerr << "Create them using 'nss db --create [--path /foo/bar]' before " + "continuing." + << std::endl; + return false; + } + + // init NSS + const char *certPrefix = ""; // certutil -P option --- can leave this empty + SECStatus rv = NSS_Initialize(initDir.c_str(), certPrefix, certPrefix, + "secmod.db", readOnly ? NSS_INIT_READONLY : 0); + if (rv != SECSuccess) { + std::cerr << "NSS init failed!" << std::endl; + return false; + } + + bool ret = true; + if (parser.Has("--list-certs")) { + ListCertificates(); + } else if (parser.Has("--import-cert")) { + ret = ImportCertificate(parser); + } else if (parser.Has("--create")) { + ret = InitSlotPassword(); + if (ret) { + std::cout << "DB files created successfully." << std::endl; + } + } else if (parser.Has("--list-keys")) { + ret = ListKeys(); + } else if (parser.Has("--import-key")) { + ret = ImportKey(parser); + } else if (parser.Has("--delete-cert")) { + ret = DeleteCert(parser); + } else if (parser.Has("--delete-key")) { + ret = DeleteKey(parser); + } else if (parser.Has("--change-password")) { + ret = ChangeSlotPassword(); + } + + // shutdown nss + if (NSS_Shutdown() != SECSuccess) { + std::cerr << "NSS Shutdown failed!" << std::endl; + return false; + } + + return ret; +} + +bool DBTool::PathHasDBFiles(std::string path) { + std::regex certDBPattern("cert.*\\.db"); + std::regex keyDBPattern("key.*\\.db"); + + PRDir *dir = PR_OpenDir(path.c_str()); + if (!dir) { + std::cerr << "Directory " << path << " could not be accessed!" << std::endl; + return false; + } + + PRDirEntry *ent; + bool dbFileExists = false; + while ((ent = PR_ReadDir(dir, PR_SKIP_BOTH))) { + if (std::regex_match(ent->name, certDBPattern) || + std::regex_match(ent->name, keyDBPattern) || + "secmod.db" == std::string(ent->name)) { + dbFileExists = true; + break; + } + } + + (void)PR_CloseDir(dir); + return dbFileExists; +} + +void DBTool::ListCertificates() { + ScopedCERTCertList list(PK11_ListCerts(PK11CertListAll, nullptr)); + CERTCertListNode *node; + + std::cout << std::setw(60) << std::left << "Certificate Nickname" + << " " + << "Trust Attributes" << std::endl; + std::cout << std::setw(60) << std::left << "" + << " " + << "SSL,S/MIME,JAR/XPI" << std::endl + << std::endl; + + for (node = CERT_LIST_HEAD(list); !CERT_LIST_END(node, list); + node = CERT_LIST_NEXT(node)) { + CERTCertificate *cert = node->cert; + + std::string name("(unknown)"); + char *appData = static_cast<char *>(node->appData); + if (appData && strlen(appData) > 0) { + name = appData; + } else if (cert->nickname && strlen(cert->nickname) > 0) { + name = cert->nickname; + } else if (cert->emailAddr && strlen(cert->emailAddr) > 0) { + name = cert->emailAddr; + } + + CERTCertTrust trust; + std::string trusts; + if (CERT_GetCertTrust(cert, &trust) == SECSuccess) { + std::stringstream ss; + ss << PrintFlags(trust.sslFlags); + ss << ","; + ss << PrintFlags(trust.emailFlags); + ss << ","; + ss << PrintFlags(trust.objectSigningFlags); + trusts = ss.str(); + } else { + trusts = ",,"; + } + std::cout << std::setw(60) << std::left << name << " " << trusts + << std::endl; + } +} + +bool DBTool::ImportCertificate(const ArgParser &parser) { + if (!parser.Has("--name")) { + std::cerr << "A name (--name) is required to import a certificate." + << std::endl; + Usage(); + return false; + } + + std::string derFilePath = parser.Get("--import-cert"); + std::string certName = parser.Get("--name"); + std::string trustString("TCu,Cu,Tu"); + if (parser.Has("--trusts")) { + trustString = parser.Get("--trusts"); + } + + CERTCertTrust trust; + SECStatus rv = CERT_DecodeTrustString(&trust, trustString.c_str()); + if (rv != SECSuccess) { + std::cerr << "Cannot decode trust string!" << std::endl; + return false; + } + + ScopedPK11SlotInfo slot(PK11_GetInternalKeySlot()); + if (slot.get() == nullptr) { + std::cerr << "Error: Init PK11SlotInfo failed!" << std::endl; + return false; + } + + std::vector<uint8_t> certData = ReadInputData(derFilePath); + + ScopedCERTCertificate cert(CERT_DecodeCertFromPackage( + reinterpret_cast<char *>(certData.data()), certData.size())); + if (cert.get() == nullptr) { + std::cerr << "Error: Could not decode certificate!" << std::endl; + return false; + } + + rv = PK11_ImportCert(slot.get(), cert.get(), CK_INVALID_HANDLE, + certName.c_str(), PR_FALSE); + if (rv != SECSuccess) { + // TODO handle authentication -> PK11_Authenticate (see certutil.c line + // 134) + std::cerr << "Error: Could not add certificate to database!" << std::endl; + return false; + } + + rv = CERT_ChangeCertTrust(CERT_GetDefaultCertDB(), cert.get(), &trust); + if (rv != SECSuccess) { + std::cerr << "Cannot change cert's trust" << std::endl; + return false; + } + + std::cout << "Certificate import was successful!" << std::endl; + // TODO show information about imported certificate + return true; +} + +bool DBTool::ListKeys() { + ScopedPK11SlotInfo slot(PK11_GetInternalKeySlot()); + if (slot.get() == nullptr) { + std::cerr << "Error: Init PK11SlotInfo failed!" << std::endl; + return false; + } + + if (!DBLoginIfNeeded(slot)) { + return false; + } + + ScopedSECKEYPrivateKeyList list(PK11_ListPrivateKeysInSlot(slot.get())); + if (list.get() == nullptr) { + std::cerr << "Listing private keys failed with error " + << PR_ErrorToName(PR_GetError()) << std::endl; + return false; + } + + SECKEYPrivateKeyListNode *node; + int count = 0; + for (node = PRIVKEY_LIST_HEAD(list.get()); + !PRIVKEY_LIST_END(node, list.get()); node = PRIVKEY_LIST_NEXT(node)) { + char *keyNameRaw = PK11_GetPrivateKeyNickname(node->key); + std::string keyName(keyNameRaw ? keyNameRaw : ""); + + if (keyName.empty()) { + ScopedCERTCertificate cert(PK11_GetCertFromPrivateKey(node->key)); + if (cert.get()) { + if (cert->nickname && strlen(cert->nickname) > 0) { + keyName = cert->nickname; + } else if (cert->emailAddr && strlen(cert->emailAddr) > 0) { + keyName = cert->emailAddr; + } + } + if (keyName.empty()) { + keyName = "(none)"; // default value + } + } + + SECKEYPrivateKey *key = node->key; + ScopedSECItem keyIDItem(PK11_GetLowLevelKeyIDForPrivateKey(key)); + if (keyIDItem.get() == nullptr) { + std::cerr << "Error: PK11_GetLowLevelKeyIDForPrivateKey failed!" + << std::endl; + continue; + } + + std::string keyID = StringToHex(keyIDItem); + + if (count++ == 0) { + // print header + std::cout << std::left << std::setw(20) << "<key#, key name>" + << std::setw(20) << "key type" + << "key id" << std::endl; + } + + std::stringstream leftElem; + leftElem << "<" << count << ", " << keyName << ">"; + std::cout << std::left << std::setw(20) << leftElem.str() << std::setw(20) + << keyTypeName[key->keyType] << keyID << std::endl; + } + + if (count == 0) { + std::cout << "No keys found." << std::endl; + } + + return true; +} + +bool DBTool::ImportKey(const ArgParser &parser) { + std::string privKeyFilePath = parser.Get("--import-key"); + std::string name; + if (parser.Has("--name")) { + name = parser.Get("--name"); + } + + ScopedPK11SlotInfo slot(PK11_GetInternalKeySlot()); + if (slot.get() == nullptr) { + std::cerr << "Error: Init PK11SlotInfo failed!" << std::endl; + return false; + } + + if (!DBLoginIfNeeded(slot)) { + return false; + } + + std::vector<uint8_t> privKeyData = ReadInputData(privKeyFilePath); + if (privKeyData.empty()) { + return false; + } + SECItem pkcs8PrivKeyItem = { + siBuffer, reinterpret_cast<unsigned char *>(privKeyData.data()), + static_cast<unsigned int>(privKeyData.size())}; + + SECItem nickname = {siBuffer, nullptr, 0}; + if (!name.empty()) { + nickname.data = const_cast<unsigned char *>( + reinterpret_cast<const unsigned char *>(name.c_str())); + nickname.len = static_cast<unsigned int>(name.size()); + } + + SECStatus rv = PK11_ImportDERPrivateKeyInfo( + slot.get(), &pkcs8PrivKeyItem, + nickname.data == nullptr ? nullptr : &nickname, nullptr /*publicValue*/, + true /*isPerm*/, false /*isPrivate*/, KU_ALL, nullptr); + if (rv != SECSuccess) { + std::cerr << "Importing a private key in DER format failed with error " + << PR_ErrorToName(PR_GetError()) << std::endl; + return false; + } + + std::cout << "Key import succeeded." << std::endl; + return true; +} + +bool DBTool::DeleteCert(const ArgParser &parser) { + std::string certName = parser.Get("--delete-cert"); + if (certName.empty()) { + std::cerr << "A name is required to delete a certificate." << std::endl; + Usage(); + return false; + } + + ScopedCERTCertificate cert(CERT_FindCertByNicknameOrEmailAddr( + CERT_GetDefaultCertDB(), certName.c_str())); + if (!cert) { + std::cerr << "Could not find certificate with name " << certName << "." + << std::endl; + return false; + } + + SECStatus rv = SEC_DeletePermCertificate(cert.get()); + if (rv != SECSuccess) { + std::cerr << "Unable to delete certificate with name " << certName << "." + << std::endl; + return false; + } + + std::cout << "Certificate with name " << certName << " deleted successfully." + << std::endl; + return true; +} + +bool DBTool::DeleteKey(const ArgParser &parser) { + std::string keyName = parser.Get("--delete-key"); + if (keyName.empty()) { + std::cerr << "A name is required to delete a key." << std::endl; + Usage(); + return false; + } + + ScopedPK11SlotInfo slot(PK11_GetInternalKeySlot()); + if (slot.get() == nullptr) { + std::cerr << "Error: Init PK11SlotInfo failed!" << std::endl; + return false; + } + + if (!DBLoginIfNeeded(slot)) { + return false; + } + + ScopedSECKEYPrivateKeyList list(PK11_ListPrivKeysInSlot( + slot.get(), const_cast<char *>(keyName.c_str()), nullptr)); + if (list.get() == nullptr) { + std::cerr << "Fetching private keys with nickname " << keyName + << " failed with error " << PR_ErrorToName(PR_GetError()) + << std::endl; + return false; + } + + unsigned int foundKeys = 0, deletedKeys = 0; + SECKEYPrivateKeyListNode *node; + for (node = PRIVKEY_LIST_HEAD(list.get()); + !PRIVKEY_LIST_END(node, list.get()); node = PRIVKEY_LIST_NEXT(node)) { + SECKEYPrivateKey *privKey = node->key; + foundKeys++; + // see PK11_DeleteTokenPrivateKey for example usage + // calling PK11_DeleteTokenPrivateKey directly does not work because it also + // destroys the SECKEYPrivateKey (by calling SECKEY_DestroyPrivateKey) - + // then SECKEY_DestroyPrivateKeyList does not + // work because it also calls SECKEY_DestroyPrivateKey + SECStatus rv = + PK11_DestroyTokenObject(privKey->pkcs11Slot, privKey->pkcs11ID); + if (rv == SECSuccess) { + deletedKeys++; + } + } + + if (foundKeys > deletedKeys) { + std::cerr << "Some keys could not be deleted." << std::endl; + } + + if (deletedKeys > 0) { + std::cout << "Found " << foundKeys << " keys." << std::endl; + std::cout << "Successfully deleted " << deletedKeys + << " key(s) with nickname " << keyName << "." << std::endl; + } else { + std::cout << "No key with nickname " << keyName << " found to delete." + << std::endl; + } + + return true; +} diff --git a/security/nss/nss-tool/db/dbtool.h b/security/nss/nss-tool/db/dbtool.h new file mode 100644 index 000000000..dd0ef0ace --- /dev/null +++ b/security/nss/nss-tool/db/dbtool.h @@ -0,0 +1,28 @@ +/* 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 dbtool_h__ +#define dbtool_h__ + +#include <string> +#include <vector> +#include "argparse.h" +#include "tool.h" + +class DBTool : public Tool { + public: + bool Run(const std::vector<std::string>& arguments) override; + + private: + void Usage() override; + bool PathHasDBFiles(std::string path); + void ListCertificates(); + bool ImportCertificate(const ArgParser& parser); + bool ListKeys(); + bool ImportKey(const ArgParser& parser); + bool DeleteCert(const ArgParser& parser); + bool DeleteKey(const ArgParser& parser); +}; + +#endif // dbtool_h__ diff --git a/security/nss/nss-tool/digest/digesttool.cc b/security/nss/nss-tool/digest/digesttool.cc new file mode 100644 index 000000000..08c3e3ba7 --- /dev/null +++ b/security/nss/nss-tool/digest/digesttool.cc @@ -0,0 +1,161 @@ +/* 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 "digesttool.h" +#include "argparse.h" +#include "scoped_ptrs.h" +#include "util.h" + +#include <algorithm> +#include <fstream> +#include <iomanip> +#include <iostream> + +#include <hasht.h> // contains supported digest types +#include <nss.h> +#include <pk11pub.h> +#include <prio.h> + +static SECOidData* HashTypeToOID(HASH_HashType hashtype) { + SECOidTag hashtag; + + if (hashtype <= HASH_AlgNULL || hashtype >= HASH_AlgTOTAL) { + return nullptr; + } + + switch (hashtype) { + case HASH_AlgMD5: + hashtag = SEC_OID_MD5; + break; + case HASH_AlgSHA1: + hashtag = SEC_OID_SHA1; + break; + case HASH_AlgSHA224: + hashtag = SEC_OID_SHA224; + break; + case HASH_AlgSHA256: + hashtag = SEC_OID_SHA256; + break; + case HASH_AlgSHA384: + hashtag = SEC_OID_SHA384; + break; + case HASH_AlgSHA512: + hashtag = SEC_OID_SHA512; + break; + default: + return nullptr; + } + + return SECOID_FindOIDByTag(hashtag); +} + +static SECOidData* HashNameToOID(const std::string& hashName) { + for (size_t htype = HASH_AlgNULL + 1; htype < HASH_AlgTOTAL; htype++) { + SECOidData* hashOID = HashTypeToOID(static_cast<HASH_HashType>(htype)); + if (hashOID && std::string(hashOID->desc) == hashName) { + return hashOID; + } + } + + return nullptr; +} + +static bool Digest(const ArgParser& parser, SECOidData* hashOID); +static bool ComputeDigest(std::istream& is, ScopedPK11Context& hashCtx); + +bool DigestTool::Run(const std::vector<std::string>& arguments) { + ArgParser parser(arguments); + + if (parser.GetPositionalArgumentCount() != 1) { + Usage(); + return false; + } + + // no need for a db for the digest tool + SECStatus rv = NSS_NoDB_Init("."); + if (rv != SECSuccess) { + std::cerr << "NSS init failed!" << std::endl; + return false; + } + + std::string hashName = parser.GetPositionalArgument(0); + std::transform(hashName.begin(), hashName.end(), hashName.begin(), ::toupper); + SECOidData* hashOID = HashNameToOID(hashName); + if (hashOID == nullptr) { + std::cerr << "Error: Unknown digest type " + << parser.GetPositionalArgument(0) << "." << std::endl; + return false; + } + + bool ret = Digest(parser, hashOID); + + // shutdown nss + if (NSS_Shutdown() != SECSuccess) { + std::cerr << "NSS Shutdown failed!" << std::endl; + return false; + } + + return ret; +} + +void DigestTool::Usage() { + std::cerr << "Usage: nss digest md5|sha-1|sha-224|sha-256|sha-384|sha-512 " + "[--infile <path>]" + << std::endl; +} + +static bool Digest(const ArgParser& parser, SECOidData* hashOID) { + std::string inputFile; + if (parser.Has("--infile")) { + inputFile = parser.Get("--infile"); + } + + ScopedPK11Context hashCtx(PK11_CreateDigestContext(hashOID->offset)); + if (hashCtx == nullptr) { + std::cerr << "Creating digest context failed." << std::endl; + return false; + } + PK11_DigestBegin(hashCtx.get()); + + std::ifstream fis; + std::istream& is = GetStreamFromFileOrStdin(inputFile, fis); + if (!is.good() || !ComputeDigest(is, hashCtx)) { + return false; + } + + unsigned char digest[HASH_LENGTH_MAX]; + unsigned int len; + SECStatus rv = PK11_DigestFinal(hashCtx.get(), digest, &len, HASH_LENGTH_MAX); + if (rv != SECSuccess || len == 0) { + std::cerr << "Calculating final hash value failed." << std::endl; + return false; + } + + // human readable output + for (size_t i = 0; i < len; i++) { + std::cout << std::setw(2) << std::setfill('0') << std::hex + << static_cast<int>(digest[i]); + } + std::cout << std::endl; + + return true; +} + +static bool ComputeDigest(std::istream& is, ScopedPK11Context& hashCtx) { + while (is) { + unsigned char buf[4096]; + is.read(reinterpret_cast<char*>(buf), sizeof(buf)); + if (is.fail() && !is.eof()) { + std::cerr << "Error reading from input stream." << std::endl; + return false; + } + SECStatus rv = PK11_DigestOp(hashCtx.get(), buf, is.gcount()); + if (rv != SECSuccess) { + std::cerr << "PK11_DigestOp failed." << std::endl; + return false; + } + } + + return true; +} diff --git a/security/nss/nss-tool/digest/digesttool.h b/security/nss/nss-tool/digest/digesttool.h new file mode 100644 index 000000000..0e18346f5 --- /dev/null +++ b/security/nss/nss-tool/digest/digesttool.h @@ -0,0 +1,20 @@ +/* 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 digest_tool_h__ +#define digest_tool_h__ + +#include <string> +#include <vector> +#include "tool.h" + +class DigestTool : public Tool { + public: + bool Run(const std::vector<std::string>& arguments) override; + + private: + void Usage() override; +}; + +#endif // digest_tool_h__ diff --git a/security/nss/nss-tool/enc/enctool.cc b/security/nss/nss-tool/enc/enctool.cc new file mode 100644 index 000000000..b3c0d1dbe --- /dev/null +++ b/security/nss/nss-tool/enc/enctool.cc @@ -0,0 +1,464 @@ +/* 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 "enctool.h" +#include "argparse.h" +#include "util.h" + +#include "nss.h" + +#include <assert.h> +#include <chrono> +#include <fstream> +#include <iomanip> +#include <iostream> + +void EncTool::PrintError(const std::string& m, size_t line_number) { + std::cerr << m << " - enctool.cc:" << line_number << std::endl; +} + +void EncTool::PrintError(const std::string& m, PRErrorCode err, + size_t line_number) { + std::cerr << m << " (error " << err << ")" + << " - enctool.cc:" << line_number << std::endl; +} + +void EncTool::PrintBytes(const std::vector<uint8_t>& bytes, + const std::string& txt) { + if (debug_) { + std::cerr << txt << ": "; + for (uint8_t b : bytes) { + std::cerr << std::setfill('0') << std::setw(2) << std::hex + << static_cast<int>(b); + } + std::cerr << std::endl << std::dec; + } +} + +std::vector<uint8_t> EncTool::GenerateRandomness(size_t num_bytes) { + std::vector<uint8_t> bytes(num_bytes); + if (PK11_GenerateRandom(bytes.data(), num_bytes) != SECSuccess) { + PrintError("No randomness available. Abort!", __LINE__); + exit(1); + } + return bytes; +} + +bool EncTool::WriteBytes(const std::vector<uint8_t>& bytes, + std::string out_file) { + std::fstream output(out_file, std::ios::out | std::ios::binary); + if (!output.good()) { + return false; + } + output.write(reinterpret_cast<const char*>( + const_cast<const unsigned char*>(bytes.data())), + bytes.size()); + output.flush(); + output.close(); + return true; +} + +bool EncTool::GetKey(const std::vector<uint8_t>& key_bytes, + ScopedSECItem& key_item) { + if (key_bytes.empty()) { + return false; + } + + // Build key. + key_item = + ScopedSECItem(SECITEM_AllocItem(nullptr, nullptr, key_bytes.size())); + if (!key_item) { + return false; + } + key_item->type = siBuffer; + memcpy(key_item->data, key_bytes.data(), key_bytes.size()); + key_item->len = key_bytes.size(); + + return true; +} + +bool EncTool::GetAesGcmKey(const std::vector<uint8_t>& aad, + const std::vector<uint8_t>& iv_bytes, + const std::vector<uint8_t>& key_bytes, + ScopedSECItem& aes_key, ScopedSECItem& params) { + if (iv_bytes.empty()) { + return false; + } + + // GCM params. + CK_GCM_PARAMS* gcm_params = + static_cast<CK_GCM_PARAMS*>(PORT_Malloc(sizeof(struct CK_GCM_PARAMS))); + if (!gcm_params) { + return false; + } + + uint8_t* iv = static_cast<uint8_t*>(PORT_Malloc(iv_bytes.size())); + if (!iv) { + return false; + } + memcpy(iv, iv_bytes.data(), iv_bytes.size()); + gcm_params->pIv = iv; + gcm_params->ulIvLen = iv_bytes.size(); + gcm_params->ulTagBits = 128; + if (aad.empty()) { + gcm_params->pAAD = nullptr; + gcm_params->ulAADLen = 0; + } else { + uint8_t* ad = static_cast<uint8_t*>(PORT_Malloc(aad.size())); + if (!ad) { + return false; + } + memcpy(ad, aad.data(), aad.size()); + gcm_params->pAAD = ad; + gcm_params->ulAADLen = aad.size(); + } + + params = + ScopedSECItem(SECITEM_AllocItem(nullptr, nullptr, sizeof(*gcm_params))); + if (!params) { + return false; + } + params->len = sizeof(*gcm_params); + params->type = siBuffer; + params->data = reinterpret_cast<unsigned char*>(gcm_params); + + return GetKey(key_bytes, aes_key); +} + +bool EncTool::GenerateAesGcmKey(const std::vector<uint8_t>& aad, + ScopedSECItem& aes_key, ScopedSECItem& params) { + size_t key_size = 16, iv_size = 12; + std::vector<uint8_t> iv_bytes = GenerateRandomness(iv_size); + PrintBytes(iv_bytes, "IV"); + std::vector<uint8_t> key_bytes = GenerateRandomness(key_size); + PrintBytes(key_bytes, "key"); + // Maybe write out the key and parameters. + if (write_key_ && !WriteBytes(key_bytes, key_file_)) { + return false; + } + if (write_iv_ && !WriteBytes(iv_bytes, iv_file_)) { + return false; + } + return GetAesGcmKey(aad, iv_bytes, key_bytes, aes_key, params); +} + +bool EncTool::ReadAesGcmKey(const std::vector<uint8_t>& aad, + ScopedSECItem& aes_key, ScopedSECItem& params) { + std::vector<uint8_t> iv_bytes = ReadInputData(iv_file_); + PrintBytes(iv_bytes, "IV"); + std::vector<uint8_t> key_bytes = ReadInputData(key_file_); + PrintBytes(key_bytes, "key"); + return GetAesGcmKey(aad, iv_bytes, key_bytes, aes_key, params); +} + +bool EncTool::GetChachaKey(const std::vector<uint8_t>& aad, + const std::vector<uint8_t>& iv_bytes, + const std::vector<uint8_t>& key_bytes, + ScopedSECItem& chacha_key, ScopedSECItem& params) { + if (iv_bytes.empty()) { + return false; + } + + // AEAD params. + CK_NSS_AEAD_PARAMS* aead_params = static_cast<CK_NSS_AEAD_PARAMS*>( + PORT_Malloc(sizeof(struct CK_NSS_AEAD_PARAMS))); + if (!aead_params) { + return false; + } + + uint8_t* iv = static_cast<uint8_t*>(PORT_Malloc(iv_bytes.size())); + if (!iv) { + return false; + } + memcpy(iv, iv_bytes.data(), iv_bytes.size()); + aead_params->pNonce = iv; + aead_params->ulNonceLen = iv_bytes.size(); + aead_params->ulTagLen = 16; + if (aad.empty()) { + aead_params->pAAD = nullptr; + aead_params->ulAADLen = 0; + } else { + uint8_t* ad = static_cast<uint8_t*>(PORT_Malloc(aad.size())); + if (!ad) { + return false; + } + memcpy(ad, aad.data(), aad.size()); + aead_params->pAAD = ad; + aead_params->ulAADLen = aad.size(); + } + + params = + ScopedSECItem(SECITEM_AllocItem(nullptr, nullptr, sizeof(*aead_params))); + if (!params) { + return false; + } + params->len = sizeof(*aead_params); + params->type = siBuffer; + params->data = reinterpret_cast<unsigned char*>(aead_params); + + return GetKey(key_bytes, chacha_key); +} + +bool EncTool::GenerateChachaKey(const std::vector<uint8_t>& aad, + ScopedSECItem& chacha_key, + ScopedSECItem& params) { + size_t key_size = 32, iv_size = 12; + std::vector<uint8_t> iv_bytes = GenerateRandomness(iv_size); + PrintBytes(iv_bytes, "IV"); + std::vector<uint8_t> key_bytes = GenerateRandomness(key_size); + PrintBytes(key_bytes, "key"); + // Maybe write out the key and parameters. + if (write_key_ && !WriteBytes(key_bytes, key_file_)) { + return false; + } + if (write_iv_ && !WriteBytes(iv_bytes, iv_file_)) { + return false; + } + return GetChachaKey(aad, iv_bytes, key_bytes, chacha_key, params); +} + +bool EncTool::ReadChachaKey(const std::vector<uint8_t>& aad, + ScopedSECItem& chacha_key, ScopedSECItem& params) { + std::vector<uint8_t> iv_bytes = ReadInputData(iv_file_); + PrintBytes(iv_bytes, "IV"); + std::vector<uint8_t> key_bytes = ReadInputData(key_file_); + PrintBytes(key_bytes, "key"); + return GetChachaKey(aad, iv_bytes, key_bytes, chacha_key, params); +} + +bool EncTool::DoCipher(std::string file_name, std::string out_file, + bool encrypt, key_func_t get_params) { + SECStatus rv; + unsigned int outLen = 0, chunkSize = 1024; + char buffer[1040]; + const unsigned char* bufferStart = + reinterpret_cast<const unsigned char*>(buffer); + + ScopedPK11SlotInfo slot(PK11_GetInternalSlot()); + if (!slot) { + PrintError("Unable to find security device", PR_GetError(), __LINE__); + return false; + } + + ScopedSECItem key, params; + if (!(this->*get_params)(std::vector<uint8_t>(), key, params)) { + PrintError("Geting keys and params failed.", __LINE__); + return false; + } + + ScopedPK11SymKey symKey( + PK11_ImportSymKey(slot.get(), cipher_mech_, PK11_OriginUnwrap, + CKA_DECRYPT | CKA_ENCRYPT, key.get(), nullptr)); + if (!symKey) { + PrintError("Failure to import key into NSS", PR_GetError(), __LINE__); + return false; + } + + std::streambuf* buf; + std::ofstream output_file(out_file, std::ios::out | std::ios::binary); + if (!out_file.empty()) { + if (!output_file.good()) { + return false; + } + buf = output_file.rdbuf(); + } else { + buf = std::cout.rdbuf(); + } + std::ostream output(buf); + + // Read from stdin. + 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()); + } else { + rv = PK11_Decrypt(symKey.get(), cipher_mech_, params.get(), out.data(), + &outLen, data.size() + 16, data.data(), data.size()); + } + if (rv != SECSuccess) { + PrintError(encrypt ? "Error encrypting" : "Error decrypting", + PR_GetError(), __LINE__); + return false; + }; + output.write(reinterpret_cast<char*>(out.data()), outLen); + output.flush(); + if (output_file.good()) { + output_file.close(); + } else { + output << std::endl; + } + + std::cerr << "Done " << (encrypt ? "encrypting" : "decrypting") + << std::endl; + return true; + } + + // Read file from file_name. + std::ifstream input(file_name, std::ios::binary); + if (!input.good()) { + return false; + } + uint8_t out[1040]; + while (input) { + if (encrypt) { + input.read(buffer, chunkSize); + rv = PK11_Encrypt(symKey.get(), cipher_mech_, params.get(), out, &outLen, + chunkSize + 16, bufferStart, input.gcount()); + } else { + // We have to read the tag when decrypting. + input.read(buffer, chunkSize + 16); + rv = PK11_Decrypt(symKey.get(), cipher_mech_, params.get(), out, &outLen, + chunkSize + 16, bufferStart, input.gcount()); + } + if (rv != SECSuccess) { + PrintError(encrypt ? "Error encrypting" : "Error decrypting", + PR_GetError(), __LINE__); + return false; + }; + output.write(reinterpret_cast<const char*>(out), outLen); + output.flush(); + } + if (output_file.good()) { + output_file.close(); + } else { + output << std::endl; + } + std::cerr << "Done " << (encrypt ? "encrypting" : "decrypting") << std::endl; + + return true; +} + +size_t EncTool::PrintFileSize(std::string file_name) { + std::ifstream input(file_name, std::ifstream::ate | std::ifstream::binary); + auto size = input.tellg(); + std::cerr << "Size of file to encrypt: " << size / 1024 / 1024 << " MB" + << std::endl; + return size; +} + +bool EncTool::IsValidCommand(ArgParser arguments) { + // Either encrypt or decrypt is fine. + bool valid = arguments.Has("--encrypt") != arguments.Has("--decrypt"); + // An input file is required for decryption only. + valid &= arguments.Has("--in") || arguments.Has("--encrypt"); + // An output file is required for encryption only. + valid &= arguments.Has("--out") || arguments.Has("--decrypt"); + // Files holding the IV and key are required for decryption. + valid &= arguments.Has("--iv") || arguments.Has("--encrypt"); + valid &= arguments.Has("--key") || arguments.Has("--encrypt"); + // Cipher is always required. + valid &= arguments.Has("--cipher"); + return valid; +} + +bool EncTool::Run(const std::vector<std::string>& arguments) { + ArgParser parser(arguments); + + if (!IsValidCommand(parser)) { + Usage(); + return false; + } + + if (NSS_NoDB_Init(nullptr) != SECSuccess) { + PrintError("NSS initialization failed", PR_GetError(), __LINE__); + return false; + } + + if (parser.Has("--debug")) { + debug_ = 1; + } + if (parser.Has("--iv")) { + iv_file_ = parser.Get("--iv"); + } else { + write_iv_ = false; + } + if (parser.Has("--key")) { + key_file_ = parser.Get("--key"); + } else { + write_key_ = false; + } + + key_func_t get_params; + bool encrypt = parser.Has("--encrypt"); + if (parser.Get("--cipher") == kAESCommand) { + cipher_mech_ = CKM_AES_GCM; + if (encrypt) { + get_params = &EncTool::GenerateAesGcmKey; + } else { + get_params = &EncTool::ReadAesGcmKey; + } + } else if (parser.Get("--cipher") == kChaChaCommand) { + cipher_mech_ = CKM_NSS_CHACHA20_POLY1305; + if (encrypt) { + get_params = &EncTool::GenerateChachaKey; + } else { + get_params = &EncTool::ReadChachaKey; + } + } else { + Usage(); + return false; + } + // Don't write out key and iv when decrypting. + if (!encrypt) { + write_key_ = false; + write_iv_ = false; + } + + std::string input_file = parser.Has("--in") ? parser.Get("--in") : ""; + std::string output_file = parser.Has("--out") ? parser.Get("--out") : ""; + size_t file_size = 0; + if (!input_file.empty()) { + file_size = PrintFileSize(input_file); + } + auto begin = std::chrono::high_resolution_clock::now(); + if (!DoCipher(input_file, output_file, encrypt, get_params)) { + (void)NSS_Shutdown(); + return false; + } + auto end = std::chrono::high_resolution_clock::now(); + auto ns = + std::chrono::duration_cast<std::chrono::nanoseconds>(end - begin).count(); + auto seconds = ns / 1000000000; + std::cerr << ns << " ns (~" << seconds << " s) and " << std::endl; + std::cerr << "That's approximately " << (double)file_size / ns << " b/ns" + << std::endl; + + if (NSS_Shutdown() != SECSuccess) { + return false; + } + + return true; +} + +void EncTool::Usage() { + std::string const txt = R"~( +Usage: nss encrypt|decrypt --cipher aes|chacha [--in <file>] [--out <file>] + [--key <file>] [--iv <file>] + + --cipher Set the cipher to use. + --cipher aes: Use AES-GCM to encrypt/decrypt. + --cipher chacha: Use ChaCha20/Poly1305 to encrypt/decrypt. + --in The file to encrypt/decrypt. If no file is given, we read + from stdin (only when encrypting). + --out The file to write the ciphertext/plaintext to. If no file + is given we write the plaintext to stdout (only when + decrypting). + --key The file to write the used key to/to read the key + from. Optional parameter. When not given, don't write out + the key. + --iv The file to write the used IV to/to read the IV + from. Optional parameter. When not given, don't write out + the IV. + + Examples: + nss encrypt --cipher aes --iv iv --key key --out ciphertext + nss decrypt --cipher chacha --iv iv --key key --in ciphertex + + Note: This tool overrides files without asking. +)~"; + std::cerr << txt << std::endl; +} diff --git a/security/nss/nss-tool/enc/enctool.h b/security/nss/nss-tool/enc/enctool.h new file mode 100644 index 000000000..5a6a5a164 --- /dev/null +++ b/security/nss/nss-tool/enc/enctool.h @@ -0,0 +1,62 @@ +/* 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 enctool_h__ +#define enctool_h__ + +#include <string> +#include <vector> +#include "argparse.h" +#include "prerror.h" +#include "scoped_ptrs.h" +#include "tool.h" + +class EncTool : public Tool { + public: + bool Run(const std::vector<std::string>& arguments) override; + void Usage() override; + + private: + typedef bool (EncTool::*key_func_t)(const std::vector<uint8_t>& aad, + ScopedSECItem& chacha_key, + ScopedSECItem& params); + void PrintBytes(const std::vector<uint8_t>& bytes, const std::string& txt); + bool WriteBytes(const std::vector<uint8_t>& bytes, std::string out_file); + void PrintError(const std::string& m, PRErrorCode err, size_t line_number); + void PrintError(const std::string& m, size_t line_number); + bool GetKey(const std::vector<uint8_t>& key_bytes, ScopedSECItem& key_item); + bool GetAesGcmKey(const std::vector<uint8_t>& aad, + const std::vector<uint8_t>& iv_bytes, + const std::vector<uint8_t>& key_bytes, + ScopedSECItem& aes_key, ScopedSECItem& params); + bool GetChachaKey(const std::vector<uint8_t>& aad, + const std::vector<uint8_t>& iv_bytes, + const std::vector<uint8_t>& key_bytes, + ScopedSECItem& chacha_key, ScopedSECItem& params); + bool GenerateAesGcmKey(const std::vector<uint8_t>& aad, + ScopedSECItem& aes_key, ScopedSECItem& params); + bool ReadAesGcmKey(const std::vector<uint8_t>& aad, ScopedSECItem& aes_key, + ScopedSECItem& params); + std::vector<uint8_t> GenerateRandomness(size_t num_bytes); + bool GenerateChachaKey(const std::vector<uint8_t>& aad, + ScopedSECItem& chacha_key, ScopedSECItem& params); + bool ReadChachaKey(const std::vector<uint8_t>& aad, ScopedSECItem& chacha_key, + ScopedSECItem& params); + bool DoCipher(std::string fileName, std::string outFile, bool encrypt, + key_func_t get_params); + size_t PrintFileSize(std::string fileName); + bool IsValidCommand(ArgParser arguments); + + bool debug_ = false; + bool write_key_ = true; + bool write_iv_ = true; + std::string key_file_ = "/tmp/key"; + std::string iv_file_ = "/tmp/iv"; + CK_MECHANISM_TYPE cipher_mech_; + + const std::string kAESCommand = "aes"; + const std::string kChaChaCommand = "chacha"; +}; + +#endif // enctool_h__ diff --git a/security/nss/nss-tool/hw-support.c b/security/nss/nss-tool/hw-support.c new file mode 100644 index 000000000..0aa097ffc --- /dev/null +++ b/security/nss/nss-tool/hw-support.c @@ -0,0 +1,37 @@ +/* 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 FREEBL_NO_DEPEND +#include "stubs.h" +#endif + +/* This is a freebl command line utility that prints hardware support as freebl + * sees it from its detection in blinit.c + */ + +#include <stdio.h> + +#include "blapi.h" +#include "blapii.h" +#include "nss.h" + +int main(int argc, char const *argv[]) { + BL_Init(); + printf("\n\n ========== NSS Hardware Report ==========\n"); +#if defined(NSS_X86_OR_X64) + printf("\tAES-NI \t%s supported\n", aesni_support() ? "" : "not"); + printf("\tPCLMUL \t%s supported\n", clmul_support() ? "" : "not"); + printf("\tAVX \t%s supported\n", avx_support() ? "" : "not"); + printf("\tSSSE3 \t%s supported\n", ssse3_support() ? "" : "not"); +#elif defined(__aarch64__) || defined(__arm__) + printf("\tNEON \t%s supported\n", arm_neon_support() ? "" : "not"); + printf("\tAES \t%s supported\n", arm_aes_support() ? "" : "not"); + printf("\tPMULL \t%s supported\n", arm_pmull_support() ? "" : "not"); + printf("\tSHA1 \t%s supported\n", arm_sha1_support() ? "" : "not"); + printf("\tSHA2 \t%s supported\n", arm_sha2_support() ? "" : "not"); +#endif + printf(" ========== Hardware Report End ==========\n\n\n"); + BL_Cleanup(); + return 0; +} diff --git a/security/nss/nss-tool/nss_tool.cc b/security/nss/nss-tool/nss_tool.cc new file mode 100644 index 000000000..8864f140d --- /dev/null +++ b/security/nss/nss-tool/nss_tool.cc @@ -0,0 +1,70 @@ +/* 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 <algorithm> +#include <cstring> +#include <iostream> +#include <memory> +#include <string> +#include <vector> + +#include <prinit.h> + +#include "argparse.h" +#include "db/dbtool.h" +#include "digest/digesttool.h" +#include "enc/enctool.h" +#include "tool.h" + +static void Usage() { + std::cerr << "Usage: nss <command> <subcommand> [options]" << std::endl; + std::cerr << " nss db [--path <directory>] <commands>" << std::endl; + std::cerr << " nss encrypt <options>" << std::endl; + std::cerr << " nss decrypt <options>" << std::endl; + std::cerr << " nss digest <options>" << std::endl; +} + +static const std::string kDbCommand = "db"; +static const std::string kEncryptCommand = "encrypt"; +static const std::string kDecryptCommand = "decrypt"; +static const std::string kDigestCommand = "digest"; + +int main(int argc, char **argv) { + if (argc < 2) { + Usage(); + return 1; + } + std::vector<std::string> arguments(argv + 2, argv + argc); + + std::unique_ptr<Tool> tool = nullptr; + if (argv[1] == kDbCommand) { + tool = std::unique_ptr<Tool>(new DBTool()); + } + if (argv[1] == kEncryptCommand) { + tool = std::unique_ptr<Tool>(new EncTool()); + arguments.push_back("--encrypt"); + } + if (argv[1] == kDecryptCommand) { + tool = std::unique_ptr<Tool>(new EncTool()); + arguments.push_back("--decrypt"); + } + if (argv[1] == kDigestCommand) { + tool = std::unique_ptr<Tool>(new DigestTool()); + } + if (!tool) { + Usage(); + return 1; + } + + int exit_code = 0; + PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1); + + if (!tool->Run(arguments)) { + exit_code = 1; + } + + PR_Cleanup(); + + return exit_code; +} diff --git a/security/nss/nss-tool/nss_tool.gyp b/security/nss/nss-tool/nss_tool.gyp new file mode 100644 index 000000000..d0741b426 --- /dev/null +++ b/security/nss/nss-tool/nss_tool.gyp @@ -0,0 +1,68 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +{ + 'includes' : [ + '../coreconf/config.gypi', + '../cmd/platlibs.gypi', + ], + 'targets' : [ + { + 'target_name' : 'nss', + 'type' : 'executable', + 'sources' : [ + 'nss_tool.cc', + 'common/argparse.cc', + 'common/util.cc', + 'db/dbtool.cc', + 'enc/enctool.cc', + 'digest/digesttool.cc' + ], + 'include_dirs': [ + 'common', + ], + 'dependencies' : [ + '<(DEPTH)/cpputil/cpputil.gyp:cpputil', + '<(DEPTH)/exports.gyp:dbm_exports', + '<(DEPTH)/exports.gyp:nss_exports', + ], + }, + { + 'target_name': 'hw-support', + 'type': 'executable', + 'sources': [ + 'hw-support.c', + ], + 'conditions': [ + [ 'OS=="win"', { + 'libraries': [ + 'advapi32.lib', + ], + }], + ], + 'dependencies' : [ + '<(DEPTH)/exports.gyp:nss_exports', + '<(DEPTH)/lib/util/util.gyp:nssutil3', + '<(DEPTH)/lib/nss/nss.gyp:nss_static', + '<(DEPTH)/lib/pk11wrap/pk11wrap.gyp:pk11wrap_static', + '<(DEPTH)/lib/cryptohi/cryptohi.gyp:cryptohi', + '<(DEPTH)/lib/certhigh/certhigh.gyp:certhi', + '<(DEPTH)/lib/certdb/certdb.gyp:certdb', + '<(DEPTH)/lib/base/base.gyp:nssb', + '<(DEPTH)/lib/dev/dev.gyp:nssdev', + '<(DEPTH)/lib/pki/pki.gyp:nsspki', + ], + 'include_dirs': [ + '<(DEPTH)/lib/freebl', + '<(DEPTH)/lib/freebl/mpi', + ], + 'defines': [ + 'NSS_USE_STATIC_LIBS' + ], + 'variables': { + 'module': 'nss', + 'use_static_libs': 1 + }, + }, + ], +} diff --git a/security/nss/nss.gyp b/security/nss/nss.gyp index e62d28449..36b0dd974 100644 --- a/security/nss/nss.gyp +++ b/security/nss/nss.gyp @@ -107,6 +107,7 @@ 'cmd/ssltap/ssltap.gyp:ssltap', 'cmd/symkeyutil/symkeyutil.gyp:symkeyutil', 'nss-tool/nss_tool.gyp:nss', + 'nss-tool/nss_tool.gyp:hw-support', ], }], ], @@ -123,7 +124,6 @@ 'cmd/atob/atob.gyp:atob', 'cmd/bltest/bltest.gyp:bltest', 'cmd/btoa/btoa.gyp:btoa', - 'cmd/certcgi/certcgi.gyp:certcgi', 'cmd/chktest/chktest.gyp:chktest', 'cmd/crmftest/crmftest.gyp:crmftest', 'cmd/dbtest/dbtest.gyp:dbtest', @@ -131,7 +131,6 @@ 'cmd/digest/digest.gyp:digest', 'cmd/ecperf/ecperf.gyp:ecperf', 'cmd/fbectest/fbectest.gyp:fbectest', - 'cmd/fipstest/fipstest.gyp:fipstest', 'cmd/httpserv/httpserv.gyp:httpserv', 'cmd/listsuites/listsuites.gyp:listsuites', 'cmd/makepqg/makepqg.gyp:makepqg', @@ -149,6 +148,7 @@ 'cmd/pk1sign/pk1sign.gyp:pk1sign', 'cmd/pp/pp.gyp:pp', 'cmd/rsaperf/rsaperf.gyp:rsaperf', + 'cmd/rsapoptst/rsapoptst.gyp:rsapoptst', 'cmd/sdrtest/sdrtest.gyp:sdrtest', 'cmd/selfserv/selfserv.gyp:selfserv', 'cmd/shlibsign/mangle/mangle.gyp:mangle', @@ -164,10 +164,13 @@ 'cmd/vfychain/vfychain.gyp:vfychain', 'cmd/vfyserv/vfyserv.gyp:vfyserv', 'gtests/certhigh_gtest/certhigh_gtest.gyp:certhigh_gtest', + 'gtests/cryptohi_gtest/cryptohi_gtest.gyp:cryptohi_gtest', 'gtests/der_gtest/der_gtest.gyp:der_gtest', 'gtests/certdb_gtest/certdb_gtest.gyp:certdb_gtest', 'gtests/freebl_gtest/freebl_gtest.gyp:prng_gtest', + 'gtests/freebl_gtest/freebl_gtest.gyp:blake2b_gtest', 'gtests/pk11_gtest/pk11_gtest.gyp:pk11_gtest', + 'gtests/softoken_gtest/softoken_gtest.gyp:softoken_gtest', 'gtests/ssl_gtest/ssl_gtest.gyp:ssl_gtest', 'gtests/util_gtest/util_gtest.gyp:util_gtest', 'gtests/nss_bogo_shim/nss_bogo_shim.gyp:nss_bogo_shim', @@ -189,6 +192,11 @@ 'gtests/freebl_gtest/freebl_gtest.gyp:freebl_gtest', ], }], + [ 'disable_fips==0', { + 'dependencies': [ + 'cmd/fipstest/fipstest.gyp:fipstest', + ], + }], ], }, ], diff --git a/security/nss/readme.md b/security/nss/readme.md index b75bfe7dd..17b99e805 100644 --- a/security/nss/readme.md +++ b/security/nss/readme.md @@ -41,49 +41,8 @@ directory `lib`, and tools in directory `bin`. In order to run the tools, set your system environment to use the libraries of your build from the "lib" directory, e.g., using the `LD_LIBRARY_PATH` or `DYLD_LIBRARY_PATH`. - Usage: build.sh [-hcv] [-j <n>] [--nspr] [--gyp|-g] [--opt|-o] [-m32] - [--test] [--pprof] [--scan-build[=output]] [--ct-verif] - [--asan] [--ubsan] [--msan] [--sancov[=edge|bb|func|...]] - [--disable-tests] [--fuzz[=tls|oss]] [--system-sqlite] - [--no-zdefs] [--with-nspr] [--system-nspr] [--enable-libpkix] - - This script builds NSS with gyp and ninja. - - This build system is still under development. It does not yet support all - the features or platforms that NSS supports. - - NSS build tool options: - - -h display this help and exit - -c clean before build - -v verbose build - -j <n> run at most <n> concurrent jobs - --nspr force a rebuild of NSPR - --gyp|-g force a rerun of gyp - --opt|-o do an opt build - -m32 do a 32-bit build on a 64-bit system - --test ignore map files and export everything we have - --fuzz build fuzzing targets (this always enables test builds) - --fuzz=tls to enable TLS fuzzing mode - --fuzz=oss to build for OSS-Fuzz - --pprof build with gperftool support - --ct-verif build with valgrind for ct-verif - --scan-build run the build with scan-build (scan-build has to be in the path) - --scan-build=/out/path sets the output path for scan-build - --asan do an asan build - --ubsan do an ubsan build - --ubsan=bool,shift,... sets specific UB sanitizers - --msan do an msan build - --sancov do sanitize coverage builds - --sancov=func sets coverage to function level for example - --disable-tests don't build tests and corresponding cmdline utils - --system-sqlite use system sqlite - --no-zdefs don't set -Wl,-z,defs - --with-nspr don't build NSPR but use the one at the given location, e.g. - --with-nspr=/path/to/nspr/include:/path/to/nspr/lib - --system-nspr use system nspr. This requires an installation of NSPR and - might not work on all systems. - --enable-libpkix make libpkix part of the build. +See [help.txt](https://hg.mozilla.org/projects/nss/raw-file/tip/help.txt) for +more information on using build.sh. ## Building NSS (legacy build system) @@ -122,10 +81,6 @@ set or export: Note that you might have to add `nss.local` to `/etc/hosts` if it's not there. The entry should look something like `127.0.0.1 nss.local nss`. -If you get name resolution errors, try to ensure that you are using an IPv4 -address; IPv6 is the default on many systems for the loopback device which -doesn't work. - ### Running tests **Runnning all tests will take a while!** @@ -182,3 +137,50 @@ The nss directory contains the following important subdirectories: A more comprehensible overview of the NSS folder structure and API guidelines can be found [here](https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/NSS_API_Guidelines). + +## Build mechanisms related to FIPS compliance + +NSS supports build configurations for FIPS-140 compliance, and alternative build +configurations that disable functionality specific to FIPS-140 compliance. + +This section documents the environment variables and build parameters that +control these configurations. + +### Build FIPS startup tests + +The C macro NSS_NO_INIT_SUPPORT controls the FIPS startup self tests. +If NSS_NO_INIT_SUPPORT is defined, the startup tests are disabled. + +The legacy build system (make) by default disables these tests. +To enable these tests, set environment variable NSS_FORCE_FIPS=1 at build time. + +The gyp build system by default disables these tests. +To enable these tests, pass parameter --enable-fips to build.sh. + +### Building either FIPS compliant or alternative compliant code + +The C macro NSS_FIPS_DISABLED can be used to disable some FIPS compliant code +and enable alternative implementations. + +The legacy build system (make) never defines NSS_FIPS_DISABLED and always uses +the FIPS compliant code. + +The gyp build system by default defines NSS_FIPS_DISABLED. +To use the FIPS compliant code, pass parameter --enable-fips to build.sh. + +### Test execution + +The NSS test suite may contain tests that are included, excluded, or are +different based on the FIPS build configuration. To execute the correct tests, +it's necessary to determine which build configuration was used. + +The legacy build system (make) uses environment variables to control all +aspects of the build configuration, including FIPS build configuration. + +Because the gyp build system doesn't use environment variables to control the +build configuration, the NSS tests cannot rely on environment variables to +determine the build configuration. + +A helper binary named nss-build-flags is produced as part of the NSS build, +which prints the C macro symbols that were defined at build time, and which are +relevant to test execution. diff --git a/security/nss/tests/all.sh b/security/nss/tests/all.sh index 833817f4a..3a02debef 100755 --- a/security/nss/tests/all.sh +++ b/security/nss/tests/all.sh @@ -63,10 +63,6 @@ # BUILT_OPT - use optimized/debug build # USE_64 - use 64bit/32bit build # -# Optional environment variables to enable specific NSS features: -# --------------------------------------------------------------- -# NSS_DISABLE_ECC - disable ECC -# # Optional environment variables to select which cycles/suites to test: # --------------------------------------------------------------------- # NSS_CYCLES - list of cycles to run (separated by space @@ -107,12 +103,16 @@ # ######################################################################## +RUN_FIPS="" + ############################## run_tests ############################### # run test suites defined in TESTS variable, skip scripts defined in # TESTS_SKIP variable ######################################################################## run_tests() { + echo "Running test cycle: ${TEST_MODE} ----------------------" + echo "List of tests that will be executed: ${TESTS}" for TEST in ${TESTS} do # NOTE: the spaces are important. If you don't include @@ -132,14 +132,20 @@ run_tests() } ########################## run_cycle_standard ########################## -# run test suites with defaults settings (no PKIX, no sharedb) +# run test suites with dbm database (no PKIX, no sharedb) ######################################################################## run_cycle_standard() { TEST_MODE=STANDARD TESTS="${ALL_TESTS}" - TESTS_SKIP= + TESTS_SKIP="cipher libpkix sdr ocsp pkits" + + NSS_DEFAULT_DB_TYPE="dbm" + export NSS_DEFAULT_DB_TYPE + + NSS_SSL_TESTS=`echo "${NSS_SSL_TESTS}" | sed -e "s/normal//g" -e "s/fips//g" -e "s/_//g"` + NSS_SSL_RUN=`echo "${NSS_SSL_RUN}" | sed -e "s/cov//g" -e "s/auth//g"` run_tests } @@ -164,7 +170,13 @@ run_cycle_pkix() TESTS="${ALL_TESTS}" TESTS_SKIP="cipher dbtests sdr crmf smime merge multinit" + NSS_SSL_TESTS=`echo "${NSS_SSL_TESTS}" | sed -e "s/normal//g" -e "s/fips//g" -e "s/_//g"` + export -n NSS_SSL_RUN + + # use the default format. (unset for the shell, export -n for binaries) + export -n NSS_DEFAULT_DB_TYPE + unset NSS_DEFAULT_DB_TYPE run_tests } @@ -187,7 +199,7 @@ run_cycle_upgrade_db() init_directories if [ -r "${OLDHOSTDIR}/cert.log" ]; then - DIRS="alicedir bobdir CA cert_extensions client clientCA dave eccurves eve ext_client ext_server fips SDR server serverCA stapling tools/copydir cert.log cert.done tests.*" + DIRS="alicedir bobdir CA cert_extensions client clientCA dave eccurves eve ext_client ext_server $RUN_FIPS SDR server serverCA stapling tools/copydir cert.log cert.done tests.*" for i in $DIRS do cp -r ${OLDHOSTDIR}/${i} ${HOSTDIR} #2> /dev/null @@ -233,10 +245,10 @@ run_cycle_shared_db() # run the tests for native sharedb support TESTS="${ALL_TESTS}" - TESTS_SKIP="cipher libpkix dbupgrade sdr ocsp pkits" + TESTS_SKIP="dbupgrade" - NSS_SSL_TESTS=`echo "${NSS_SSL_TESTS}" | sed -e "s/normal//g" -e "s/fips//g" -e "s/_//g"` - NSS_SSL_RUN=`echo "${NSS_SSL_RUN}" | sed -e "s/cov//g" -e "s/auth//g"` + export -n NSS_SSL_TESTS + export -n NSS_SSL_RUN run_tests } @@ -270,10 +282,25 @@ run_cycles() ############################## main code ############################### +SCRIPTNAME=all.sh +CLEANUP="${SCRIPTNAME}" +cd `dirname $0` + +# all.sh should be the first one to try to source the init +if [ -z "${INIT_SOURCED}" -o "${INIT_SOURCED}" != "TRUE" ]; then + cd common + . ./init.sh +fi + cycles="standard pkix upgradedb sharedb" CYCLES=${NSS_CYCLES:-$cycles} -tests="cipher lowhash libpkix cert dbtests tools fips sdr crmf smime ssl ocsp merge pkits ec gtests ssl_gtests" +NO_INIT_SUPPORT=`certutil --build-flags |grep -cw NSS_NO_INIT_SUPPORT` +if [ $NO_INIT_SUPPORT -eq 0 ]; then + RUN_FIPS="fips" +fi + +tests="cipher lowhash libpkix cert dbtests tools $RUN_FIPS sdr crmf smime ssl ocsp merge pkits ec gtests ssl_gtests" # Don't run chains tests when we have a gyp build. if [ "$OBJDIR" != "Debug" -a "$OBJDIR" != "Release" ]; then tests="$tests chains" @@ -282,22 +309,15 @@ TESTS=${NSS_TESTS:-$tests} ALL_TESTS=${TESTS} -nss_ssl_tests="crl fips_normal normal_fips iopr policy" +nss_ssl_tests="crl iopr policy" +if [ $NO_INIT_SUPPORT -eq 0 ]; then + nss_ssl_tests="$nss_ssl_tests fips_normal normal_fips" +fi NSS_SSL_TESTS="${NSS_SSL_TESTS:-$nss_ssl_tests}" nss_ssl_run="cov auth stapling stress" NSS_SSL_RUN="${NSS_SSL_RUN:-$nss_ssl_run}" -SCRIPTNAME=all.sh -CLEANUP="${SCRIPTNAME}" -cd `dirname $0` - -# all.sh should be the first one to try to source the init -if [ -z "${INIT_SOURCED}" -o "${INIT_SOURCED}" != "TRUE" ]; then - cd common - . ./init.sh -fi - # NOTE: # Lists of enabled tests and other settings are stored to ${ENV_BACKUP} # file and are are restored after every test cycle. @@ -305,6 +325,11 @@ fi ENV_BACKUP=${HOSTDIR}/env.sh env_backup > ${ENV_BACKUP} +# Print hardware support if we built it. +if [ -f ${BINDIR}/hw-support ]; then + ${BINDIR}/hw-support +fi + if [ "${O_CRON}" = "ON" ]; then run_cycles >> ${LOGFILE} else diff --git a/security/nss/tests/bogo/bogo.sh b/security/nss/tests/bogo/bogo.sh index 26dfb0abb..d1a93bf9b 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 bbfe603519bc54fbc4c8dd87efe1ed385df550b4 + git -C "$BORING" checkout -q a513e86c1ebb1383930c9e504bdabcc302a85f30 fi SCRIPTNAME="bogo.sh" diff --git a/security/nss/tests/cert/TestCA-bogus-rsa-pss1.crt b/security/nss/tests/cert/TestCA-bogus-rsa-pss1.crt new file mode 100644 index 000000000..e3c8fcdcf --- /dev/null +++ b/security/nss/tests/cert/TestCA-bogus-rsa-pss1.crt @@ -0,0 +1,26 @@ +-----BEGIN CERTIFICATE----- +MIIEbDCCAxqgAwIBAgIBATBHBgkqhkiG9w0BAQowOqAPMA0GCWCGSAFlAwQCAQUA
+oRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAQUAogMCASCjBAICEmcwgYMxCzAJ
+BgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFp
+biBWaWV3MRIwEAYDVQQKEwlCT0dVUyBOU1MxMzAxBgNVBAMTKk5TUyBUZXN0IENB
+IChSU0EtUFNTIGludmFsaWQgdHJhaWxlckZpZWxkKTAgFw0xNzEyMDcxMjU3NDBa
+GA8yMDY3MTIwNzEyNTc0MFowgYMxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxp
+Zm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRIwEAYDVQQKEwlCT0dVUyBO
+U1MxMzAxBgNVBAMTKk5TUyBUZXN0IENBIChSU0EtUFNTIGludmFsaWQgdHJhaWxl
+ckZpZWxkKTCCAVwwRwYJKoZIhvcNAQEKMDqgDzANBglghkgBZQMEAgEFAKEcMBoG
+CSqGSIb3DQEBCDANBglghkgBZQMEAgEFAKIDAgEgowQCAhJnA4IBDwAwggEKAoIB
+AQDgkKJk+PoFpESak7kMQ0w147/xilUZCG7hDGG2uuGTbX8jqy9N9pxzB9sJjgJX
+yYND0XEmrUQ2Memmy8jufhXML5DekW1tr3Gi2L3VivbIReJZfXk1xDMvNbB/Gjjo
+SoPyu8C4hnevjgMlmqG3KdMkB+eN6PnBG64YFyki3vnLO5iTNHEBTgFYo0gTX4uK
+xl0hLtiDL+4K5l7BwVgxZwQF6uHoHjrjjlhkzR0FwjjqR8U0pH20Pb6IlRsFMv07
+/1GHf+jm34pKb/1ZNzAbiKxYv7YAQUWEZ7e/GSXgA6gbTpV9ueiLkVucUeXN/mXK
+Tqb4zivi5FaSGVl8SJnqsJXJAgMBAAGjOTA3MBQGCWCGSAGG+EIBAQEB/wQEAwIC
+BDAPBgNVHRMECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwICBDBHBgkqhkiG9w0BAQow
+OqAPMA0GCWCGSAFlAwQCAQUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAQUA
+ogMCASCjBAICEmcDggEBAJht9t9p/dlhJtx7ShDvUXyq8N4tCoGKdREM83K/jlW8
+HxdHOz5PuvZx+UMlaUtqZVIriSCnRtEWkoSo0hWmcv1rp80it2G1zLfLPYdyrPba
+nQmE1iFb69Wr9dwrX7o/CII+WHQgoIGeFGntZ8YRZTe5+JeiGAlAyZCqUKbl9lhh
+pCpf1YYxb3VI8mAGVi0jwabWBEbInGBZYH9HP0nK7/Tflk6UY3f4h4Fbkk5D4WZA
+hFfkebx6Wh90QGiKQhp4/N+dYira8bKvWqqn0VqwzBoJBU/RmMaJVpwqFFvcaUJh
+uEKUPeQbqkYvj1WJYmy4ettVwi4OZU50+kCaRQhMsFA= +-----END CERTIFICATE----- diff --git a/security/nss/tests/cert/TestCA-bogus-rsa-pss2.crt b/security/nss/tests/cert/TestCA-bogus-rsa-pss2.crt new file mode 100644 index 000000000..d46442dc4 --- /dev/null +++ b/security/nss/tests/cert/TestCA-bogus-rsa-pss2.crt @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIIEFzCCAs2gAwIBAgIBATA/BgkqhkiG9w0BAQowMqAOMAwGCCqGSIb3DQIFBQCh
+GzAZBgkqhkiG9w0BAQgwDAYIKoZIhvcNAgUFAKIDAgEgMH4xCzAJBgNVBAYTAlVT
+MRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRIw
+EAYDVQQKEwlCT0dVUyBOU1MxLjAsBgNVBAMTJU5TUyBUZXN0IENBIChSU0EtUFNT
+IGludmFsaWQgaGFzaEFsZykwIBcNMTcxMjA3MTQwNjQ0WhgPMjA2ODAxMDcxNDA2
+NDRaMH4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQH
+Ew1Nb3VudGFpbiBWaWV3MRIwEAYDVQQKEwlCT0dVUyBOU1MxLjAsBgNVBAMTJU5T
+UyBUZXN0IENBIChSU0EtUFNTIGludmFsaWQgaGFzaEFsZykwggEgMAsGCSqGSIb3
+DQEBCgOCAQ8AMIIBCgKCAQEAtDXA73yTOgs8zVYNMCtuQ9a07UgbfeQbjHp3pkF6
+7rsC/Q28mrLh+zLkht5e7qU/Qf/8a2ZkcYhPOBAjCzjgIXOdE2lsWvdVujOJLR0x
+Fesd3hDLRmL6f6momc+j1/Tw3bKyZinaeJ9BFRv9c94SayB3QUe+6+TNJKASwlhj
+sx6mUsND+h3DkuL77gi7hIUpUXfFSwa+zM69VLhIu+/WRZfG8gfKkCAIGUC3WYJa
+eU1HgQKfVSXW0ok4ototXWEe9ohU+Z1tO9LJStcY8mMpig7EU9zbpObhG46Sykfu
+aKsubB9J+gFgwP5Tb85tRYT6SbHeHR6U/N8GBrKdRcomWwIDAQABozwwOjAUBglg
+hkgBhvhCAQEBAf8EBAMCAgQwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8E
+BAMCAgQwPwYJKoZIhvcNAQEKMDKgDjAMBggqhkiG9w0CBQUAoRswGQYJKoZIhvcN
+AQEIMAwGCCqGSIb3DQIFBQCiAwIBIAOCAQEAjeemeTxh2xrMUJ6Z5Yn2nH2FbcPY
+fTHJcdfXjfNBkrMl5pe2/lk0JyNuACTuTYFCxdWNRL1coN//h9DSUbF3dpF1ex6D
+difo+6PwxkO2aPVGPYw4DSivt4SFbn5dKGgVqBQfnmNK7p/iT91AcErg/grRrNL+
+4jeT0UiRjQYeX9xKJArv+ocIidNpQL3QYxXuBLZxVC92Af69ol7WG8QBRLnFi1p2
+g6q8hOHqOfB29qnsSo3PkI1yuShOl50tRLbNgyotEfZdk1N3oXvapoBsm/jlcdCT
+0aKelCSQYYAfyl5PKCpa1lgBm7zfcHSDStMhEEFu/fbnJhqO9g9znj3STQ== +-----END CERTIFICATE----- diff --git a/security/nss/tests/cert/cert.sh b/security/nss/tests/cert/cert.sh index 9b3455747..d1a9148a9 100755 --- a/security/nss/tests/cert/cert.sh +++ b/security/nss/tests/cert/cert.sh @@ -46,11 +46,7 @@ cert_init() fi SCRIPTNAME="cert.sh" CRL_GRP_DATE=`date -u "+%Y%m%d%H%M%SZ"` - if [ -z "$NSS_DISABLE_ECC" ] ; then - html_head "Certutil and Crlutil Tests with ECC" - else - html_head "Certutil and Crlutil Tests" - fi + html_head "Certutil and Crlutil Tests" LIBDIR="${DIST}/${OBJDIR}/lib" @@ -300,14 +296,12 @@ cert_create_cert() fi - if [ -z "$NSS_DISABLE_ECC" ] ; then CU_ACTION="Import EC Root CA for $CERTNAME" certu -A -n "TestCA-ec" -t "TC,TC,TC" -f "${R_PWFILE}" \ -d "${PROFILEDIR}" -i "${R_CADIR}/TestCA-ec.ca.cert" 2>&1 if [ "$RET" -ne 0 ]; then return $RET fi - fi cert_add_cert "$5" return $? @@ -402,7 +396,6 @@ cert_add_cert() # # Generate and add EC cert # - if [ -z "$NSS_DISABLE_ECC" ] ; then CURVE="secp384r1" CU_ACTION="Generate EC Cert Request for $CERTNAME" CU_SUBJECT="CN=$CERTNAME, E=${CERTNAME}-ec@bogus.com, O=BOGUS NSS, L=Mountain View, ST=California, C=US" @@ -454,7 +447,6 @@ cert_add_cert() return $RET fi cert_log "SUCCESS: $CERTNAME's mixed EC Cert Created" - fi return 0 } @@ -467,6 +459,7 @@ cert_add_cert() cert_all_CA() { echo nss > ${PWFILE} + echo > ${EMPTY_FILE} ALL_CU_SUBJECT="CN=NSS Test CA, O=BOGUS NSS, L=Mountain View, ST=California, C=US" cert_CA $CADIR TestCA -x "CTu,CTu,CTu" ${D_CA} "1" @@ -517,10 +510,16 @@ cert_all_CA() # dsaroot.cert in $CLIENT_CADIR and in $SERVER_CADIR is one of the last # in the chain +# +# Create RSA-PSS version of TestCA + ALL_CU_SUBJECT="CN=NSS Test CA (RSA-PSS), O=BOGUS NSS, L=Mountain View, ST=California, C=US" + cert_rsa_pss_CA $CADIR TestCA-rsa-pss -x "CTu,CTu,CTu" ${D_CA} "1" SHA256 + rm $CADIR/rsapssroot.cert + ALL_CU_SUBJECT="CN=NSS Test CA (RSA-PSS-SHA1), O=BOGUS NSS, L=Mountain View, ST=California, C=US" + cert_rsa_pss_CA $CADIR TestCA-rsa-pss-sha1 -x "CTu,CTu,CTu" ${D_CA} "1" SHA1 + rm $CADIR/rsapssroot.cert - - if [ -z "$NSS_DISABLE_ECC" ] ; then # # Create EC version of TestCA CA_CURVE="secp521r1" @@ -545,8 +544,6 @@ cert_all_CA() rm $CLIENT_CADIR/ecroot.cert $SERVER_CADIR/ecroot.cert # ecroot.cert in $CLIENT_CADIR and in $SERVER_CADIR is one of the last # in the chain - - fi } ################################# cert_CA ################################ @@ -637,7 +634,7 @@ CERTSCRIPT ################################ cert_dsa_CA ############################# # local shell function to build the Temp. Certificate Authority (CA) # used for testing purposes, creating a CA Certificate and a root cert -# This is the ECC version of cert_CA. +# This is the DSA version of cert_CA. ########################################################################## cert_dsa_CA() { @@ -648,7 +645,7 @@ cert_dsa_CA() DOMAIN=$5 CERTSERIAL=$6 - echo "$SCRIPTNAME: Creating an DSA CA Certificate $NICKNAME ==========================" + echo "$SCRIPTNAME: Creating a DSA CA Certificate $NICKNAME ==========================" if [ ! -d "${CUR_CADIR}" ]; then mkdir -p "${CUR_CADIR}" @@ -661,7 +658,7 @@ cert_dsa_CA() LPROFILE="multiaccess:${DOMAIN}" fi - ################# Creating an DSA CA Cert ############################### + ################# Creating a DSA CA Cert ############################### # CU_ACTION="Creating DSA CA Cert $NICKNAME " CU_SUBJECT=$ALL_CU_SUBJECT @@ -700,6 +697,79 @@ CERTSCRIPT + +################################ cert_rsa_pss_CA ############################# +# local shell function to build the Temp. Certificate Authority (CA) +# used for testing purposes, creating a CA Certificate and a root cert +# This is the RSA-PSS version of cert_CA. +########################################################################## +cert_rsa_pss_CA() +{ + CUR_CADIR=$1 + NICKNAME=$2 + SIGNER=$3 + TRUSTARG=$4 + DOMAIN=$5 + CERTSERIAL=$6 + HASHALG=$7 + + echo "$SCRIPTNAME: Creating an RSA-PSS CA Certificate $NICKNAME ==========================" + + if [ ! -d "${CUR_CADIR}" ]; then + mkdir -p "${CUR_CADIR}" + fi + cd ${CUR_CADIR} + pwd + + LPROFILE=. + if [ -n "${MULTIACCESS_DBM}" ]; then + LPROFILE="multiaccess:${DOMAIN}" + fi + + HASHOPT= + if [ -n "$HASHALG" ]; then + HASHOPT="-Z $HASHALG" + fi + + ################# Creating an RSA-PSS CA Cert ############################### + # + CU_ACTION="Creating RSA-PSS CA Cert $NICKNAME " + CU_SUBJECT=$ALL_CU_SUBJECT + certu -S -n $NICKNAME -k rsa --pss $HASHOPT -t $TRUSTARG -v 600 $SIGNER \ + -d ${LPROFILE} -1 -2 -5 -f ${R_PWFILE} -z ${R_NOISE_FILE} \ + -m $CERTSERIAL 2>&1 <<CERTSCRIPT +5 +6 +9 +n +y +-1 +n +5 +6 +7 +9 +n +CERTSCRIPT + + if [ "$RET" -ne 0 ]; then + echo "return value is $RET" + Exit 6 "Fatal - failed to create RSA-PSS CA cert" + fi + + ################# Exporting RSA-PSS Root Cert ############################### + # + CU_ACTION="Exporting RSA-PSS Root Cert" + certu -L -n $NICKNAME -r -d ${LPROFILE} -o rsapssroot.cert + if [ "$RET" -ne 0 ]; then + Exit 7 "Fatal - failed to export RSA-PSS root cert" + fi + cp rsapssroot.cert ${NICKNAME}.ca.cert +} + + + + ################################ cert_ec_CA ############################## # local shell function to build the Temp. Certificate Authority (CA) # used for testing purposes, creating a CA Certificate and a root cert @@ -831,7 +901,6 @@ cert_smime_client() certu -E -t ",," -d ${P_R_BOBDIR} -f ${R_PWFILE} \ -i ${R_EVEDIR}/Eve.cert 2>&1 - if [ -z "$NSS_DISABLE_ECC" ] ; then echo "$SCRIPTNAME: Importing EC Certificates ==============================" CU_ACTION="Import Bob's EC cert into Alice's db" certu -E -t ",," -d ${P_R_ALICEDIR} -f ${R_PWFILE} \ @@ -855,7 +924,6 @@ cert_smime_client() # CU_ACTION="Import Eve's EC cert into Bob's DB" # certu -E -t ",," -d ${P_R_BOBDIR} -f ${R_PWFILE} \ # -i ${R_EVEDIR}/Eve-ec.cert 2>&1 - fi if [ "$CERTFAILED" != 0 ] ; then cert_log "ERROR: SMIME failed $RET" @@ -946,7 +1014,6 @@ cert_extended_ssl() # -d "${PROFILEDIR}" -i "${CLIENT_CADIR}/clientCA-dsamixed.ca.cert" \ # 2>&1 - if [ -z "$NSS_DISABLE_ECC" ] ; then # # Repeat the above for EC certs # @@ -992,7 +1059,6 @@ cert_extended_ssl() # certu -A -n "clientCA-ecmixed" -t "T,," -f "${R_PWFILE}" \ # -d "${PROFILEDIR}" -i "${CLIENT_CADIR}/clientCA-ecmixed.ca.cert" \ # 2>&1 - fi echo "Importing all the server's own CA chain into the servers DB" for CA in `find ${SERVER_CADIR} -name "?*.ca.cert"` ; @@ -1081,7 +1147,6 @@ cert_extended_ssl() # done with mixed DSA certs # - if [ -z "$NSS_DISABLE_ECC" ] ; then # # Repeat the above for EC certs # @@ -1128,7 +1193,6 @@ cert_extended_ssl() # # done with mixed EC certs # - fi echo "Importing all the client's own CA chain into the servers DB" for CA in `find ${CLIENT_CADIR} -name "?*.ca.cert"` ; @@ -1175,10 +1239,8 @@ cert_ssl() CU_ACTION="Modify trust attributes of DSA Root CA -t TC,TC,TC" certu -M -n "TestCA-dsa" -t "TC,TC,TC" -d ${PROFILEDIR} -f "${R_PWFILE}" - if [ -z "$NSS_DISABLE_ECC" ] ; then - CU_ACTION="Modify trust attributes of EC Root CA -t TC,TC,TC" - certu -M -n "TestCA-ec" -t "TC,TC,TC" -d ${PROFILEDIR} -f "${R_PWFILE}" - fi + CU_ACTION="Modify trust attributes of EC Root CA -t TC,TC,TC" + certu -M -n "TestCA-ec" -t "TC,TC,TC" -d ${PROFILEDIR} -f "${R_PWFILE}" # cert_init_cert ${SERVERDIR} "${HOSTADDR}" 1 ${D_SERVER} # echo "************* Copying CA files to ${SERVERDIR}" # cp ${CADIR}/*.db . @@ -1199,6 +1261,12 @@ cert_ssl() cp -r ${R_SERVERDIR} ${R_STAPLINGDIR} pk12u -o ${R_STAPLINGDIR}/ca.p12 -n TestCA -k ${R_PWFILE} -w ${R_PWFILE} -d ${R_CADIR} pk12u -i ${R_STAPLINGDIR}/ca.p12 -k ${R_PWFILE} -w ${R_PWFILE} -d ${R_STAPLINGDIR} + + echo "$SCRIPTNAME: Creating database for strsclnt no login tests ===============" + echo "cp -r ${CLIENTDIR} ${NOLOGINDIR}" + cp -r ${R_CLIENTDIR} ${R_NOLOGINDIR} + # change the password to empty + certu -W -d "${R_NOLOGINDIR}" -f "${R_PWFILE}" -@ "${R_EMPTY_FILE}" 2>&1 } ############################## cert_stresscerts ################################ @@ -1269,12 +1337,35 @@ MODSCRIPT html_passed "${CU_ACTION}" fi + CU_ACTION="Setting invalid database password in FIPS mode" + RETEXPECTED=255 + certu -W -d "${PROFILEDIR}" -f "${R_FIPSPWFILE}" -@ "${R_FIPSBADPWFILE}" 2>&1 + CU_ACTION="Attempt to generate a key with exponent of 3 (too small)" + certu -G -k rsa -g 2048 -y 3 -d "${PROFILEDIR}" -z ${R_NOISE_FILE} -f "${R_FIPSPWFILE}" + CU_ACTION="Attempt to generate a key with exponent of 17 (too small)" + certu -G -k rsa -g 2048 -y 17 -d "${PROFILEDIR}" -z ${R_NOISE_FILE} -f "${R_FIPSPWFILE}" + RETEXPECTED=0 + CU_ACTION="Generate Certificate for ${CERTNAME}" CU_SUBJECT="CN=${CERTNAME}, E=fips@bogus.com, O=BOGUS NSS, OU=FIPS PUB 140, L=Mountain View, ST=California, C=US" certu -S -n ${FIPSCERTNICK} -x -t "Cu,Cu,Cu" -d "${PROFILEDIR}" -f "${R_FIPSPWFILE}" -k dsa -v 600 -m 500 -z "${R_NOISE_FILE}" 2>&1 if [ "$RET" -eq 0 ]; then cert_log "SUCCESS: FIPS passed" fi + +} + +########################## cert_rsa_exponent ################################# +# local shell function to verify small rsa exponent can be used (only +# run if FIPS has not been turned on in the build). +############################################################################## +cert_rsa_exponent_nonfips() +{ + echo "$SCRIPTNAME: Verify that small RSA exponents still work ==============" + CU_ACTION="Attempt to generate a key with exponent of 3" + certu -G -k rsa -g 2048 -y 3 -d "${CLIENTDIR}" -z ${R_NOISE_FILE} -f "${R_PWFILE}" + CU_ACTION="Attempt to generate a key with exponent of 17" + certu -G -k rsa -g 2048 -y 17 -d "${CLIENTDIR}" -z ${R_NOISE_FILE} -f "${R_PWFILE}" } ############################## cert_eccurves ########################### @@ -1284,7 +1375,6 @@ cert_eccurves() { ################# Creating Certs for EC curves test ######################## # - if [ -z "$NSS_DISABLE_ECC" ] ; then echo "$SCRIPTNAME: Creating Server CA Issued Certificate for " echo " EC Curves Test Certificates ------------------------------------" @@ -1325,8 +1415,6 @@ cert_eccurves() -f "${R_PWFILE}" -i "${CERTNAME}-ec.cert" 2>&1 fi done - - fi # $NSS_DISABLE_ECC } ########################### cert_extensions_test ############################# @@ -1678,7 +1766,6 @@ EOF_CRLINI - if [ -z "$NSS_DISABLE_ECC" ] ; then CU_ACTION="Generating CRL (ECC) for range ${CRL_GRP_1_BEGIN}-${CRL_GRP_END} TestCA-ec authority" # Until Bug 292285 is resolved, do not encode x400 Addresses. After @@ -1693,7 +1780,6 @@ addext issuerAltNames 0 "rfc822Name:ca-ecemail@ca.com|dnsName:ca-ec.com|director EOF_CRLINI CRL_GEN_RES=`expr $? + $CRL_GEN_RES` chmod 600 ${CRL_FILE_GRP_1}_or-ec - fi echo test > file ############################# Modification ################################## @@ -1724,7 +1810,6 @@ EOF_CRLINI TEMPFILES="$TEMPFILES ${CRL_FILE_GRP_1}_or-dsa" - if [ -z "$NSS_DISABLE_ECC" ] ; then CU_ACTION="Modify CRL (ECC) by adding one more cert" crlu -d $CADIR -M -n "TestCA-ec" -f ${R_PWFILE} \ -o ${CRL_FILE_GRP_1}_or1-ec -i ${CRL_FILE_GRP_1}_or-ec <<EOF_CRLINI @@ -1734,7 +1819,6 @@ EOF_CRLINI CRL_GEN_RES=`expr $? + $CRL_GEN_RES` chmod 600 ${CRL_FILE_GRP_1}_or1-ec TEMPFILES="$TEMPFILES ${CRL_FILE_GRP_1}_or-ec" - fi ########### Removing one cert ${UNREVOKED_CERT_GRP_1} ####################### echo "$SCRIPTNAME: Modifying CA CRL by removing one cert ===============" @@ -1763,7 +1847,6 @@ EOF_CRLINI - if [ -z "$NSS_DISABLE_ECC" ] ; then CU_ACTION="Modify CRL (ECC) by removing one cert" crlu -d $CADIR -M -n "TestCA-ec" -f ${R_PWFILE} -o ${CRL_FILE_GRP_1}-ec \ -i ${CRL_FILE_GRP_1}_or1-ec <<EOF_CRLINI @@ -1772,7 +1855,6 @@ rmcert ${UNREVOKED_CERT_GRP_1} EOF_CRLINI chmod 600 ${CRL_FILE_GRP_1}-ec TEMPFILES="$TEMPFILES ${CRL_FILE_GRP_1}_or1-ec" - fi ########### Creating second CRL which includes groups 1 and 2 ############## CRL_GRP_END=`expr ${CRL_GRP_2_BEGIN} + ${CRL_GRP_2_RANGE} - 1` @@ -1792,7 +1874,6 @@ rmcert ${UNREVOKED_CERT_GRP_2} EOF_CRLINI CRL_GEN_RES=`expr $? + $CRL_GEN_RES` chmod 600 ${CRL_FILE_GRP_2} - if [ -z "$NSS_DISABLE_ECC" ] ; then CU_ACTION="Creating CRL (ECC) for groups 1 and 2" crlu -d $CADIR -M -n "TestCA-ec" -f ${R_PWFILE} -o ${CRL_FILE_GRP_2}-ec \ -i ${CRL_FILE_GRP_1}-ec <<EOF_CRLINI @@ -1803,7 +1884,6 @@ rmcert ${UNREVOKED_CERT_GRP_2} EOF_CRLINI CRL_GEN_RES=`expr $? + $CRL_GEN_RES` chmod 600 ${CRL_FILE_GRP_2}-ec - fi ########### Creating second CRL which includes groups 1, 2 and 3 ############## CRL_GRP_END=`expr ${CRL_GRP_3_BEGIN} + ${CRL_GRP_3_RANGE} - 1` @@ -1825,7 +1905,6 @@ addext crlNumber 0 2 EOF_CRLINI CRL_GEN_RES=`expr $? + $CRL_GEN_RES` chmod 600 ${CRL_FILE_GRP_3} - if [ -z "$NSS_DISABLE_ECC" ] ; then CU_ACTION="Creating CRL (ECC) for groups 1, 2 and 3" crlu -d $CADIR -M -n "TestCA-ec" -f ${R_PWFILE} -o ${CRL_FILE_GRP_3}-ec \ -i ${CRL_FILE_GRP_2}-ec <<EOF_CRLINI @@ -1836,7 +1915,6 @@ addext crlNumber 0 2 EOF_CRLINI CRL_GEN_RES=`expr $? + $CRL_GEN_RES` chmod 600 ${CRL_FILE_GRP_3}-ec - fi ############ Importing Server CA Issued CRL for certs of first group ####### @@ -1845,13 +1923,11 @@ EOF_CRLINI crlu -D -n TestCA -f "${R_PWFILE}" -d "${R_SERVERDIR}" crlu -I -i ${CRL_FILE} -n "TestCA" -f "${R_PWFILE}" -d "${R_SERVERDIR}" CRL_GEN_RES=`expr $? + $CRL_GEN_RES` - if [ -z "$NSS_DISABLE_ECC" ] ; then CU_ACTION="Importing CRL (ECC) for groups 1" crlu -D -n TestCA-ec -f "${R_PWFILE}" -d "${R_SERVERDIR}" crlu -I -i ${CRL_FILE}-ec -n "TestCA-ec" -f "${R_PWFILE}" \ -d "${R_SERVERDIR}" CRL_GEN_RES=`expr $? + $CRL_GEN_RES` - fi if [ "$CERTFAILED" != 0 -o "$CRL_GEN_RES" != 0 ] ; then cert_log "ERROR: SSL CRL prep failed $CERTFAILED : $CRL_GEN_RES" @@ -1968,6 +2044,387 @@ cert_test_ocspresp() ocspr ${SERVER_CADIR} "serverCA" "chain-1-serverCA" -f "${R_PWFILE}" 2>&1 } +cert_test_implicit_db_init() +{ + echo "$SCRIPTNAME: test implicit database init" + + CU_ACTION="Add cert with trust flags to db with implicit init" + mkdir ${IMPLICIT_INIT_DIR} + certu -A -n ca -t 'C,C,C' -d ${P_R_IMPLICIT_INIT_DIR} -i "${SERVER_CADIR}/serverCA.ca.cert" +} + +check_sign_algo() +{ + certu -L -n "$CERTNAME" -d "${PROFILEDIR}" -f "${R_PWFILE}" | \ + sed -n '/^ *Data:/,/^$/{ +/^ Signature Algorithm/,/^ *Salt length/s/^ //p +}' > ${TMP}/signalgo.txt + + diff ${TMP}/signalgo.exp ${TMP}/signalgo.txt + RET=$? + if [ "$RET" -ne 0 ]; then + CERTFAILED=$RET + html_failed "${CU_ACTION} ($RET) " + cert_log "ERROR: ${CU_ACTION} failed $RET" + else + html_passed "${CU_ACTION}" + fi +} + +cert_test_rsapss() +{ + TEMPFILES="$TEMPFILES ${TMP}/signalgo.exp ${TMP}/signalgo.txt" + + cert_init_cert "${RSAPSSDIR}" "RSA-PSS Test Cert" 1000 "${D_RSAPSS}" + + CU_ACTION="Initialize Cert DB" + certu -N -d "${PROFILEDIR}" -f "${R_PWFILE}" 2>&1 + + CU_ACTION="Import RSA CA Cert" + certu -A -n "TestCA" -t "C,," -d "${PROFILEDIR}" -f "${R_PWFILE}" \ + -i "${R_CADIR}/TestCA.ca.cert" 2>&1 + + CU_ACTION="Import RSA-PSS CA Cert" + certu -A -n "TestCA-rsa-pss" -t "C,," -d "${PROFILEDIR}" -f "${R_PWFILE}" \ + -i "${R_CADIR}/TestCA-rsa-pss.ca.cert" 2>&1 + + CU_ACTION="Verify RSA-PSS CA Cert" + certu -V -u L -e -n "TestCA-rsa-pss" -d "${PROFILEDIR}" -f "${R_PWFILE}" + + CU_ACTION="Import RSA-PSS CA Cert (SHA1)" + certu -A -n "TestCA-rsa-pss-sha1" -t "C,," -d "${PROFILEDIR}" -f "${R_PWFILE}" \ + -i "${R_CADIR}/TestCA-rsa-pss-sha1.ca.cert" 2>&1 + + CU_ACTION="Import Bogus RSA-PSS CA Cert (invalid trailerField)" + certu -A -n "TestCA-bogus-rsa-pss1" -t "C,," -d "${PROFILEDIR}" -f "${R_PWFILE}" \ + -i "${QADIR}/cert/TestCA-bogus-rsa-pss1.crt" 2>&1 + RETEXPECTED=255 + certu -V -b 1712101010Z -n TestCA-bogus-rsa-pss1 -u L -e -d "${PROFILEDIR}" -f "${R_PWFILE}" 2>&1 + RETEXPECTED=0 + + CU_ACTION="Import Bogus RSA-PSS CA Cert (invalid hashAlg)" + certu -A -n "TestCA-bogus-rsa-pss2" -t "C,," -d "${PROFILEDIR}" -f "${R_PWFILE}" \ + -i "${QADIR}/cert/TestCA-bogus-rsa-pss2.crt" 2>&1 + RETEXPECTED=255 + certu -V -b 1712101010Z -n TestCA-bogus-rsa-pss2 -u L -e -d "${PROFILEDIR}" -f "${R_PWFILE}" 2>&1 + RETEXPECTED=0 + + CERTSERIAL=200 + + # Subject certificate: RSA + # Issuer certificate: RSA + # Signature: RSA-PSS (explicit, with --pss-sign) + CERTNAME="TestUser-rsa-pss1" + + CU_ACTION="Generate Cert Request for $CERTNAME" + CU_SUBJECT="CN=$CERTNAME, E=${CERTNAME}@bogus.com, O=BOGUS NSS, L=Mountain View, ST=California, C=US" + certu -R -d "${PROFILEDIR}" -f "${R_PWFILE}" -z "${R_NOISE_FILE}" -o req 2>&1 + + CU_ACTION="Sign ${CERTNAME}'s Request" + certu -C -c "TestCA" --pss-sign -m "${CERTSERIAL}" -v 60 -d "${P_R_CADIR}" \ + -i req -o "${CERTNAME}.cert" -f "${R_PWFILE}" "$1" 2>&1 + + CU_ACTION="Import $CERTNAME's Cert" + certu -A -n "$CERTNAME" -t ",," -d "${PROFILEDIR}" -f "${R_PWFILE}" \ + -i "${CERTNAME}.cert" 2>&1 + + CU_ACTION="Verify $CERTNAME's Cert" + certu -V -u V -e -n "$CERTNAME" -d "${PROFILEDIR}" -f "${R_PWFILE}" + cat > ${TMP}/signalgo.exp <<EOF +Signature Algorithm: PKCS #1 RSA-PSS Signature + Parameters: + Hash algorithm: SHA-256 + Mask algorithm: PKCS #1 MGF1 Mask Generation Function + Mask hash algorithm: SHA-256 + Salt length: 32 (0x20) +EOF + check_sign_algo + + CERTSERIAL=`expr $CERTSERIAL + 1` + + # Subject certificate: RSA + # Issuer certificate: RSA + # Signature: RSA-PSS (explict, with --pss-sign -Z SHA512) + CERTNAME="TestUser-rsa-pss2" + + CU_ACTION="Generate Cert Request for $CERTNAME" + CU_SUBJECT="CN=$CERTNAME, E=${CERTNAME}@bogus.com, O=BOGUS NSS, L=Mountain View, ST=California, C=US" + certu -R -d "${PROFILEDIR}" -f "${R_PWFILE}" -z "${R_NOISE_FILE}" -o req 2>&1 + + CU_ACTION="Sign ${CERTNAME}'s Request" + certu -C -c "TestCA" --pss-sign -Z SHA512 -m "${CERTSERIAL}" -v 60 -d "${P_R_CADIR}" \ + -i req -o "${CERTNAME}.cert" -f "${R_PWFILE}" "$1" 2>&1 + + CU_ACTION="Import $CERTNAME's Cert" + certu -A -n "$CERTNAME" -t ",," -d "${PROFILEDIR}" -f "${R_PWFILE}" \ + -i "${CERTNAME}.cert" 2>&1 + + CU_ACTION="Verify $CERTNAME's Cert" + certu -V -u V -e -n "$CERTNAME" -d "${PROFILEDIR}" -f "${R_PWFILE}" + cat > ${TMP}/signalgo.exp <<EOF +Signature Algorithm: PKCS #1 RSA-PSS Signature + Parameters: + Hash algorithm: SHA-512 + Mask algorithm: PKCS #1 MGF1 Mask Generation Function + Mask hash algorithm: SHA-512 + Salt length: 64 (0x40) +EOF + check_sign_algo + + CERTSERIAL=`expr $CERTSERIAL + 1` + + # Subject certificate: RSA + # Issuer certificate: RSA-PSS + # Signature: RSA-PSS + CERTNAME="TestUser-rsa-pss3" + + CU_ACTION="Generate Cert Request for $CERTNAME" + CU_SUBJECT="CN=$CERTNAME, E=${CERTNAME}@bogus.com, O=BOGUS NSS, L=Mountain View, ST=California, C=US" + certu -R -d "${PROFILEDIR}" -f "${R_PWFILE}" -z "${R_NOISE_FILE}" -o req 2>&1 + + CU_ACTION="Sign ${CERTNAME}'s Request" + certu -C -c "TestCA-rsa-pss" -m "${CERTSERIAL}" -v 60 -d "${P_R_CADIR}" \ + -i req -o "${CERTNAME}.cert" -f "${R_PWFILE}" "$1" 2>&1 + + CU_ACTION="Import $CERTNAME's Cert" + certu -A -n "$CERTNAME" -t ",," -d "${PROFILEDIR}" -f "${R_PWFILE}" \ + -i "${CERTNAME}.cert" 2>&1 + + CU_ACTION="Verify $CERTNAME's Cert" + certu -V -u V -e -n "$CERTNAME" -d "${PROFILEDIR}" -f "${R_PWFILE}" + cat > ${TMP}/signalgo.exp <<EOF +Signature Algorithm: PKCS #1 RSA-PSS Signature + Parameters: + Hash algorithm: SHA-256 + Mask algorithm: PKCS #1 MGF1 Mask Generation Function + Mask hash algorithm: SHA-256 + Salt length: 32 (0x20) +EOF + check_sign_algo + + CERTSERIAL=`expr $CERTSERIAL + 1` + + # Subject certificate: RSA-PSS + # Issuer certificate: RSA + # Signature: RSA-PSS (explicit, with --pss-sign) + CERTNAME="TestUser-rsa-pss4" + + CU_ACTION="Generate Cert Request for $CERTNAME" + CU_SUBJECT="CN=$CERTNAME, E=${CERTNAME}@bogus.com, O=BOGUS NSS, L=Mountain View, ST=California, C=US" + certu -R -d "${PROFILEDIR}" -f "${R_PWFILE}" -z "${R_NOISE_FILE}" --pss -o req 2>&1 + + CU_ACTION="Sign ${CERTNAME}'s Request" + certu -C -c "TestCA" --pss-sign -m "${CERTSERIAL}" -v 60 -d "${P_R_CADIR}" \ + -i req -o "${CERTNAME}.cert" -f "${R_PWFILE}" "$1" 2>&1 + + CU_ACTION="Import $CERTNAME's Cert" + certu -A -n "$CERTNAME" -t ",," -d "${PROFILEDIR}" -f "${R_PWFILE}" \ + -i "${CERTNAME}.cert" 2>&1 + + CU_ACTION="Verify $CERTNAME's Cert" + certu -V -u V -e -n "$CERTNAME" -d "${PROFILEDIR}" -f "${R_PWFILE}" + cat > ${TMP}/signalgo.exp <<EOF +Signature Algorithm: PKCS #1 RSA-PSS Signature + Parameters: + Hash algorithm: SHA-256 + Mask algorithm: PKCS #1 MGF1 Mask Generation Function + Mask hash algorithm: SHA-256 + Salt length: 32 (0x20) +EOF + check_sign_algo + + CERTSERIAL=`expr $CERTSERIAL + 1` + + # Subject certificate: RSA-PSS + # Issuer certificate: RSA-PSS + # Signature: RSA-PSS (explicit, with --pss-sign) + CERTNAME="TestUser-rsa-pss5" + + CU_ACTION="Generate Cert Request for $CERTNAME" + CU_SUBJECT="CN=$CERTNAME, E=${CERTNAME}@bogus.com, O=BOGUS NSS, L=Mountain View, ST=California, C=US" + certu -R -d "${PROFILEDIR}" -f "${R_PWFILE}" -z "${R_NOISE_FILE}" --pss -o req 2>&1 + + CU_ACTION="Sign ${CERTNAME}'s Request" + certu -C -c "TestCA-rsa-pss" --pss-sign -m "${CERTSERIAL}" -v 60 -d "${P_R_CADIR}" \ + -i req -o "${CERTNAME}.cert" -f "${R_PWFILE}" "$1" 2>&1 + + CU_ACTION="Import $CERTNAME's Cert" + certu -A -n "$CERTNAME" -t ",," -d "${PROFILEDIR}" -f "${R_PWFILE}" \ + -i "${CERTNAME}.cert" 2>&1 + + CU_ACTION="Verify $CERTNAME's Cert" + certu -V -u V -e -n "$CERTNAME" -d "${PROFILEDIR}" -f "${R_PWFILE}" + cat > ${TMP}/signalgo.exp <<EOF +Signature Algorithm: PKCS #1 RSA-PSS Signature + Parameters: + Hash algorithm: SHA-256 + Mask algorithm: PKCS #1 MGF1 Mask Generation Function + Mask hash algorithm: SHA-256 + Salt length: 32 (0x20) +EOF + check_sign_algo + + CERTSERIAL=`expr $CERTSERIAL + 1` + + # Subject certificate: RSA-PSS + # Issuer certificate: RSA-PSS + # Signature: RSA-PSS (implicit, without --pss-sign) + CERTNAME="TestUser-rsa-pss6" + + CU_ACTION="Generate Cert Request for $CERTNAME" + CU_SUBJECT="CN=$CERTNAME, E=${CERTNAME}@bogus.com, O=BOGUS NSS, L=Mountain View, ST=California, C=US" + certu -R -d "${PROFILEDIR}" -f "${R_PWFILE}" -z "${R_NOISE_FILE}" --pss -o req 2>&1 + + CU_ACTION="Sign ${CERTNAME}'s Request" + # Sign without --pss-sign nor -Z option + certu -C -c "TestCA-rsa-pss" -m "${CERTSERIAL}" -v 60 -d "${P_R_CADIR}" \ + -i req -o "${CERTNAME}.cert" -f "${R_PWFILE}" "$1" 2>&1 + + CU_ACTION="Import $CERTNAME's Cert" + certu -A -n "$CERTNAME" -t ",," -d "${PROFILEDIR}" -f "${R_PWFILE}" \ + -i "${CERTNAME}.cert" 2>&1 + + CU_ACTION="Verify $CERTNAME's Cert" + certu -V -u V -e -n "$CERTNAME" -d "${PROFILEDIR}" -f "${R_PWFILE}" + cat > ${TMP}/signalgo.exp <<EOF +Signature Algorithm: PKCS #1 RSA-PSS Signature + Parameters: + Hash algorithm: SHA-256 + Mask algorithm: PKCS #1 MGF1 Mask Generation Function + Mask hash algorithm: SHA-256 + Salt length: 32 (0x20) +EOF + check_sign_algo + + CERTSERIAL=`expr $CERTSERIAL + 1` + + # Subject certificate: RSA-PSS + # Issuer certificate: RSA-PSS + # Signature: RSA-PSS (with conflicting hash algorithm) + CERTNAME="TestUser-rsa-pss7" + + CU_ACTION="Generate Cert Request for $CERTNAME" + CU_SUBJECT="CN=$CERTNAME, E=${CERTNAME}@bogus.com, O=BOGUS NSS, L=Mountain View, ST=California, C=US" + certu -R -d "${PROFILEDIR}" -f "${R_PWFILE}" -z "${R_NOISE_FILE}" --pss -o req 2>&1 + + CU_ACTION="Sign ${CERTNAME}'s Request" + RETEXPECTED=255 + certu -C -c "TestCA-rsa-pss" --pss-sign -Z SHA512 -m "${CERTSERIAL}" -v 60 -d "${P_R_CADIR}" \ + -i req -o "${CERTNAME}.cert" -f "${R_PWFILE}" "$1" 2>&1 + RETEXPECTED=0 + + CERTSERIAL=`expr $CERTSERIAL + 1` + + # Subject certificate: RSA-PSS + # Issuer certificate: RSA-PSS + # Signature: RSA-PSS (with compatible hash algorithm) + CERTNAME="TestUser-rsa-pss8" + + CU_ACTION="Generate Cert Request for $CERTNAME" + CU_SUBJECT="CN=$CERTNAME, E=${CERTNAME}@bogus.com, O=BOGUS NSS, L=Mountain View, ST=California, C=US" + certu -R -d "${PROFILEDIR}" -f "${R_PWFILE}" -z "${R_NOISE_FILE}" --pss -o req 2>&1 + + CU_ACTION="Sign ${CERTNAME}'s Request" + certu -C -c "TestCA-rsa-pss" --pss-sign -Z SHA256 -m "${CERTSERIAL}" -v 60 -d "${P_R_CADIR}" \ + -i req -o "${CERTNAME}.cert" -f "${R_PWFILE}" "$1" 2>&1 + + CU_ACTION="Import $CERTNAME's Cert" + certu -A -n "$CERTNAME" -t ",," -d "${PROFILEDIR}" -f "${R_PWFILE}" \ + -i "${CERTNAME}.cert" 2>&1 + + CU_ACTION="Verify $CERTNAME's Cert" + certu -V -u V -e -n "$CERTNAME" -d "${PROFILEDIR}" -f "${R_PWFILE}" + cat > ${TMP}/signalgo.exp <<EOF +Signature Algorithm: PKCS #1 RSA-PSS Signature + Parameters: + Hash algorithm: SHA-256 + Mask algorithm: PKCS #1 MGF1 Mask Generation Function + Mask hash algorithm: SHA-256 + Salt length: 32 (0x20) +EOF + check_sign_algo + + CERTSERIAL=`expr $CERTSERIAL + 1` + + # Subject certificate: RSA + # Issuer certificate: RSA + # Signature: RSA-PSS (explict, with --pss-sign -Z SHA1) + CERTNAME="TestUser-rsa-pss9" + + CU_ACTION="Generate Cert Request for $CERTNAME" + CU_SUBJECT="CN=$CERTNAME, E=${CERTNAME}@bogus.com, O=BOGUS NSS, L=Mountain View, ST=California, C=US" + certu -R -d "${PROFILEDIR}" -f "${R_PWFILE}" -z "${R_NOISE_FILE}" -o req 2>&1 + + CU_ACTION="Sign ${CERTNAME}'s Request" + certu -C -c "TestCA" --pss-sign -Z SHA1 -m "${CERTSERIAL}" -v 60 -d "${P_R_CADIR}" \ + -i req -o "${CERTNAME}.cert" -f "${R_PWFILE}" "$1" 2>&1 + + CU_ACTION="Import $CERTNAME's Cert" + certu -A -n "$CERTNAME" -t ",," -d "${PROFILEDIR}" -f "${R_PWFILE}" \ + -i "${CERTNAME}.cert" 2>&1 + + CU_ACTION="Verify $CERTNAME's Cert" + certu -V -u V -e -n "$CERTNAME" -d "${PROFILEDIR}" -f "${R_PWFILE}" + cat > ${TMP}/signalgo.exp <<EOF +Signature Algorithm: PKCS #1 RSA-PSS Signature + Parameters: + Hash algorithm: default, SHA-1 + Mask algorithm: default, MGF1 + Mask hash algorithm: default, SHA-1 + Salt length: default, 20 (0x14) +EOF + check_sign_algo + + CERTSERIAL=`expr $CERTSERIAL + 1` + + # Subject certificate: RSA-PSS + # Issuer certificate: RSA-PSS + # Signature: RSA-PSS (implicit, without --pss-sign, default parameters) + CERTNAME="TestUser-rsa-pss10" + + CU_ACTION="Generate Cert Request for $CERTNAME" + CU_SUBJECT="CN=$CERTNAME, E=${CERTNAME}@bogus.com, O=BOGUS NSS, L=Mountain View, ST=California, C=US" + certu -R -d "${PROFILEDIR}" -f "${R_PWFILE}" -z "${R_NOISE_FILE}" -o req 2>&1 + + CU_ACTION="Sign ${CERTNAME}'s Request" + # Sign without --pss-sign nor -Z option + certu -C -c "TestCA-rsa-pss-sha1" -m "${CERTSERIAL}" -v 60 -d "${P_R_CADIR}" \ + -i req -o "${CERTNAME}.cert" -f "${R_PWFILE}" "$1" 2>&1 + + CU_ACTION="Import $CERTNAME's Cert" + certu -A -n "$CERTNAME" -t ",," -d "${PROFILEDIR}" -f "${R_PWFILE}" \ + -i "${CERTNAME}.cert" 2>&1 + + CU_ACTION="Verify $CERTNAME's Cert" + certu -V -u V -e -n "$CERTNAME" -d "${PROFILEDIR}" -f "${R_PWFILE}" + cat > ${TMP}/signalgo.exp <<EOF +Signature Algorithm: PKCS #1 RSA-PSS Signature + Parameters: + Hash algorithm: default, SHA-1 + Mask algorithm: default, MGF1 + Mask hash algorithm: default, SHA-1 + Salt length: default, 20 (0x14) +EOF + check_sign_algo + + CERTSERIAL=`expr $CERTSERIAL + 1` + + # Subject certificate: RSA-PSS + # Issuer certificate: RSA-PSS + # Signature: RSA-PSS (with conflicting hash algorithm, default parameters) + CERTNAME="TestUser-rsa-pss11" + + CU_ACTION="Generate Cert Request for $CERTNAME" + CU_SUBJECT="CN=$CERTNAME, E=${CERTNAME}@bogus.com, O=BOGUS NSS, L=Mountain View, ST=California, C=US" + certu -R -d "${PROFILEDIR}" -f "${R_PWFILE}" -z "${R_NOISE_FILE}" --pss -o req 2>&1 + + CU_ACTION="Sign ${CERTNAME}'s Request" + RETEXPECTED=255 + certu -C -c "TestCA-rsa-pss-sha1" --pss-sign -Z SHA256 -m "${CERTSERIAL}" -v 60 -d "${P_R_CADIR}" \ + -i req -o "${CERTNAME}.cert" -f "${R_PWFILE}" "$1" 2>&1 + RETEXPECTED=0 +} + ############################## cert_cleanup ############################ # local shell function to finish this script (no exit since it might be # sourced) @@ -1975,20 +2432,24 @@ cert_test_ocspresp() cert_cleanup() { cert_log "$SCRIPTNAME: finished $SCRIPTNAME" - html "</TABLE><BR>" + html "</TABLE><BR>" cd ${QADIR} . common/cleanup.sh } ################## main ################################################# -cert_init +cert_init cert_all_CA -cert_extended_ssl -cert_ssl -cert_smime_client -if [ -z "$NSS_TEST_DISABLE_FIPS" ]; then - cert_fips +cert_test_implicit_db_init +cert_extended_ssl +cert_ssl +cert_smime_client +IS_FIPS_DISABLED=`certutil --build-flags |grep -cw NSS_FIPS_DISABLED` +if [ $IS_FIPS_DISABLED -ne 0 ]; then + cert_rsa_exponent_nonfips +else + cert_fips fi cert_eccurves cert_extensions @@ -1996,6 +2457,7 @@ cert_san_and_generic_extensions cert_test_password cert_test_distrust cert_test_ocspresp +cert_test_rsapss if [ -z "$NSS_TEST_DISABLE_CRL" ] ; then cert_crl_ssl @@ -2004,7 +2466,7 @@ else fi if [ -n "$DO_DIST_ST" -a "$DO_DIST_ST" = "TRUE" ] ; then - cert_stresscerts + cert_stresscerts fi cert_iopr_setup diff --git a/security/nss/tests/cipher/cipher.sh b/security/nss/tests/cipher/cipher.sh index 1d2561d9c..11a621815 100755 --- a/security/nss/tests/cipher/cipher.sh +++ b/security/nss/tests/cipher/cipher.sh @@ -107,6 +107,21 @@ cipher_gcm() done < ${GCM_TXT} } +###################### cipher_rsa_populate ############################ +# Test the ability to reconstruct rsa private key reconstruction +# also test the PK11GenericObject interface +################################################################### +cipher_rsa_populate() +{ + TESTNAME="RSA Reconstruct Private Keys Test" + echo "$SCRIPTNAME: $TESTNAME --------------------------------" + echo "rsapoptst -t all -r 10" +# skip e_d_q. It isn't reliable, and can return incorrect data. e_d_q should +# be turned off. + ${PROFTOOL} ${BINDIR}/rsapoptst -t e_n_p,d_n_q,d_p_q,e_d_n -r 10 + html_msg $? 0 "$TESTNAME" +} + ############################## cipher_cleanup ############################ # local shell function to finish this script (no exit since it might be # sourced) @@ -136,5 +151,6 @@ fi # Skip cipher_gcm if this is a softoken only build. if [ "${NSS_BUILD_SOFTOKEN_ONLY}" != "1" ]; then cipher_gcm + cipher_rsa_populate fi cipher_cleanup diff --git a/security/nss/tests/common/cleanup.sh b/security/nss/tests/common/cleanup.sh index 40885bc79..97c139321 100755 --- a/security/nss/tests/common/cleanup.sh +++ b/security/nss/tests/common/cleanup.sh @@ -30,6 +30,8 @@ if [ -z "${CLEANUP}" -o "${CLEANUP}" = "${SCRIPTNAME}" ]; then echo "NSS_DISABLE_HW_AES=${NSS_DISABLE_HW_AES}" echo "NSS_DISABLE_PCLMUL=${NSS_DISABLE_PCLMUL}" echo "NSS_DISABLE_AVX=${NSS_DISABLE_AVX}" + echo "NSS_DISABLE_ARM_NEON=${NSS_DISABLE_ARM_NEON}" + echo "NSS_DISABLE_SSSE3=${NSS_DISABLE_SSSE3}" echo echo "Tests summary:" echo "--------------" diff --git a/security/nss/tests/common/init.sh b/security/nss/tests/common/init.sh index caf3013e6..933551e83 100644 --- a/security/nss/tests/common/init.sh +++ b/security/nss/tests/common/init.sh @@ -63,11 +63,13 @@ if [ -z "${INIT_SOURCED}" -o "${INIT_SOURCED}" != "TRUE" ]; then DBPASSDIR=${HOSTDIR}/dbpass ECCURVES_DIR=${HOSTDIR}/eccurves DISTRUSTDIR=${HOSTDIR}/distrust + RSAPSSDIR=${HOSTDIR}/rsapss SERVER_CADIR=${HOSTDIR}/serverCA CLIENT_CADIR=${HOSTDIR}/clientCA EXT_SERVERDIR=${HOSTDIR}/ext_server EXT_CLIENTDIR=${HOSTDIR}/ext_client + IMPLICIT_INIT_DIR=${HOSTDIR}/implicit_init IOPR_CADIR=${HOSTDIR}/CA_iopr IOPR_SSL_SERVERDIR=${HOSTDIR}/server_ssl_iopr @@ -76,10 +78,12 @@ if [ -z "${INIT_SOURCED}" -o "${INIT_SOURCED}" != "TRUE" ]; then CERT_EXTENSIONS_DIR=${HOSTDIR}/cert_extensions STAPLINGDIR=${HOSTDIR}/stapling + NOLOGINDIR=${HOSTDIR}/nologin SSLGTESTDIR=${HOSTDIR}/ssl_gtests GTESTDIR=${HOSTDIR}/gtests PWFILE=${HOSTDIR}/tests.pw + EMPTY_FILE=${HOSTDIR}/tests_empty NOISE_FILE=${HOSTDIR}/tests_noise CORELIST_FILE=${HOSTDIR}/clist @@ -528,13 +532,16 @@ if [ -z "${INIT_SOURCED}" -o "${INIT_SOURCED}" != "TRUE" ]; then D_CLIENT_CA="ClientCA.$version" D_SERVER="Server.$version" D_CLIENT="Client.$version" + D_NOLOGIN="NoLogin.$version" D_FIPS="FIPS.$version" D_DBPASS="DBPASS.$version" D_ECCURVES="ECCURVES.$version" D_EXT_SERVER="ExtendedServer.$version" D_EXT_CLIENT="ExtendedClient.$version" + D_IMPLICIT_INIT="ImplicitInit.$version" D_CERT_EXTENSTIONS="CertExtensions.$version" 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 @@ -552,8 +559,10 @@ if [ -z "${INIT_SOURCED}" -o "${INIT_SOURCED}" != "TRUE" ]; then R_EVEDIR=../eve R_EXT_SERVERDIR=../ext_server R_EXT_CLIENTDIR=../ext_client + R_IMPLICIT_INIT_DIR=../implicit_init R_CERT_EXT=../cert_extensions R_STAPLINGDIR=../stapling + R_NOLOGINDIR=../nologin R_SSLGTESTDIR=../ssl_gtests R_GTESTDIR=../gtests @@ -568,8 +577,10 @@ if [ -z "${INIT_SOURCED}" -o "${INIT_SOURCED}" != "TRUE" ]; then P_R_EVEDIR=${R_EVEDIR} P_R_SERVERDIR=${R_SERVERDIR} P_R_CLIENTDIR=${R_CLIENTDIR} + P_R_NOLOGINDIR=${R_NOLOGINDIR} P_R_EXT_SERVERDIR=${R_EXT_SERVERDIR} P_R_EXT_CLIENTDIR=${R_EXT_CLIENTDIR} + P_R_IMPLICIT_INIT_DIR=${R_IMPLICIT_INIT_DIR} if [ -n "${MULTIACCESS_DBM}" ]; then P_R_CADIR="multiaccess:${D_CA}" P_R_ALICEDIR="multiaccess:${D_ALICE}" @@ -578,11 +589,14 @@ if [ -z "${INIT_SOURCED}" -o "${INIT_SOURCED}" != "TRUE" ]; then P_R_EVEDIR="multiaccess:${D_EVE}" P_R_SERVERDIR="multiaccess:${D_SERVER}" P_R_CLIENTDIR="multiaccess:${D_CLIENT}" + P_R_NOLOGINDIR="multiaccess:${D_NOLOGIN}" 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}" fi R_PWFILE=../tests.pw + R_EMPTY_FILE=../tests_empty R_NOISE_FILE=../tests_noise R_FIPSPWFILE=../tests.fipspw diff --git a/security/nss/tests/gtests/gtests.sh b/security/nss/tests/gtests/gtests.sh index c785241c4..6606b59e7 100755 --- a/security/nss/tests/gtests/gtests.sh +++ b/security/nss/tests/gtests/gtests.sh @@ -83,7 +83,7 @@ gtest_cleanup() } ################## main ################################################# -GTESTS="prng_gtest certhigh_gtest certdb_gtest der_gtest pk11_gtest util_gtest freebl_gtest" +GTESTS="prng_gtest certhigh_gtest certdb_gtest der_gtest pk11_gtest util_gtest freebl_gtest softoken_gtest blake2b_gtest" SOURCE_DIR="$PWD"/../.. gtest_init $0 gtest_start diff --git a/security/nss/tests/interop/interop.sh b/security/nss/tests/interop/interop.sh index 59f0cb481..97c82e0ca 100644 --- a/security/nss/tests/interop/interop.sh +++ b/security/nss/tests/interop/interop.sh @@ -24,7 +24,8 @@ interop_init() cd "${HOSTDIR}/interop" INTEROP=${INTEROP:=tls_interop} if [ ! -d "$INTEROP" ]; then - git clone -q https://github.com/mozilla/tls-interop "$INTEROP" + git clone -q https://github.com/ttaubert/tls-interop "$INTEROP" + git -C "$INTEROP" checkout -q 07930b791827c1bdb6f4c19ca0aa63850fd59e22 fi INTEROP=$(cd "$INTEROP";pwd -P) @@ -56,7 +57,12 @@ interop_run() (cd "$INTEROP"; cargo run -- --client "$client" --server "$server" --rootdir "$BORING"/ssl/test/runner/ --test-cases cases.json) 2>interop-${test_name}.errors | tee interop-${test_name}.log - html_msg "${PIPESTATUS[0]}" 0 "Interop" "Run successfully" + RESULT=${PIPESTATUS[0]} + html_msg "${RESULT}" 0 "Interop" "Run successfully" + if [ $RESULT -ne 0 ]; then + cat interop-${test_name}.errors + cat interop-${test_name}.log + fi grep -i 'FAILED\|Assertion failure' interop-${test_name}.errors html_msg $? 1 "Interop" "No failures" } diff --git a/security/nss/tests/merge/merge.sh b/security/nss/tests/merge/merge.sh index 1929b12c8..d17a8c4ef 100755 --- a/security/nss/tests/merge/merge.sh +++ b/security/nss/tests/merge/merge.sh @@ -98,7 +98,7 @@ merge_init() # are dbm databases. if [ "${TEST_MODE}" = "UPGRADE_DB" ]; then save=${NSS_DEFAULT_DB_TYPE} - NSS_DEFAULT_DB_TYPE= ; export NSS_DEFAULT_DB_TYPE + NSS_DEFAULT_DB_TYPE=dbm ; export NSS_DEFAULT_DB_TYPE fi certutil -N -d ${CONFLICT1DIR} -f ${R_PWFILE} diff --git a/security/nss/tests/pkits/pkits.sh b/security/nss/tests/pkits/pkits.sh index ecf007736..e79fdd382 100755 --- a/security/nss/tests/pkits/pkits.sh +++ b/security/nss/tests/pkits/pkits.sh @@ -93,7 +93,7 @@ pkits_init() ${BINDIR}/certutil -N -d ${PKITSdb} -f ${PKITSdb}/pw ${BINDIR}/certutil -A -n TrustAnchorRootCertificate -t "C,C,C" -i \ - $certs/TrustAnchorRootCertificate.crt -d $PKITSdb + $certs/TrustAnchorRootCertificate.crt -d $PKITSdb -f ${PKITSdb}/pw if [ -z "$NSS_NO_PKITS_CRLS" ]; then ${BINDIR}/crlutil -I -i $crls/TrustAnchorRootCRL.crl -d ${PKITSdb} -f ${PKITSdb}/pw else diff --git a/security/nss/tests/remote/Makefile b/security/nss/tests/remote/Makefile index 6c6e5bd55..4635bccc5 100644 --- a/security/nss/tests/remote/Makefile +++ b/security/nss/tests/remote/Makefile @@ -80,7 +80,6 @@ package_for_testing: echo 'export USE_64=$(USE_64)' >> $(RTSH) echo 'export BUILD_OPT=$(BUILD_OPT)' >> $(RTSH) echo 'export PKITS_DATA=$(PKITS_DATA)' >> $(RTSH) - echo 'export NSS_DISABLE_ECC=$(NSS_DISABLE_ECC)' >> $(RTSH) echo 'export NSPR_LOG_MODULES=$(NSPR_LOG_MODULES)' >> $(RTSH) ifeq ($(OS_TARGET),Android) # Android doesn't support FIPS tests, because diff --git a/security/nss/tests/smime/smime.sh b/security/nss/tests/smime/smime.sh index 2360100de..9cdc0875b 100755 --- a/security/nss/tests/smime/smime.sh +++ b/security/nss/tests/smime/smime.sh @@ -40,11 +40,7 @@ smime_init() fi SCRIPTNAME=smime.sh - if [ -z "$NSS_DISABLE_ECC" ] ; then - html_head "S/MIME Tests with ECC" - else - html_head "S/MIME Tests" - fi + html_head "S/MIME Tests" grep "SUCCESS: SMIME passed" $CERT_LOG_FILE >/dev/null || { Exit 11 "Fatal - S/MIME of cert.sh needs to pass first" @@ -85,29 +81,27 @@ smime_sign() html_msg $? 0 "Compare Attached Signed Data and Original (${HASH})" "." # Test ECDSA signing for all hash algorithms. - if [ -z "$NSS_DISABLE_ECC" ] ; then - echo "$SCRIPTNAME: Signing Detached Message ECDSA w/ {$HASH} ------------------" - echo "cmsutil -S -T -N Alice-ec ${HASH_CMD} -i alice.txt -d ${P_R_ALICEDIR} -p nss -o alice-ec.d${SIG}" - ${PROFTOOL} ${BINDIR}/cmsutil -S -T -N Alice-ec ${HASH_CMD} -i alice.txt -d ${P_R_ALICEDIR} -p nss -o alice-ec.d${SIG} - html_msg $? 0 "Create Detached Signature Alice (ECDSA w/ ${HASH})" "." - - echo "cmsutil -D -i alice-ec.d${SIG} -c alice.txt -d ${P_R_BOBDIR} " - ${PROFTOOL} ${BINDIR}/cmsutil -D -i alice-ec.d${SIG} -c alice.txt -d ${P_R_BOBDIR} - html_msg $? 0 "Verifying Alice's Detached Signature (ECDSA w/ ${HASH})" "." - - echo "$SCRIPTNAME: Signing Attached Message (ECDSA w/ ${HASH}) ------------------" - echo "cmsutil -S -N Alice-ec ${HASH_CMD} -i alice.txt -d ${P_R_ALICEDIR} -p nss -o alice-ec.${SIG}" - ${PROFTOOL} ${BINDIR}/cmsutil -S -N Alice-ec ${HASH_CMD} -i alice.txt -d ${P_R_ALICEDIR} -p nss -o alice-ec.${SIG} - html_msg $? 0 "Create Attached Signature Alice (ECDSA w/ ${HASH})" "." - - echo "cmsutil -D -i alice-ec.${SIG} -d ${P_R_BOBDIR} -o alice-ec.data.${HASH}" - ${PROFTOOL} ${BINDIR}/cmsutil -D -i alice-ec.${SIG} -d ${P_R_BOBDIR} -o alice-ec.data.${HASH} - html_msg $? 0 "Decode Alice's Attached Signature (ECDSA w/ ${HASH})" "." - - echo "diff alice.txt alice-ec.data.${HASH}" - diff alice.txt alice-ec.data.${HASH} - html_msg $? 0 "Compare Attached Signed Data and Original (ECDSA w/ ${HASH})" "." - fi + echo "$SCRIPTNAME: Signing Detached Message ECDSA w/ {$HASH} ------------------" + echo "cmsutil -S -T -N Alice-ec ${HASH_CMD} -i alice.txt -d ${P_R_ALICEDIR} -p nss -o alice-ec.d${SIG}" + ${PROFTOOL} ${BINDIR}/cmsutil -S -T -N Alice-ec ${HASH_CMD} -i alice.txt -d ${P_R_ALICEDIR} -p nss -o alice-ec.d${SIG} + html_msg $? 0 "Create Detached Signature Alice (ECDSA w/ ${HASH})" "." + + echo "cmsutil -D -i alice-ec.d${SIG} -c alice.txt -d ${P_R_BOBDIR} " + ${PROFTOOL} ${BINDIR}/cmsutil -D -i alice-ec.d${SIG} -c alice.txt -d ${P_R_BOBDIR} + html_msg $? 0 "Verifying Alice's Detached Signature (ECDSA w/ ${HASH})" "." + + echo "$SCRIPTNAME: Signing Attached Message (ECDSA w/ ${HASH}) ------------------" + echo "cmsutil -S -N Alice-ec ${HASH_CMD} -i alice.txt -d ${P_R_ALICEDIR} -p nss -o alice-ec.${SIG}" + ${PROFTOOL} ${BINDIR}/cmsutil -S -N Alice-ec ${HASH_CMD} -i alice.txt -d ${P_R_ALICEDIR} -p nss -o alice-ec.${SIG} + html_msg $? 0 "Create Attached Signature Alice (ECDSA w/ ${HASH})" "." + + echo "cmsutil -D -i alice-ec.${SIG} -d ${P_R_BOBDIR} -o alice-ec.data.${HASH}" + ${PROFTOOL} ${BINDIR}/cmsutil -D -i alice-ec.${SIG} -d ${P_R_BOBDIR} -o alice-ec.data.${HASH} + html_msg $? 0 "Decode Alice's Attached Signature (ECDSA w/ ${HASH})" "." + + echo "diff alice.txt alice-ec.data.${HASH}" + diff alice.txt alice-ec.data.${HASH} + html_msg $? 0 "Compare Attached Signed Data and Original (ECDSA w/ ${HASH})" "." } diff --git a/security/nss/tests/ssl/ssl.sh b/security/nss/tests/ssl/ssl.sh index 944849ad3..de867a4bd 100755 --- a/security/nss/tests/ssl/ssl.sh +++ b/security/nss/tests/ssl/ssl.sh @@ -57,10 +57,16 @@ ssl_init() fi PORT=${PORT-8443} + # Avoid port conflicts when multiple tests are running on the same machine. + if [ -n "$NSS_TASKCLUSTER_MAC" ]; then + cwd=$(cd $(dirname $0); pwd -P) + padd=$(echo $cwd | cut -d "/" -f4 | sed 's/[^0-9]//g') + PORT=$(($PORT + $padd)) + fi NSS_SSL_TESTS=${NSS_SSL_TESTS:-normal_normal} - nss_ssl_run="stapling signed_cert_timestamps cov auth stress" + nss_ssl_run="stapling signed_cert_timestamps cov auth stress dtls" NSS_SSL_RUN=${NSS_SSL_RUN:-$nss_ssl_run} - + # Test case files SSLCOV=${QADIR}/ssl/sslcov.txt SSLAUTH=${QADIR}/ssl/sslauth.txt @@ -90,15 +96,8 @@ ssl_init() NON_EC_SUITES=":0016:0032:0033:0038:0039:003B:003C:003D:0040:0041:0067:006A:006B" NON_EC_SUITES="${NON_EC_SUITES}:0084:009C:009D:009E:009F:00A2:00A3:CCAAcdeinvyz" - if [ -z "$NSS_DISABLE_ECC" ] ; then - ECC_STRING=" - with ECC" - # List of cipher suites to test, including ECC cipher suites. - CIPHER_SUITES="-c ${EC_SUITES}${NON_EC_SUITES}" - else - ECC_STRING="" - # List of cipher suites to test, excluding ECC cipher suites. - CIPHER_SUITES="-c ${NON_EC_SUITES}" - fi + # List of cipher suites to test, including ECC cipher suites. + CIPHER_SUITES="-c ${EC_SUITES}${NON_EC_SUITES}" if [ "${OS_ARCH}" != "WINNT" ]; then ulimit -n 1000 # make sure we have enough file descriptors @@ -141,16 +140,16 @@ wait_for_selfserv() { #verbose="-v" echo "trying to connect to selfserv at `date`" - echo "tstclnt -p ${PORT} -h ${HOSTADDR} ${CLIENT_OPTIONS} -q \\" + echo "tstclnt -4 -p ${PORT} -h ${HOSTADDR} ${CLIENT_OPTIONS} -q \\" echo " -d ${P_R_CLIENTDIR} $verbose < ${REQUEST_FILE}" - ${BINDIR}/tstclnt -p ${PORT} -h ${HOSTADDR} ${CLIENT_OPTIONS} -q \ + ${BINDIR}/tstclnt -4 -p ${PORT} -h ${HOSTADDR} ${CLIENT_OPTIONS} -q \ -d ${P_R_CLIENTDIR} $verbose < ${REQUEST_FILE} if [ $? -ne 0 ]; then sleep 5 echo "retrying to connect to selfserv at `date`" echo "tstclnt -p ${PORT} -h ${HOSTADDR} ${CLIENT_OPTIONS} -q \\" echo " -d ${P_R_CLIENTDIR} $verbose < ${REQUEST_FILE}" - ${BINDIR}/tstclnt -p ${PORT} -h ${HOSTADDR} ${CLIENT_OPTIONS} -q \ + ${BINDIR}/tstclnt -4 -p ${PORT} -h ${HOSTADDR} ${CLIENT_OPTIONS} -q \ -d ${P_R_CLIENTDIR} $verbose < ${REQUEST_FILE} if [ $? -ne 0 ]; then html_failed "Waiting for Server" @@ -212,8 +211,7 @@ start_selfserv() echo "$SCRIPTNAME: $testname ----" fi sparam=`echo $sparam | sed -e 's;_; ;g'` - if [ -z "$NSS_DISABLE_ECC" ] && \ - [ -z "$NO_ECC_CERTS" -o "$NO_ECC_CERTS" != "1" ] ; then + if [ -z "$NO_ECC_CERTS" -o "$NO_ECC_CERTS" != "1" ] ; then ECC_OPTIONS="-e ${HOSTADDR}-ecmixed -e ${HOSTADDR}-ec" else ECC_OPTIONS="" @@ -258,13 +256,18 @@ start_selfserv() echo "selfserv with PID ${PID} started at `date`" } +ignore_blank_lines() +{ + LC_ALL=C grep -v '^[[:space:]]*\(#\|$\)' "$1" +} + ############################## ssl_cov ################################# # local shell function to perform SSL Cipher Coverage tests ######################################################################## ssl_cov() { #verbose="-v" - html_head "SSL Cipher Coverage $NORM_EXT - server $SERVER_MODE/client $CLIENT_MODE $ECC_STRING" + html_head "SSL Cipher Coverage $NORM_EXT - server $SERVER_MODE/client $CLIENT_MODE" testname="" sparam="$CIPHER_SUITES" @@ -274,15 +277,15 @@ ssl_cov() VMIN="ssl3" VMAX="tls1.1" - exec < ${SSLCOV} + ignore_blank_lines ${SSLCOV} | \ while read ectype testmax param testname do echo "${testname}" | grep "EXPORT" > /dev/null EXP=$? - if [ "$ectype" = "ECC" -a -n "$NSS_DISABLE_ECC" ] ; then + if [ "$ectype" = "ECC" ] ; then echo "$SCRIPTNAME: skipping $testname (ECC only)" - elif [ "`echo $ectype | cut -b 1`" != "#" ] ; then + else echo "$SCRIPTNAME: running $testname ----------------------------" VMAX="ssl3" if [ "$testmax" = "TLS10" ]; then @@ -295,11 +298,11 @@ ssl_cov() VMAX="tls1.2" fi - echo "tstclnt -p ${PORT} -h ${HOSTADDR} -c ${param} -V ${VMIN}:${VMAX} ${CLIENT_OPTIONS} \\" + 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 -p ${PORT} -h ${HOSTADDR} -c ${param} -V ${VMIN}:${VMAX} ${CLIENT_OPTIONS} -f \ + ${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=$? @@ -320,12 +323,11 @@ ssl_cov() ssl_auth() { #verbose="-v" - html_head "SSL Client Authentication $NORM_EXT - server $SERVER_MODE/client $CLIENT_MODE $ECC_STRING" + html_head "SSL Client Authentication $NORM_EXT - server $SERVER_MODE/client $CLIENT_MODE" - exec < ${SSLAUTH} + ignore_blank_lines ${SSLAUTH} | \ while read ectype value sparam cparam testname do - [ -z "$ectype" ] && continue echo "${testname}" | grep "don't require client auth" > /dev/null CAUTH=$? @@ -333,9 +335,9 @@ 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" -a -n "$NSS_DISABLE_ECC" ] ; then + elif [ "$ectype" = "ECC" ] ; then echo "$SCRIPTNAME: skipping $testname (ECC only)" - elif [ "`echo $ectype | cut -b 1`" != "#" ]; then + else cparam=`echo $cparam | sed -e 's;_; ;g' -e "s/TestUser/$USER_NICKNAME/g" ` if [ "$ectype" = "SNI" ]; then cparam=`echo $cparam | sed -e "s/Host/$HOST/g" -e "s/Dom/$DOMSUF/g" ` @@ -343,10 +345,10 @@ ssl_auth() fi start_selfserv - echo "tstclnt -p ${PORT} -h ${HOSTADDR} -f -d ${P_R_CLIENTDIR} $verbose ${CLIENT_OPTIONS} \\" + echo "tstclnt -4 -p ${PORT} -h ${HOSTADDR} -f -d ${P_R_CLIENTDIR} $verbose ${CLIENT_OPTIONS} \\" echo " ${cparam} < ${REQUEST_FILE}" rm ${TMP}/$HOST.tmp.$$ 2>/dev/null - ${PROFTOOL} ${BINDIR}/tstclnt -p ${PORT} -h ${HOSTADDR} -f ${cparam} $verbose ${CLIENT_OPTIONS} \ + ${PROFTOOL} ${BINDIR}/tstclnt -4 -p ${PORT} -h ${HOSTADDR} -f ${cparam} $verbose ${CLIENT_OPTIONS} \ -d ${P_R_CLIENTDIR} < ${REQUEST_FILE} \ >${TMP}/$HOST.tmp.$$ 2>&1 ret=$? @@ -395,10 +397,10 @@ ssl_stapling_sub() start_selfserv - echo "tstclnt -p ${PORT} -h ${HOSTADDR} -f -d ${P_R_CLIENTDIR} $verbose ${CLIENT_OPTIONS} \\" + echo "tstclnt -4 -p ${PORT} -h ${HOSTADDR} -f -d ${P_R_CLIENTDIR} $verbose ${CLIENT_OPTIONS} \\" echo " -c v -T -O -F -M 1 -V ssl3:tls1.2 < ${REQUEST_FILE}" rm ${TMP}/$HOST.tmp.$$ 2>/dev/null - ${PROFTOOL} ${BINDIR}/tstclnt -p ${PORT} -h ${HOSTADDR} -f ${CLIENT_OPTIONS} \ + ${PROFTOOL} ${BINDIR}/tstclnt -4 -p ${PORT} -h ${HOSTADDR} -f ${CLIENT_OPTIONS} \ -d ${P_R_CLIENTDIR} $verbose -c v -T -O -F -M 1 -V ssl3:tls1.2 < ${REQUEST_FILE} \ >${TMP}/$HOST.tmp.$$ 2>&1 ret=$? @@ -465,7 +467,7 @@ ssl_stapling_stress() ######################################################################## ssl_stapling() { - html_head "SSL Cert Status (OCSP Stapling) $NORM_EXT - server $SERVER_MODE/client $CLIENT_MODE $ECC_STRING" + html_head "SSL Cert Status (OCSP Stapling) $NORM_EXT - server $SERVER_MODE/client $CLIENT_MODE" # tstclnt Exit code: # 0: have fresh and valid revocation data, status good @@ -498,7 +500,7 @@ ssl_stapling() ssl_signed_cert_timestamps() { #verbose="-v" - html_head "SSL Signed Certificate Timestamps $NORM_EXT - server $SERVER_MODE/client $CLIENT_MODE $ECC_STRING" + html_head "SSL Signed Certificate Timestamps $NORM_EXT - server $SERVER_MODE/client $CLIENT_MODE" testname="ssl_signed_cert_timestamps" value=0 @@ -514,10 +516,10 @@ ssl_signed_cert_timestamps() # Since we don't have server-side support, this test only covers advertising the # extension in the client hello. - echo "tstclnt -p ${PORT} -h ${HOSTADDR} -f -d ${P_R_CLIENTDIR} $verbose ${CLIENT_OPTIONS} \\" + echo "tstclnt -4 -p ${PORT} -h ${HOSTADDR} -f -d ${P_R_CLIENTDIR} $verbose ${CLIENT_OPTIONS} \\" echo " -U -V tls1.0:tls1.2 < ${REQUEST_FILE}" rm ${TMP}/$HOST.tmp.$$ 2>/dev/null - ${PROFTOOL} ${BINDIR}/tstclnt -p ${PORT} -h ${HOSTADDR} -f ${CLIENT_OPTIONS} \ + ${PROFTOOL} ${BINDIR}/tstclnt -4 -p ${PORT} -h ${HOSTADDR} -f ${CLIENT_OPTIONS} \ -d ${P_R_CLIENTDIR} $verbose -U -V tls1.0:tls1.2 < ${REQUEST_FILE} \ >${TMP}/$HOST.tmp.$$ 2>&1 ret=$? @@ -536,26 +538,26 @@ ssl_signed_cert_timestamps() ######################################################################## ssl_stress() { - html_head "SSL Stress Test $NORM_EXT - server $SERVER_MODE/client $CLIENT_MODE $ECC_STRING" + html_head "SSL Stress Test $NORM_EXT - server $SERVER_MODE/client $CLIENT_MODE" - exec < ${SSLSTRESS} + ignore_blank_lines ${SSLSTRESS} | \ while read ectype value sparam cparam testname do - if [ -z "$ectype" ]; then - # silently ignore blank lines - continue - fi - echo "${testname}" | grep "client auth" > /dev/null CAUTH=$? + echo "${testname}" | grep "no login" > /dev/null + NOLOGIN=$? if [ "$ectype" = "SNI" -a "$NORM_EXT" = "Extended Test" ] ; then echo "$SCRIPTNAME: skipping $testname for $NORM_EXT" - elif [ "$ectype" = "ECC" -a -n "$NSS_DISABLE_ECC" ] ; then + 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 [ "`echo $ectype | cut -b 1`" != "#" ]; then + elif [ "${NOLOGIN}" -eq 0 ] && \ + [ "${CLIENT_MODE}" = "fips" -o "$NORM_EXT" = "Extended Test" ] ; then + echo "$SCRIPTNAME: skipping $testname for $NORM_EXT" + else cparam=`echo $cparam | sed -e 's;_; ;g' -e "s/TestUser/$USER_NICKNAME/g" ` if [ "$ectype" = "SNI" ]; then cparam=`echo $cparam | sed -e "s/Host/$HOST/g" -e "s/Dom/$DOMSUF/g" ` @@ -569,10 +571,16 @@ ssl_stress() ps -ef | grep selfserv fi - echo "strsclnt -q -p ${PORT} -d ${P_R_CLIENTDIR} ${CLIENT_OPTIONS} -w nss $cparam \\" + if [ "${NOLOGIN}" -eq 0 ] ; then + dbdir=${P_R_NOLOGINDIR} + else + dbdir=${P_R_CLIENTDIR} + fi + + echo "strsclnt -q -p ${PORT} -d ${dbdir} ${CLIENT_OPTIONS} -w nss $cparam \\" echo " -V ssl3:tls1.2 $verbose ${HOSTADDR}" echo "strsclnt started at `date`" - ${PROFTOOL} ${BINDIR}/strsclnt -q -p ${PORT} -d ${P_R_CLIENTDIR} ${CLIENT_OPTIONS} -w nss $cparam \ + ${PROFTOOL} ${BINDIR}/strsclnt -q -p ${PORT} -d ${dbdir} ${CLIENT_OPTIONS} -w nss $cparam \ -V ssl3:tls1.2 $verbose ${HOSTADDR} ret=$? echo "strsclnt completed at `date`" @@ -596,7 +604,7 @@ ssl_stress() ssl_crl_ssl() { #verbose="-v" - html_head "CRL SSL Client Tests $NORM_EXT $ECC_STRING" + html_head "CRL SSL Client Tests $NORM_EXT" # Using First CRL Group for this test. There are $CRL_GRP_1_RANGE certs in it. # Cert number $UNREVOKED_CERT_GRP_1 was not revoked @@ -604,15 +612,14 @@ ssl_crl_ssl() CRL_GROUP_RANGE=$CRL_GRP_1_RANGE UNREVOKED_CERT=$UNREVOKED_CERT_GRP_1 - exec < ${SSLAUTH} + ignore_blank_lines ${SSLAUTH} | \ while read ectype value sparam cparam testname do - [ "$ectype" = "" ] && continue - if [ "$ectype" = "ECC" -a -n "$NSS_DISABLE_ECC" ] ; then + if [ "$ectype" = "ECC" ] ; then echo "$SCRIPTNAME: skipping $testname (ECC only)" elif [ "$ectype" = "SNI" ]; then continue - elif [ "`echo $ectype | cut -b 1`" != "#" ]; then + else servarg=`echo $sparam | awk '{r=split($0,a,"-r") - 1;print r;}'` pwd=`echo $cparam | grep nss` user=`echo $cparam | grep TestUser` @@ -642,10 +649,10 @@ ssl_crl_ssl() cparam=`echo $_cparam | sed -e 's;_; ;g' -e "s/TestUser/$USER_NICKNAME/g" ` start_selfserv - echo "tstclnt -p ${PORT} -h ${HOSTADDR} -f -d ${R_CLIENTDIR} $verbose \\" + echo "tstclnt -4 -p ${PORT} -h ${HOSTADDR} -f -d ${R_CLIENTDIR} $verbose \\" echo " ${cparam} < ${REQUEST_FILE}" rm ${TMP}/$HOST.tmp.$$ 2>/dev/null - ${PROFTOOL} ${BINDIR}/tstclnt -p ${PORT} -h ${HOSTADDR} -f ${cparam} \ + ${PROFTOOL} ${BINDIR}/tstclnt -4 -p ${PORT} -h ${HOSTADDR} -f ${cparam} \ -d ${R_CLIENTDIR} $verbose < ${REQUEST_FILE} \ >${TMP}/$HOST.tmp.$$ 2>&1 ret=$? @@ -669,19 +676,47 @@ ssl_crl_ssl() html "</TABLE><BR>" } -############################## ssl_cov ################################# +############################# setup_policy ############################# +# local shell function to create policy configuration +######################################################################## +setup_policy() +{ + policy="$1" + outdir="$2" + OUTFILE="${outdir}/pkcs11.txt" + cat > "$OUTFILE" << ++EOF++ +library= +name=NSS Internal PKCS #11 Module +parameters=configdir='./client' certPrefix='' keyPrefix='' secmod='secmod.db' flags= updatedir='' updateCertPrefix='' updateKeyPrefix='' updateid='' updateTokenDescription='' +NSS=Flags=internal,critical trustOrder=75 cipherOrder=100 slotParams=(1={slotFlags=[RSA,DSA,DH,RC2,RC4,DES,RANDOM,SHA1,MD5,MD2,SSL,TLS,AES,Camellia,SEED,SHA256,SHA512] askpw=any timeout=30}) +++EOF++ + echo "config=${policy}" >> "$OUTFILE" + echo "" >> "$OUTFILE" + echo "library=${DIST}/${OBJDIR}/lib/libnssckbi.so" >> "$OUTFILE" + cat >> "$OUTFILE" << ++EOF++ +name=RootCerts +NSS=trustOrder=100 +++EOF++ + + echo "******************************Testing with: " + cat "$OUTFILE" + echo "******************************" +} + +############################## ssl_policy ############################## # local shell function to perform SSL Policy tests ######################################################################## ssl_policy() { #verbose="-v" - html_head "SSL POLICY $NORM_EXT - server $SERVER_MODE/client $CLIENT_MODE $ECC_STRING" + html_head "SSL POLICY $NORM_EXT - server $SERVER_MODE/client $CLIENT_MODE" testname="" sparam="$CIPHER_SUITES" if [ ! -f "${P_R_CLIENTDIR}/pkcs11.txt" ] ; then - return; + html_failed "${SCRIPTNAME}: ${P_R_CLIENTDIR} is not initialized" + return 1; fi echo "Saving pkcs11.txt" @@ -689,17 +724,14 @@ ssl_policy() start_selfserv # Launch the server - VMIN="ssl3" - VMAX="tls1.2" - - exec < ${SSLPOLICY} + ignore_blank_lines ${SSLPOLICY} | \ while read value ectype testmax param policy testname do VMIN="ssl3" - if [ "$ectype" = "ECC" -a -n "$NSS_DISABLE_ECC" ] ; then + if [ "$ectype" = "ECC" ] ; then echo "$SCRIPTNAME: skipping $testname (ECC only)" - elif [ "`echo $value | cut -b 1`" != "#" ] ; then + else echo "$SCRIPTNAME: running $testname ----------------------------" VMAX="ssl3" if [ "$testmax" = "TLS10" ]; then @@ -714,30 +746,13 @@ ssl_policy() # load the policy policy=`echo ${policy} | sed -e 's;_; ;g'` + setup_policy "$policy" ${P_R_CLIENTDIR} - cat > ${P_R_CLIENTDIR}/pkcs11.txt << ++EOF++ -library= -name=NSS Internal PKCS #11 Module -parameters=configdir='./client' certPrefix='' keyPrefix='' secmod='secmod.db' flags= updatedir='' updateCertPrefix='' updateKeyPrefix='' updateid='' updateTokenDescription='' -NSS=Flags=internal,critical trustOrder=75 cipherOrder=100 slotParams=(1={slotFlags=[RSA,DSA,DH,RC2,RC4,DES,RANDOM,SHA1,MD5,MD2,SSL,TLS,AES,Camellia,SEED,SHA256,SHA512] askpw=any timeout=30}) -++EOF++ - echo "config=${policy}" >> ${P_R_CLIENTDIR}/pkcs11.txt - echo "" >> ${P_R_CLIENTDIR}/pkcs11.txt - echo "library=${DIST}/${OBJDIR}/lib/libnssckbi.so" >> ${P_R_CLIENTDIR}/pkcs11.txt >> ${P_R_CLIENTDIR}/pkcs11.txt - cat >> ${P_R_CLIENTDIR}/pkcs11.txt << ++EOF++ -name=RootCerts -NSS=trustOrder=100 -++EOF++ - - echo "******************************Testing with: " - cat ${P_R_CLIENTDIR}/pkcs11.txt - echo "******************************" - - echo "tstclnt -p ${PORT} -h ${HOSTADDR} -c ${param} -V ${VMIN}:${VMAX} ${CLIENT_OPTIONS} \\" + 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 -p ${PORT} -h ${HOSTADDR} -c ${param} -V ${VMIN}:${VMAX} ${CLIENT_OPTIONS} -f \ + ${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=$? @@ -757,6 +772,103 @@ NSS=trustOrder=100 kill_selfserv html "</TABLE><BR>" } + +list_enabled_suites() +{ + echo "SSL_DIR=${P_R_CLIENTDIR} ${BINDIR}/listsuites" + SSL_DIR="${P_R_CLIENTDIR}" ${BINDIR}/listsuites | tail -n+3 | \ + sed -n -e '/^TLS_/h' -e '/^ .*Enabled.*/{g;p}' | sed 's/:$//' +} + +############################## ssl_policy_listsuites ################### +# local shell function to perform SSL Policy tests, using listsuites +######################################################################## +ssl_policy_listsuites() +{ + #verbose="-v" + html_head "SSL POLICY LISTSUITES $NORM_EXT - server $SERVER_MODE/client $CLIENT_MODE" + + testname="" + sparam="$CIPHER_SUITES" + + if [ ! -f "${P_R_CLIENTDIR}/pkcs11.txt" ] ; then + html_failed "${SCRIPTNAME}: ${P_R_CLIENTDIR} is not initialized" + return 1; + fi + + echo "Saving pkcs11.txt" + cp ${P_R_CLIENTDIR}/pkcs11.txt ${P_R_CLIENTDIR}/pkcs11.txt.sav + + # Disallow all explicitly + setup_policy "disallow=all" ${P_R_CLIENTDIR} + RET_EXP=1 + list_enabled_suites | grep '^TLS_' + RET=$? + html_msg $RET $RET_EXP "${testname}" \ + "produced a returncode of $RET, expected is $RET_EXP" + + # Disallow RSA in key exchange explicitly + setup_policy "disallow=rsa/ssl-key-exchange" ${P_R_CLIENTDIR} + RET_EXP=1 + list_enabled_suites | grep '^TLS_RSA_' + RET=$? + html_msg $RET $RET_EXP "${testname}" \ + "produced a returncode of $RET, expected is $RET_EXP" + + cp ${P_R_CLIENTDIR}/pkcs11.txt.sav ${P_R_CLIENTDIR}/pkcs11.txt + + html "</TABLE><BR>" +} + +############################## ssl_policy_selfserv ##################### +# local shell function to perform SSL Policy tests, using selfserv +######################################################################## +ssl_policy_selfserv() +{ + #verbose="-v" + html_head "SSL POLICY SELFSERV $NORM_EXT - server $SERVER_MODE/client $CLIENT_MODE" + + testname="" + sparam="$CIPHER_SUITES" + + if [ ! -f "${P_R_SERVERDIR}/pkcs11.txt" ] ; then + html_failed "${SCRIPTNAME}: ${P_R_SERVERDIR} is not initialized" + return 1; + fi + + echo "Saving pkcs11.txt" + cp ${P_R_SERVERDIR}/pkcs11.txt ${P_R_SERVERDIR}/pkcs11.txt.sav + + # Disallow RSA in key exchange explicitly + setup_policy "disallow=rsa/ssl-key-exchange" ${P_R_SERVERDIR} + + start_selfserv # Launch the server + + VMIN="ssl3" + VMAX="tls1.2" + + # Try to connect to the server with a ciphersuite using RSA in key exchange + echo "tstclnt -4 -p ${PORT} -h ${HOSTADDR} -c d -V ${VMIN}:${VMAX} ${CLIENT_OPTIONS} \\" + echo " -f -d ${P_R_CLIENTDIR} $verbose -w nss < ${REQUEST_FILE}" + + rm ${TMP}/$HOST.tmp.$$ 2>/dev/null + RET_EXP=254 + ${PROFTOOL} ${BINDIR}/tstclnt -4 -p ${PORT} -h ${HOSTADDR} -c d -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 $RET_EXP "${testname}" \ + "produced a returncode of $RET, expected is $RET_EXP" + + cp ${P_R_SERVERDIR}/pkcs11.txt.sav ${P_R_SERVERDIR}/pkcs11.txt + + kill_selfserv + html "</TABLE><BR>" +} + ############################# is_revoked ############################### # local shell function to check if certificate is revoked ######################################################################## @@ -826,7 +938,7 @@ load_group_crl() { fi echo "================= Reloading ${eccomment}CRL for group $grpBegin - $grpEnd =============" - echo "tstclnt -p ${PORT} -h ${HOSTADDR} -f -d ${R_CLIENTDIR} $verbose \\" + echo "tstclnt -4 -p ${PORT} -h ${HOSTADDR} -f -d ${R_CLIENTDIR} $verbose \\" echo " -V ssl3:tls1.2 -w nss -n TestUser${UNREVOKED_CERT_GRP_1}${ecsuffix}" echo "Request:" echo "GET crl://${SERVERDIR}/root.crl_${grpBegin}-${grpEnd}${ecsuffix}" @@ -839,7 +951,7 @@ GET crl://${SERVERDIR}/root.crl_${grpBegin}-${grpEnd}${ecsuffix} _EOF_REQUEST_ - ${PROFTOOL} ${BINDIR}/tstclnt -p ${PORT} -h ${HOSTADDR} -f \ + ${PROFTOOL} ${BINDIR}/tstclnt -4 -p ${PORT} -h ${HOSTADDR} -f \ -d ${R_CLIENTDIR} $verbose -V ssl3:tls1.2 -w nss -n TestUser${UNREVOKED_CERT_GRP_1}${ecsuffix} \ >${OUTFILE_TMP} 2>&1 < ${REQF} @@ -876,7 +988,7 @@ _EOF_REQUEST_ ssl_crl_cache() { #verbose="-v" - html_head "Cache CRL SSL Client Tests $NORM_EXT $ECC_STRING" + html_head "Cache CRL SSL Client Tests $NORM_EXT" SSLAUTH_TMP=${TMP}/authin.tl.tmp SERV_ARG=-r_-r rm -f ${SSLAUTH_TMP} @@ -892,7 +1004,7 @@ ssl_crl_cache() while read ectype value sparam cparam testname do [ "$ectype" = "" ] && continue - if [ "$ectype" = "ECC" -a -n "$NSS_DISABLE_ECC" ] ; then + if [ "$ectype" = "ECC" ] ; then echo "$SCRIPTNAME: skipping $testname (ECC only)" elif [ "$ectype" = "SNI" ]; then continue @@ -930,10 +1042,10 @@ ssl_crl_cache() cparam=`echo $_cparam | sed -e 's;_; ;g' -e "s/TestUser/$USER_NICKNAME/g" ` echo "Server Args: $SERV_ARG" - echo "tstclnt -p ${PORT} -h ${HOSTADDR} -f -d ${R_CLIENTDIR} $verbose \\" + echo "tstclnt -4 -p ${PORT} -h ${HOSTADDR} -f -d ${R_CLIENTDIR} $verbose \\" echo " ${cparam} < ${REQUEST_FILE}" rm ${TMP}/$HOST.tmp.$$ 2>/dev/null - ${PROFTOOL} ${BINDIR}/tstclnt -p ${PORT} -h ${HOSTADDR} -f ${cparam} \ + ${PROFTOOL} ${BINDIR}/tstclnt -4 -p ${PORT} -h ${HOSTADDR} -f ${cparam} \ -d ${R_CLIENTDIR} $verbose < ${REQUEST_FILE} \ >${TMP}/$HOST.tmp.$$ 2>&1 ret=$? @@ -985,6 +1097,47 @@ ssl_crl_cache() html "</TABLE><BR>" } +############################ ssl_dtls ################################### +# local shell function to test tstclnt acting as client and server for DTLS +######################################################################### +ssl_dtls() +{ + #verbose="-v" + html_head "SSL DTLS $NORM_EXT - server $SERVER_MODE/client $CLIENT_MODE" + + testname="ssl_dtls" + value=0 + + if [ "$SERVER_MODE" = "fips" -o "$CLIENT_MODE" = "fips" ] ; then + echo "$SCRIPTNAME: skipping $testname (non-FIPS only)" + return 0 + fi + + echo "${testname}" + + echo "tstclnt -4 -p ${PORT} -h ${HOSTADDR} -f -d ${P_R_SERVERDIR} $verbose ${SERVER_OPTIONS} \\" + echo " -U -V tls1.1:tls1.2 -P server -Q < ${REQUEST_FILE} &" + + ${PROFTOOL} ${BINDIR}/tstclnt -4 -p ${PORT} -h ${HOSTADDR} -f ${SERVER_OPTIONS} \ + -d ${P_R_SERVERDIR} $verbose -U -V tls1.1:tls1.2 -P server -n ${HOSTADDR} -w nss < ${REQUEST_FILE} 2>&1 & + + PID=$! + + sleep 1 + + echo "tstclnt -4 -p ${PORT} -h ${HOSTADDR} -f -d ${P_R_CLIENTDIR} $verbose ${CLIENT_OPTIONS} \\" + echo " -U -V tls1.1:tls1.2 -P client -Q < ${REQUEST_FILE}" + ${PROFTOOL} ${BINDIR}/tstclnt -4 -p ${PORT} -h ${HOSTADDR} -f ${CLIENT_OPTIONS} \ + -d ${P_R_CLIENTDIR} $verbose -U -V tls1.1:tls1.2 -P client -Q < ${REQUEST_FILE} 2>&1 + ret=$? + html_msg $ret $value "${testname}" \ + "produced a returncode of $ret, expected is $value" + + kill ${PID} + + html "</TABLE><BR>" +} + ############################## ssl_cleanup ############################# # local shell function to finish this script (no exit since it might be @@ -1022,6 +1175,9 @@ ssl_run() "stress") ssl_stress ;; + "dtls") + ssl_dtls + ;; esac done } @@ -1143,7 +1299,9 @@ ssl_run_tests() case "${SSL_TEST}" in "policy") if [ "${TEST_MODE}" = "SHARED_DB" ] ; then - ssl_policy + ssl_policy_listsuites + ssl_policy_selfserv + ssl_policy fi ;; "crl") @@ -1166,8 +1324,8 @@ ssl_run_tests() ssl_set_fips server on ;; *) - echo "${SCRIPTNAME}: Error: Unknown server mode ${SERVER_MODE}" - continue + html_failed "${SCRIPTNAME}: Error: Unknown server mode ${SERVER_MODE}" + return 1 ;; esac @@ -1180,8 +1338,8 @@ ssl_run_tests() ssl_set_fips client on ;; *) - echo "${SCRIPTNAME}: Error: Unknown client mode ${CLIENT_MODE}" - continue + html_failed "${SCRIPTNAME}: Error: Unknown client mode ${CLIENT_MODE}" + return 1 ;; esac diff --git a/security/nss/tests/ssl/sslstress.txt b/security/nss/tests/ssl/sslstress.txt index e9defc502..a87eedad7 100644 --- a/security/nss/tests/ssl/sslstress.txt +++ b/security/nss/tests/ssl/sslstress.txt @@ -21,6 +21,7 @@ # add client auth versions here... # noECC 0 -r_-r -c_100_-C_c_-V_ssl3:ssl3_-N_-n_TestUser Stress SSL3 RC4 128 with MD5 (no reuse, client auth) + noECC 0 -r_-r -c_100_-C_c_-V_ssl3:ssl3_-N_-n_TestUser Stress SSL3 RC4 128 with MD5 (no reuse, client auth, no login) noECC 0 -r_-r -c_100_-C_c_-N_-n_TestUser Stress TLS RC4 128 with MD5 (no reuse, client auth) noECC 0 -r_-r_-u -V_ssl3:tls1.2_-c_100_-C_c_-n_TestUser_-u Stress TLS RC4 128 with MD5 (session ticket, client auth) noECC 0 -r_-r_-z -V_ssl3:tls1.2_-c_100_-C_c_-n_TestUser_-z Stress TLS RC4 128 with MD5 (compression, client auth) diff --git a/security/nss/tests/ssl_gtests/ssl_gtests.sh b/security/nss/tests/ssl_gtests/ssl_gtests.sh index ac39f212c..fd678bf59 100755 --- a/security/nss/tests/ssl_gtests/ssl_gtests.sh +++ b/security/nss/tests/ssl_gtests/ssl_gtests.sh @@ -21,16 +21,17 @@ # Generate input to certutil certscript() { + ca=n while [ $# -gt 0 ]; do case $1 in sign) echo 0 ;; kex) echo 2 ;; - ca) echo 5;echo 6 ;; + ca) echo 5;echo 6;ca=y ;; esac; shift done; echo 9 echo n - echo ${ca:-n} + echo $ca echo echo n } @@ -41,6 +42,7 @@ certscript() { make_cert() { name=$1 type=$2 + unset type_args trust sign case $type in dsa) type_args='-g 1024' ;; rsa) type_args='-g 1024' ;; @@ -49,8 +51,11 @@ make_cert() { p256) type_args='-q nistp256';type=ec ;; p384) type_args='-q secp384r1';type=ec ;; p521) type_args='-q secp521r1';type=ec ;; - rsa_ca) type_args='-g 1024';trust='CT,CT,CT';ca=y;type=rsa ;; + rsa_ca) type_args='-g 1024';trust='CT,CT,CT';type=rsa ;; rsa_chain) type_args='-g 1024';sign='-c rsa_ca';type=rsa;; + rsapss_ca) type_args='-g 1024 --pss';trust='CT,CT,CT';type=rsa ;; + rsapss_chain) type_args='-g 1024';sign='-c rsa_pss_ca';type=rsa;; + rsa_ca_rsapss_chain) type_args='-g 1024 --pss-sign';sign='-c rsa_ca';type=rsa;; ecdh_rsa) type_args='-q nistp256';sign='-c rsa_ca';type=ec ;; esac shift 2 @@ -87,6 +92,9 @@ ssl_gtest_certs() { make_cert ecdh_ecdsa p256 kex make_cert rsa_ca rsa_ca ca make_cert rsa_chain rsa_chain sign + make_cert rsa_pss_ca rsapss_ca ca + make_cert rsa_pss_chain rsapss_chain sign + make_cert rsa_ca_rsa_pss_chain rsa_ca_rsapss_chain sign make_cert ecdh_rsa ecdh_rsa kex make_cert dsa dsa sign } diff --git a/security/nss/tests/tools/TestOldAES128CA.p12 b/security/nss/tests/tools/TestOldAES128CA.p12 Binary files differnew file mode 100644 index 000000000..a05be8bde --- /dev/null +++ b/security/nss/tests/tools/TestOldAES128CA.p12 diff --git a/security/nss/tests/tools/TestOldCA.p12 b/security/nss/tests/tools/TestOldCA.p12 Binary files differnew file mode 100644 index 000000000..40d5671b9 --- /dev/null +++ b/security/nss/tests/tools/TestOldCA.p12 diff --git a/security/nss/tests/tools/tools.sh b/security/nss/tests/tools/tools.sh index 769bafa00..11be23e05 100644 --- a/security/nss/tests/tools/tools.sh +++ b/security/nss/tests/tools/tools.sh @@ -76,11 +76,7 @@ tools_init() fi SCRIPTNAME=tools.sh - if [ -z "$NSS_DISABLE_ECC" ] ; then - html_head "Tools Tests with ECC" - else - html_head "Tools Tests" - fi + html_head "Tools Tests" grep "SUCCESS: SMIME passed" $CERT_LOG_FILE >/dev/null || { Exit 15 "Fatal - S/MIME of cert.sh needs to pass first" @@ -106,6 +102,9 @@ tools_init() cp ${ALICEDIR}/* ${SIGNDIR}/ mkdir -p ${TOOLSDIR}/html cp ${QADIR}/tools/sign*.html ${TOOLSDIR}/html + mkdir -p ${TOOLSDIR}/data + cp ${QADIR}/tools/TestOldCA.p12 ${TOOLSDIR}/data + cp ${QADIR}/tools/TestOldAES128CA.p12 ${TOOLSDIR}/data cd ${TOOLSDIR} } @@ -397,30 +396,44 @@ tools_p12_export_list_import_with_default_ciphers() export_list_import "DEFAULT" "DEFAULT" - if [ -z "$NSS_DISABLE_ECC" ] ; then - echo "$SCRIPTNAME: Exporting Alice's email EC cert & key---------------" - echo "pk12util -o Alice-ec.p12 -n \"Alice-ec\" -d ${P_R_ALICEDIR} -k ${R_PWFILE} \\" - echo " -w ${R_PWFILE}" - ${BINDIR}/pk12util -o Alice-ec.p12 -n "Alice-ec" -d ${P_R_ALICEDIR} -k ${R_PWFILE} \ - -w ${R_PWFILE} 2>&1 - ret=$? - html_msg $ret 0 "Exporting Alice's email EC cert & key (pk12util -o)" - check_tmpfile - - echo "$SCRIPTNAME: Importing Alice's email EC cert & key --------------" - echo "pk12util -i Alice-ec.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -w ${R_PWFILE}" - ${BINDIR}/pk12util -i Alice-ec.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -w ${R_PWFILE} 2>&1 - ret=$? - html_msg $ret 0 "Importing Alice's email EC cert & key (pk12util -i)" - check_tmpfile - - echo "$SCRIPTNAME: Listing Alice's pk12 EC file -----------------" - echo "pk12util -l Alice-ec.p12 -w ${R_PWFILE}" - ${BINDIR}/pk12util -l Alice-ec.p12 -w ${R_PWFILE} 2>&1 - ret=$? - html_msg $ret 0 "Listing Alice's pk12 EC file (pk12util -l)" - check_tmpfile - fi + echo "$SCRIPTNAME: Exporting Alice's email EC cert & key---------------" + echo "pk12util -o Alice-ec.p12 -n \"Alice-ec\" -d ${P_R_ALICEDIR} -k ${R_PWFILE} \\" + echo " -w ${R_PWFILE}" + ${BINDIR}/pk12util -o Alice-ec.p12 -n "Alice-ec" -d ${P_R_ALICEDIR} -k ${R_PWFILE} \ + -w ${R_PWFILE} 2>&1 + ret=$? + html_msg $ret 0 "Exporting Alice's email EC cert & key (pk12util -o)" + check_tmpfile + + echo "$SCRIPTNAME: Importing Alice's email EC cert & key --------------" + echo "pk12util -i Alice-ec.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -w ${R_PWFILE}" + ${BINDIR}/pk12util -i Alice-ec.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -w ${R_PWFILE} 2>&1 + ret=$? + html_msg $ret 0 "Importing Alice's email EC cert & key (pk12util -i)" + check_tmpfile + + echo "$SCRIPTNAME: Listing Alice's pk12 EC file -----------------" + echo "pk12util -l Alice-ec.p12 -w ${R_PWFILE}" + ${BINDIR}/pk12util -l Alice-ec.p12 -w ${R_PWFILE} 2>&1 + ret=$? + html_msg $ret 0 "Listing Alice's pk12 EC file (pk12util -l)" + check_tmpfile +} + +tools_p12_import_old_files() +{ + echo "$SCRIPTNAME: Importing PKCS#12 files created with older NSS --------------" + echo "pk12util -i TestOldCA.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -w ${R_PWFILE}" + ${BINDIR}/pk12util -i ${TOOLSDIR}/data/TestOldCA.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -w ${R_PWFILE} 2>&1 + ret=$? + html_msg $ret 0 "Importing PKCS#12 file created with NSS 3.21 (PBES2 with BMPString password)" + check_tmpfile + + echo "pk12util -i TestOldAES128CA.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -w ${R_PWFILE}" + ${BINDIR}/pk12util -i ${TOOLSDIR}/data/TestOldAES128CA.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -w ${R_PWFILE} 2>&1 + ret=$? + html_msg $ret 0 "Importing PKCS#12 file created with NSS 3.29.5 (PBES2 with incorrect AES-128-CBC algorithm ID)" + check_tmpfile } ############################## tools_p12 ############################### @@ -434,6 +447,7 @@ tools_p12() tools_p12_export_list_import_all_pkcs12v2pbe_ciphers tools_p12_export_with_none_ciphers tools_p12_export_with_invalid_ciphers + tools_p12_import_old_files } ############################## tools_sign ############################## @@ -503,6 +517,21 @@ SIGNSCRIPT } +tools_modutil() +{ + echo "$SCRIPTNAME: Test if DB created by modutil -create is initialized" + mkdir -p ${R_TOOLSDIR}/moddir + # copied from modu function in cert.sh + # echo is used to press Enter expected by modutil + echo | ${BINDIR}/modutil -create -dbdir "${R_TOOLSDIR}/moddir" 2>&1 + ret=$? + ${BINDIR}/certutil -S -s 'CN=TestUser' -d "${TOOLSDIR}/moddir" -n TestUser \ + -x -t ',,' -z "${R_NOISE_FILE}" + ret=$? + html_msg $ret 0 "Test if DB created by modutil -create is initialized" + check_tmpfile +} + ############################## tools_cleanup ########################### # local shell function to finish this script (no exit since it might be # sourced) @@ -519,6 +548,7 @@ tools_cleanup() tools_init tools_p12 tools_sign +tools_modutil tools_cleanup |