Update NSS to 3.36.4-RTM

This commit is contained in:
JustOff 2018-06-09 15:11:22 +03:00 committed by Roy Tam
commit fe96962962
148 changed files with 5550 additions and 5825 deletions

1
security/nss/TAG-INFO Normal file
View file

@ -0,0 +1 @@
NSS_3_36_4_RTM

View file

@ -1,8 +0,0 @@
Functions changes summary: 1 Removed, 0 Changed, 0 Added function
Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
1 Removed function:
'function void PR_EXPERIMENTAL_ONLY_IN_4_17_GetOverlappedIOHandle(void**)' {PR_EXPERIMENTAL_ONLY_IN_4_17_GetOverlappedIOHandle}

View file

@ -1,3 +1,28 @@
Functions changes summary: 0 Removed, 0 Changed (5 filtered out), 0 Added function
Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
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'

View file

@ -1 +1 @@
NSS_3_34_BRANCH
NSS_3_35_BRANCH

View file

@ -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
@ -268,10 +268,49 @@ check_abi()
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
if [ $? -ne 0 ]; then
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 "FAILED to run abidiff {$PREVDIST , $NEWDIST} for $SO, or failed writing to ${HGDIR}/nss/automation/abi-check/new-report-$SO.txt"
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

View file

@ -1,4 +1,4 @@
4.18
4.19
# The first line of this file must contain the human readable NSPR
# version number, which is the minimum required version of NSPR

View file

@ -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

View file

@ -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));

View file

@ -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)

View file

@ -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));

View file

@ -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));

View file

@ -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

View file

@ -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));

View file

@ -5,11 +5,11 @@ MAINTAINER Franziskus Kiefer <franziskuskiefer@gmail.com>
# the original F* formula with Daniel Fabian
# Pinned versions of HACL* (F* and KreMLin are pinned as submodules)
ENV haclrepo https://github.com/mitls/hacl-star.git
ENV haclrepo https://github.com/franziskuskiefer/hacl-star.git
# Define versions of dependencies
ENV opamv 4.04.2
ENV haclversion dcd48329d535727dbde93877b124c5ec4a7a2b20
ENV haclversion 668d6cf274c33bbe2e951e3a84b73f2b6442a51f
# Install required packages and set versions
ADD setup.sh /tmp/setup.sh

View file

@ -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"]

View file

@ -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

View file

@ -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 https://releases.llvm.org/4.0.0/clang+llvm-4.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz
curl -LO https://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"

View file

@ -30,6 +30,11 @@ const HACL_GEN_IMAGE = {
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) || " +
@ -72,7 +77,8 @@ queue.filter(task => {
}
}
if (task.tests == "fips" && task.platform == "mac") {
if (task.tests == "fips" &&
(task.platform == "mac" || task.platform == "aarch64")) {
return false;
}
@ -88,7 +94,7 @@ queue.filter(task => {
}
}
// 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")) {
@ -187,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",
@ -266,6 +272,18 @@ export default async function main() {
}, 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"});
}
@ -418,12 +436,12 @@ 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, {
@ -894,6 +912,13 @@ function scheduleTests(task_build, task_cert, test_base) {
name: "Cipher tests", symbol: "NoAVX", tests: "cipher",
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"
}));
@ -946,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",
@ -958,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: {
@ -991,5 +1028,69 @@ async function scheduleTools() {
]
}));
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();
}

View file

@ -30,7 +30,7 @@ export async function buildTask({name, path}) {
let ns = `docker.images.v1.${process.env.TC_PROJECT}.${name}.hash.${hash}`;
return {
name: "Image Builder",
name: `Image Builder (${name})`,
image: "nssdev/image_builder:0.1.5",
routes: ["index." + ns],
env: {

View file

@ -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;
}

View file

@ -51,7 +51,7 @@ function parseOptions(opts) {
}
// Parse tools.
let allTools = ["clang-format", "scan-build", "hacl"];
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));
});
}

View file

@ -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

View file

@ -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"

View file

@ -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

View file

@ -91,6 +91,7 @@ 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) ;;

View file

@ -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.

View file

@ -1,48 +0,0 @@
#! 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 ../platlibs.mk
#######################################################################
# (5) Execute "global" rules. (OPTIONAL) #
#######################################################################
include $(CORE_DEPTH)/coreconf/rules.mk
#######################################################################
# (6) Execute "component" rules. (OPTIONAL) #
#######################################################################
#######################################################################
# (7) Execute "local" rules. (OPTIONAL). #
#######################################################################
include ../platrules.mk

View file

@ -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>

View file

@ -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>

File diff suppressed because it is too large Load diff

View file

@ -1,33 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
{
'includes': [
'../../coreconf/config.gypi',
'../../cmd/platlibs.gypi'
],
'targets': [
{
'target_name': 'certcgi',
'type': 'executable',
'sources': [
'certcgi.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
}
}

View file

@ -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>&nbsp;&nbsp;</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>

View file

@ -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:&nbsp; <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:&nbsp; <input type="text" size="15" maxlength="17" name="notBefore">
<DD>Not After:&nbsp;&nbsp;&nbsp; <input type="text" size="15" maxlength="17" name="notAfter">
<DD>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<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>

View file

@ -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

View file

@ -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>

View file

@ -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>

View file

@ -1371,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;

View file

@ -36,7 +36,6 @@ NSS_SRCDIRS = \
addbuiltin \
atob \
btoa \
certcgi \
certutil \
chktest \
crlutil \

View file

@ -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;

View file

@ -105,6 +105,7 @@
'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,
@ -431,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',

View file

@ -10,8 +10,10 @@
#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); }
@ -37,6 +39,12 @@ struct ScopedDelete {
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>
@ -68,6 +76,8 @@ SCOPED(PK11URI);
SCOPED(PLArenaPool);
SCOPED(PK11Context);
SCOPED(PK11GenericObject);
SCOPED(SSLResumptionTokenInfo);
SCOPED(SEC_PKCS12DecoderContext);
#undef SCOPED

View file

@ -47,6 +47,7 @@ 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;

View file

@ -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>

View file

@ -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',
]
}
],

View file

@ -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 \

View file

@ -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

View file

@ -1,6 +1,70 @@
{
"DisabledTests": {
"### These tests break whenever we rev versions, so just leave them here for easy uncommenting":"",
"SendWarningAlerts-Pass":"BoringSSL updated",
"SendBogusAlertType":"BoringSSL updated",
"SendEmptyRecords-Pass":"BoringSSL updated",
"ExtraCompressionMethods-TLS12":"BoringSSL updated",
"SendSNIWarningAlert":"BoringSSL updated",
"NoNullCompression-TLS12":"BoringSSL updated",
"InvalidCompressionMethod":"BoringSSL updated",
"SupportTicketsWithSessionID":"BoringSSL updated",
"NoSharedCipher":"BoringSSL updated",
"ServerHelloBogusCipher":"BoringSSL updated",
"ClientHelloVersionTooHigh":"BoringSSL updated",
"ServerAuth-SignatureType":"BoringSSL updated",
"ECDSACurveMismatch-Verify-TLS12":"BoringSSL updated",
"UnknownExtension-Client":"BoringSSL updated",
"UnofferedExtension-Client":"BoringSSL updated",
"SendClientVersion-RSA":"BoringSSL updated",
"SupportedCurves-ServerHello-TLS12":"BoringSSL updated",
"Basic-Client*Sync":"BoringSSL updated",
"Resume-Client-CipherMismatch":"BoringSSL updated",
"ClientAuth-SignatureType":"BoringSSL updated",
"Agree-Digest-Default":"BoringSSL updated",
"Basic-Server*Sync":"BoringSSL updated",
"ClientAuth-*-Sync":"BoringSSL updated",
"RSA-PSS-Default*":"BoringSSL updated",
"Renegotiate-Server-NoExt*":"BoringSSL updated",
"Downgrade-TLS12*":"BoringSSL updated",
"MaxCBCPadding":"BoringSSL updated",
"UnknownCipher":"BoringSSL updated",
"LargeMessage":"BoringSSL updated",
"NoCommonCurves":"BoringSSL updated",
"UnknownCurve":"BoringSSL updated",
"SessionTicketsDisabled*":"BoringSSL updated",
"BadFinished-*":"BoringSSL updated",
"ServerSkipCertificateVerify":"BoringSSL updated",
"*VersionTolerance":"BoringSSL updated",
"ConflictingVersionNegotiation*":"BoringSSL updated",
"Ed25519DefaultDisable*":"BoringSSL updated",
"*SHA1-Fallback*":"BoringSSL updated",
"ExtendedMasterSecret-NoToNo*":"BoringSSL updated",
"ServerNameExtensionClientMissing*":"BoringSSL updated",
"NoClientCertificate*":"BoringSSL updated",
"ServerCipherFilter*":"BoringSSL updated",
"*FallbackSCSV*":"BoringSSL updated",
"LooseInitialRecordVersion*":"BoringSSL updated",
"ALPNClient*":"BoringSSL updated",
"MinimumVersion*":"BoringSSL updated",
"VersionNegotiation*":"BoringSSL updated",
"*Client-ClientAuth*":"BoringSSL updated",
"*Server-ClientAuth*":"BoringSSL updated",
"NoExtendedMasterSecret*":"BoringSSL updated",
"PointFormat*":"BoringSSL updated",
"*Sync-SplitHandshakeRecords*":"BoringSSL updated",
"*Sync-PackHandshakeFlight*":"BoringSSL updated",
"TicketSessionIDLength*":"BoringSSL updated",
"*LargeRecord*":"BoringSSL updated",
"WrongMessageType-NewSessionTicket":"BoringSSL updated",
"WrongMessageType*Certificate*":"BoringSSL updated",
"WrongMessageType*Client*":"BoringSSL updated",
"WrongMessageType*Server*":"BoringSSL updated",
"WrongMessageType*DTLS":"BoringSSL updated",
"GarbageCertificate*":"BoringSSL updated",
"EmptyExtensions*":"BoringSSL updated",
"*OmitExtensions*":"BoringSSL updated",
"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)",

View file

@ -105,4 +105,4 @@ static const BloomFilterConfig kBloomFilterConfigurations[] = {
INSTANTIATE_TEST_CASE_P(BloomFilterConfigurations, BloomFilterTest,
::testing::ValuesIn(kBloomFilterConfigurations));
} // namespace nspr_test
} // namespace nss_test

View file

@ -332,10 +332,6 @@ 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;

View file

@ -50,7 +50,6 @@ 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);

View file

@ -94,7 +94,7 @@ class TlsZeroRttReplayTest : public TlsConnectTls13 {
// Now run a true 0-RTT handshake, but capture the first packet.
auto first_packet = std::make_shared<SaveFirstPacket>();
client_->SetPacketFilter(first_packet);
client_->SetFilter(first_packet);
client_->Set0RttEnabled(true);
server_->Set0RttEnabled(true);
ExpectResumption(RESUME_TICKET);
@ -116,8 +116,7 @@ class TlsZeroRttReplayTest : public TlsConnectTls13 {
// Capture the early_data extension, which should not appear.
auto early_data_ext =
std::make_shared<TlsExtensionCapture>(ssl_tls13_early_data_xtn);
server_->SetPacketFilter(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
@ -405,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();
@ -422,27 +424,28 @@ TEST_P(TlsConnectTls13, TestTls13ZeroRttDowngradeEarlyData) {
// 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(); // Send ClientHello.
PRInt32 rv =
PR_Write(client_->ssl_fd(), k0RttData, k0RttDataLen); // 0-RTT write.
EXPECT_EQ(k0RttDataLen, rv);
client_->Handshake();
server_->Handshake();
ASSERT_TRUE_WAIT(
(client_->error_code() == SSL_ERROR_DOWNGRADE_WITH_EARLY_DATA), 2000);
// 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,
@ -455,10 +458,13 @@ 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);
@ -510,8 +516,10 @@ 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);
@ -521,6 +529,8 @@ TEST_P(TlsConnectTls13, ReceiveTooMuchEarlyData) {
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));
@ -534,21 +544,31 @@ 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());
}
}
@ -583,7 +603,7 @@ TEST_P(TlsConnectTls13, ZeroRttOrdering) {
// Now, coalesce the next three things from the client: early data, second
// flight and 1-RTT data.
auto coalesce = std::make_shared<PacketCoalesceFilter>();
client_->SetPacketFilter(coalesce);
client_->SetFilter(coalesce);
// Send (and hold) early data.
static const std::vector<uint8_t> early_data = {3, 2, 1};

View file

@ -160,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();

View file

@ -95,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;
@ -114,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();
@ -127,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();
@ -146,21 +143,20 @@ 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()
: TlsHandshakeFilter({kTlsHandshakeCertificateRequest}) {}
TlsZeroCertificateRequestSigAlgsFilter(const std::shared_ptr<TlsAgent>& agent)
: TlsHandshakeFilter(agent, {kTlsHandshakeCertificateRequest}) {}
virtual PacketFilter::Action FilterHandshake(
const TlsHandshakeFilter::HandshakeHeader& header,
const DataBuffer& input, DataBuffer* output) {
@ -205,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);
@ -358,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);
@ -368,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);
@ -387,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) {}
@ -411,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.
@ -436,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_;
@ -461,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) {}
@ -497,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_;
};
@ -512,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();
}
@ -544,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);
@ -560,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
},
@ -572,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);
@ -606,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());
@ -616,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
@ -632,12 +645,12 @@ TEST_P(TlsConnectTls13, AuthCompleteDelayed) {
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
@ -645,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 = {
@ -767,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();
@ -796,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,
@ -805,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,
@ -842,4 +892,4 @@ INSTANTIATE_TEST_CASE_P(
TlsAgent::kServerEcdsa384),
::testing::Values(ssl_auth_ecdsa),
::testing::Values(ssl_sig_ecdsa_sha1)));
}
} // namespace nss_test

View file

@ -180,9 +180,8 @@ TEST_P(TlsConnectGenericPre13, OcspMangled) {
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);
@ -192,8 +191,7 @@ TEST_P(TlsConnectGeneric, OcspSuccess) {
EnsureTlsSetup();
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,
@ -245,4 +243,4 @@ TEST_P(TlsConnectGeneric, OcspHugeSuccess) {
Connect();
}
} // namespace nspr_test
} // namespace nss_test

View file

@ -74,12 +74,12 @@ class TlsCipherSuiteTestBase : public TlsConnectTestBase {
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;
@ -313,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
@ -466,4 +466,4 @@ static const SecStatusParams kSecStatusTestValuesArr[] = {
INSTANTIATE_TEST_CASE_P(TestSecurityStatus, SecurityStatusTest,
::testing::ValuesIn(kSecStatusTestValuesArr));
} // namespace nspr_test
} // namespace nss_test

View file

@ -150,9 +150,8 @@ TEST_F(TlsConnectStreamTls13, CustomExtensionWriterDisable) {
client_->ssl_fd(), ssl_signed_cert_timestamp_xtn, NoopExtensionWriter,
nullptr, NoopExtensionHandler, nullptr);
EXPECT_EQ(SECSuccess, rv);
auto capture =
std::make_shared<TlsExtensionCapture>(ssl_signed_cert_timestamp_xtn);
client_->SetPacketFilter(capture);
auto capture = MakeTlsFilter<TlsExtensionCapture>(
client_, ssl_signed_cert_timestamp_xtn);
Connect();
// So nothing will be sent.
@ -204,9 +203,8 @@ TEST_F(TlsConnectStreamTls13, CustomExtensionOverride) {
EXPECT_EQ(SECSuccess, rv);
// Capture it to see what we got.
auto capture =
std::make_shared<TlsExtensionCapture>(ssl_signed_cert_timestamp_xtn);
client_->SetPacketFilter(capture);
auto capture = MakeTlsFilter<TlsExtensionCapture>(
client_, ssl_signed_cert_timestamp_xtn);
ConnectExpectAlert(server_, kTlsAlertDecodeError);
@ -246,8 +244,7 @@ TEST_F(TlsConnectStreamTls13, CustomExtensionClientToServer) {
EXPECT_EQ(SECSuccess, rv);
// Capture it to see what we got.
auto capture = std::make_shared<TlsExtensionCapture>(extension_code);
client_->SetPacketFilter(capture);
auto capture = MakeTlsFilter<TlsExtensionCapture>(client_, extension_code);
// Handle it so that the handshake completes.
rv = SSL_InstallExtensionHooks(server_->ssl_fd(), extension_code,
@ -290,9 +287,8 @@ TEST_F(TlsConnectStreamTls13, CustomExtensionServerToClientSH) {
EXPECT_EQ(SECSuccess, rv);
// Capture the extension from the ServerHello only and check it.
auto capture = std::make_shared<TlsExtensionCapture>(extension_code);
auto capture = MakeTlsFilter<TlsExtensionCapture>(server_, extension_code);
capture->SetHandshakeTypes({kTlsHandshakeServerHello});
server_->SetPacketFilter(capture);
Connect();
@ -329,9 +325,9 @@ TEST_F(TlsConnectStreamTls13, CustomExtensionServerToClientEE) {
EXPECT_EQ(SECSuccess, rv);
// Capture the extension from the EncryptedExtensions only and check it.
auto capture = std::make_shared<TlsExtensionCapture>(extension_code);
auto capture = MakeTlsFilter<TlsExtensionCapture>(server_, extension_code);
capture->SetHandshakeTypes({kTlsHandshakeEncryptedExtensions});
server_->SetTlsRecordFilter(capture);
capture->EnableDecryption();
Connect();
@ -350,8 +346,7 @@ TEST_F(TlsConnectStreamTls13, CustomExtensionUnsolicitedServer) {
EXPECT_EQ(SECSuccess, rv);
// Capture it to see what we got.
auto capture = std::make_shared<TlsExtensionCapture>(extension_code);
server_->SetPacketFilter(capture);
auto capture = MakeTlsFilter<TlsExtensionCapture>(server_, extension_code);
client_->ExpectSendAlert(kTlsAlertUnsupportedExtension);
server_->ExpectSendAlert(kTlsAlertBadRecordMac);
@ -500,4 +495,4 @@ TEST_F(TlsConnectStreamTls13, CustomExtensionOverrunBuffer) {
client_->CheckErrorCode(SEC_ERROR_APPLICATION_CALLBACK_ERROR);
}
} // namespace "nss_test"
} // namespace nss_test

View file

@ -50,19 +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);
server_->SetPacketFilter(std::make_shared<AfterRecordN>(
MakeTlsFilter<AfterRecordN>(
server_, client_,
0, // ServerHello.
[this]() { SSLInt_DamageServerHsTrafficSecret(client_->ssl_fd()); }));
[this]() { SSLInt_DamageServerHsTrafficSecret(client_->ssl_fd()); });
ConnectExpectAlert(client_, kTlsAlertDecryptError);
client_->CheckErrorCode(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
}
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);
@ -71,9 +71,9 @@ 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();
ConnectExpectAlert(client_, kTlsAlertDecryptError);
client_->CheckErrorCode(SEC_ERROR_BAD_SIGNATURE);
}
@ -82,9 +82,9 @@ TEST_P(TlsConnectGeneric, DamageClientSignature) {
EnsureTlsSetup();
client_->SetupClientAuth();
server_->RequestClientAuth(true);
auto filter =
std::make_shared<TlsLastByteDamager>(kTlsHandshakeCertificateVerify);
client_->SetTlsRecordFilter(filter);
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.
@ -100,4 +100,4 @@ TEST_P(TlsConnectGeneric, DamageClientSignature) {
server_->CheckErrorCode(SEC_ERROR_BAD_SIGNATURE);
}
} // namespace nspr_test
} // namespace nss_test

View file

@ -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();
@ -61,12 +61,12 @@ TEST_P(TlsConnectGeneric, ConnectFfdheClient) {
EnableOnlyDheCiphers();
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();
@ -103,8 +103,8 @@ TEST_P(TlsConnectGenericPre13, ConnectFfdheServer) {
class TlsDheServerKeyExchangeDamager : public TlsHandshakeFilter {
public:
TlsDheServerKeyExchangeDamager()
: TlsHandshakeFilter({kTlsHandshakeServerKeyExchange}) {}
TlsDheServerKeyExchangeDamager(const std::shared_ptr<TlsAgent>& agent)
: TlsHandshakeFilter(agent, {kTlsHandshakeServerKeyExchange}) {}
virtual PacketFilter::Action FilterHandshake(
const TlsHandshakeFilter::HandshakeHeader& header,
const DataBuffer& input, DataBuffer* output) {
@ -122,7 +122,7 @@ class TlsDheServerKeyExchangeDamager : public TlsHandshakeFilter {
TEST_P(TlsConnectGenericPre13, DamageServerKeyShare) {
EnableOnlyDheCiphers();
client_->SetOption(SSL_REQUIRE_DH_NAMED_GROUPS, PR_TRUE);
server_->SetPacketFilter(std::make_shared<TlsDheServerKeyExchangeDamager>());
MakeTlsFilter<TlsDheServerKeyExchangeDamager>(server_);
ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
@ -141,8 +141,9 @@ class TlsDheSkeChangeY : public TlsHandshakeFilter {
kYZeroPad
};
TlsDheSkeChangeY(uint8_t handshake_type, ChangeYTo change)
: TlsHandshakeFilter({handshake_type}), 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,
@ -207,8 +208,9 @@ class TlsDheSkeChangeY : public TlsHandshakeFilter {
class TlsDheSkeChangeYServer : public TlsDheSkeChangeY {
public:
TlsDheSkeChangeYServer(ChangeYTo change, bool modify)
: TlsDheSkeChangeY(kTlsHandshakeServerKeyExchange, change),
TlsDheSkeChangeYServer(const std::shared_ptr<TlsAgent>& agent,
ChangeYTo change, bool modify)
: TlsDheSkeChangeY(agent, kTlsHandshakeServerKeyExchange, change),
modify_(modify),
p_() {}
@ -245,9 +247,9 @@ 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(kTlsHandshakeClientKeyExchange, change),
: TlsDheSkeChangeY(agent, kTlsHandshakeClientKeyExchange, change),
server_filter_(server_filter) {}
protected:
@ -282,8 +284,7 @@ TEST_P(TlsDamageDHYTest, DamageServerY) {
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);
@ -312,14 +313,12 @@ TEST_P(TlsDamageDHYTest, DamageClientY) {
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);
@ -358,7 +357,9 @@ INSTANTIATE_TEST_CASE_P(
class TlsDheSkeMakePEven : public TlsHandshakeFilter {
public:
TlsDheSkeMakePEven() : TlsHandshakeFilter({kTlsHandshakeServerKeyExchange}) {}
TlsDheSkeMakePEven(const std::shared_ptr<TlsAgent>& agent)
: TlsHandshakeFilter(agent, {kTlsHandshakeServerKeyExchange}) {}
virtual PacketFilter::Action FilterHandshake(
const TlsHandshakeFilter::HandshakeHeader& header,
const DataBuffer& input, DataBuffer* output) {
@ -379,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);
@ -389,7 +390,9 @@ TEST_P(TlsConnectGenericPre13, MakeDhePEven) {
class TlsDheSkeZeroPadP : public TlsHandshakeFilter {
public:
TlsDheSkeZeroPadP() : TlsHandshakeFilter({kTlsHandshakeServerKeyExchange}) {}
TlsDheSkeZeroPadP(const std::shared_ptr<TlsAgent>& agent)
: TlsHandshakeFilter(agent, {kTlsHandshakeServerKeyExchange}) {}
virtual PacketFilter::Action FilterHandshake(
const TlsHandshakeFilter::HandshakeHeader& header,
const DataBuffer& input, DataBuffer* output) {
@ -407,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);
@ -455,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.
@ -499,8 +502,8 @@ 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) {
@ -524,29 +527,28 @@ TEST_P(TlsConnectTls13, ResumeFfdhe) {
Connect();
SendReceive(); // Need to read so that we absorb the session ticket.
CheckKeys(ssl_kea_dh, ssl_grp_ffdhe_2048, ssl_auth_rsa_sign,
ssl_sig_rsa_pss_sha256);
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_rsa_pss_sha256);
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)
: TlsHandshakeFilter({kTlsHandshakeServerKeyExchange}),
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) {}
@ -595,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);

View file

@ -22,13 +22,13 @@ extern "C" {
namespace nss_test {
TEST_P(TlsConnectDatagramPre13, DropClientFirstFlightOnce) {
client_->SetPacketFilter(std::make_shared<SelectiveDropFilter>(0x1));
client_->SetFilter(std::make_shared<SelectiveDropFilter>(0x1));
Connect();
SendReceive();
}
TEST_P(TlsConnectDatagramPre13, DropServerFirstFlightOnce) {
server_->SetPacketFilter(std::make_shared<SelectiveDropFilter>(0x1));
server_->SetFilter(std::make_shared<SelectiveDropFilter>(0x1));
Connect();
SendReceive();
}
@ -37,32 +37,32 @@ TEST_P(TlsConnectDatagramPre13, DropServerFirstFlightOnce) {
// 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(TlsConnectDatagramPre13, DropAllFirstTransmissions) {
client_->SetPacketFilter(std::make_shared<SelectiveDropFilter>(0x15));
server_->SetPacketFilter(std::make_shared<SelectiveDropFilter>(0x5));
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(TlsConnectDatagramPre13, DropServerFirstFlightThrice) {
server_->SetPacketFilter(std::make_shared<SelectiveDropFilter>(0x7));
server_->SetFilter(std::make_shared<SelectiveDropFilter>(0x7));
Connect();
}
// This drops the client's second flight once
TEST_P(TlsConnectDatagramPre13, DropClientSecondFlightOnce) {
client_->SetPacketFilter(std::make_shared<SelectiveDropFilter>(0x2));
client_->SetFilter(std::make_shared<SelectiveDropFilter>(0x2));
Connect();
}
// This drops the client's second flight three times.
TEST_P(TlsConnectDatagramPre13, DropClientSecondFlightThrice) {
client_->SetPacketFilter(std::make_shared<SelectiveDropFilter>(0xe));
client_->SetFilter(std::make_shared<SelectiveDropFilter>(0xe));
Connect();
}
// This drops the server's second flight three times.
TEST_P(TlsConnectDatagramPre13, DropServerSecondFlightThrice) {
server_->SetPacketFilter(std::make_shared<SelectiveDropFilter>(0xe));
server_->SetFilter(std::make_shared<SelectiveDropFilter>(0xe));
Connect();
}
@ -74,7 +74,7 @@ class TlsDropDatagram13 : public TlsConnectDatagram13 {
expected_client_acks_(0),
expected_server_acks_(1) {}
void SetUp() {
void SetUp() override {
TlsConnectDatagram13::SetUp();
ConfigureSessionCache(RESUME_NONE, RESUME_NONE);
SetFilters();
@ -82,12 +82,8 @@ class TlsDropDatagram13 : public TlsConnectDatagram13 {
void SetFilters() {
EnsureTlsSetup();
client_->SetPacketFilter(client_filters_.chain_);
client_filters_.ack_->SetAgent(client_.get());
client_filters_.ack_->EnableDecryption();
server_->SetPacketFilter(server_filters_.chain_);
server_filters_.ack_->SetAgent(server_.get());
server_filters_.ack_->EnableDecryption();
client_filters_.Init(client_);
server_filters_.Init(server_);
}
void HandshakeAndAck(const std::shared_ptr<TlsAgent>& agent) {
@ -119,11 +115,17 @@ class TlsDropDatagram13 : public TlsConnectDatagram13 {
class DropAckChain {
public:
DropAckChain()
: records_(std::make_shared<TlsRecordRecorder>()),
ack_(std::make_shared<TlsRecordRecorder>(content_ack)),
drop_(std::make_shared<SelectiveRecordDropFilter>(0, false)),
chain_(std::make_shared<ChainedPacketFilter>(
ChainedPacketFilterInit({records_, ack_, drop_}))) {}
: 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); }
@ -227,7 +229,7 @@ TEST_F(TlsDropDatagram13, DropServerSecondRecordOnce) {
HandshakeAndAck(client_);
expected_client_acks_ = 1;
CheckedHandshakeSendReceive();
CheckAcks(client_filters_, 0, {0});
CheckAcks(client_filters_, 0, {0}); // ServerHello
CheckAcks(server_filters_, 0, {0x0002000000000000ULL});
}
@ -257,7 +259,7 @@ TEST_F(TlsDropDatagram13, DropServerAckOnce) {
CheckPostHandshake();
// There should be two copies of the finished ACK
CheckAcks(server_filters_, 0, {0x0002000000000000ULL});
CheckAcks(server_filters_, 0, {0x0002000000000000ULL});
CheckAcks(server_filters_, 1, {0x0002000000000000ULL});
}
// Drop the client certificate verify.
@ -276,10 +278,9 @@ TEST_F(TlsDropDatagram13, DropClientCertVerify) {
// 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)
);
{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.
@ -303,10 +304,9 @@ TEST_F(TlsDropDatagram13, DropFirstHalfOfServerCertificate) {
EXPECT_EQ(ct1_size, server_filters_.record(0).buffer.len());
CheckedHandshakeSendReceive();
CheckAcks(client_filters_, 0,
{0, // SH
0x0002000000000000ULL, // EE
0x0002000000000002ULL} // CT2
);
{0, // SH
0x0002000000000000ULL, // EE
0x0002000000000002ULL}); // CT2
CheckAcks(server_filters_, 0, {0x0002000000000000ULL});
}
@ -540,7 +540,10 @@ TEST_F(TlsDropDatagram13, NoDropsDuringZeroRtt) {
ExpectEarlyDataAccepted(true);
CheckConnected();
SendReceive();
CheckAcks(server_filters_, 0, {0x0002000000000000ULL});
EXPECT_EQ(0U, client_filters_.ack_->count());
CheckAcks(server_filters_, 0,
{0x0001000000000001ULL, // EOED
0x0002000000000000ULL}); // Finished
}
TEST_F(TlsDropDatagram13, DropEEDuringZeroRtt) {
@ -558,7 +561,9 @@ TEST_F(TlsDropDatagram13, DropEEDuringZeroRtt) {
CheckConnected();
SendReceive();
CheckAcks(client_filters_, 0, {0});
CheckAcks(server_filters_, 0, {0x0002000000000000ULL});
CheckAcks(server_filters_, 0,
{0x0001000000000002ULL, // EOED
0x0002000000000000ULL}); // Finished
}
class TlsReorderDatagram13 : public TlsDropDatagram13 {
@ -688,6 +693,7 @@ TEST_F(TlsDropDatagram13, SendOutOfOrderHsNonsenseWithHandshakeKey) {
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});
}
@ -746,7 +752,9 @@ TEST_F(TlsReorderDatagram13, DataAfterEOEDDuringZeroRtt) {
ReSend(TlsAgent::CLIENT, std::vector<size_t>({1, 0, 2}));
server_->Handshake();
CheckConnected();
CheckAcks(server_filters_, 0, {0x0002000000000000ULL});
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);
@ -783,7 +791,9 @@ TEST_F(TlsReorderDatagram13, DataAfterFinDuringZeroRtt) {
ReSend(TlsAgent::CLIENT, std::vector<size_t>({1, 2, 0}));
server_->Handshake();
CheckConnected();
CheckAcks(server_filters_, 0, {0x0002000000000000ULL});
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);

View file

@ -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,13 +187,13 @@ 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()
: TlsHandshakeFilter({kTlsHandshakeServerKeyExchange}),
TlsKeyExchangeGroupCapture(const std::shared_ptr<TlsAgent> &agent)
: TlsHandshakeFilter(agent, {kTlsHandshakeServerKeyExchange}),
group_(ssl_grp_none) {}
SSLNamedGroup group() const { return group_; }
@ -221,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);
@ -236,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);
@ -276,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.
@ -284,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) {
@ -318,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
@ -337,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);
}
@ -357,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);
}
@ -379,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);
}
@ -401,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);
}
@ -423,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);
}
@ -445,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);
}
@ -507,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);
@ -516,7 +512,8 @@ TEST_P(TlsKeyExchangeTest13, MultipleClientShares) {
// Replace the point in the client key exchange message with an empty one
class ECCClientKEXFilter : public TlsHandshakeFilter {
public:
ECCClientKEXFilter() : TlsHandshakeFilter({kTlsHandshakeClientKeyExchange}) {}
ECCClientKEXFilter(const std::shared_ptr<TlsAgent> &client)
: TlsHandshakeFilter(client, {kTlsHandshakeClientKeyExchange}) {}
protected:
virtual PacketFilter::Action FilterHandshake(const HandshakeHeader &header,
@ -532,7 +529,8 @@ class ECCClientKEXFilter : public TlsHandshakeFilter {
// Replace the point in the server key exchange message with an empty one
class ECCServerKEXFilter : public TlsHandshakeFilter {
public:
ECCServerKEXFilter() : TlsHandshakeFilter({kTlsHandshakeServerKeyExchange}) {}
ECCServerKEXFilter(const std::shared_ptr<TlsAgent> &server)
: TlsHandshakeFilter(server, {kTlsHandshakeServerKeyExchange}) {}
protected:
virtual PacketFilter::Action FilterHandshake(const HandshakeHeader &header,
@ -550,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);
}

View file

@ -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) {
@ -63,8 +65,11 @@ class TlsExtensionDamager : public TlsExtensionFilter {
class TlsExtensionAppender : public TlsHandshakeFilter {
public:
TlsExtensionAppender(uint8_t handshake_type, uint16_t ext, DataBuffer& data)
: TlsHandshakeFilter({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,
@ -124,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);
}
@ -156,7 +161,7 @@ class TlsExtensionTestBase : public TlsConnectTestBase {
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);
@ -197,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);
@ -209,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();
}
};
@ -241,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
@ -272,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);
}
@ -299,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) {
@ -321,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) {
@ -340,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) {
@ -348,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) {
@ -356,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) {
@ -364,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) {
@ -372,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) {
@ -380,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) {
@ -388,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);
}
@ -445,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();
@ -531,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
@ -542,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();
@ -563,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();
@ -585,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();
@ -597,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();
@ -618,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,
@ -733,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);
@ -744,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);
@ -757,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);
@ -770,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);
@ -782,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);
@ -797,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);
@ -809,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);
@ -822,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);
@ -833,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);
@ -849,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();
@ -860,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());
}
@ -958,11 +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);
} else {
server_->SetPacketFilter(filter);
filter->EnableDecryption();
}
}
@ -1078,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());

View file

@ -149,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();
}

View file

@ -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,
@ -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();
}
@ -219,29 +215,28 @@ FUZZ_P(TlsConnectGeneric, SessionTicketResumption) {
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" << i1->buffer() << std::endl;
std::cerr << "ticket" << filter->buffer() << std::endl;
size_t offset = 4; /* lifetime */
if (version_ == SSL_LIBRARY_VERSION_TLS_1_3) {
offset += 4; /* ticket_age_add */
uint32_t nonce_len = 0;
EXPECT_TRUE(i1->buffer().Read(offset, 1, &nonce_len));
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));
}
}

View file

@ -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,7 @@ 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);
@ -192,7 +193,7 @@ TEST_P(TlsConnectTls13, RetryWithSameKeyShare) {
TEST_P(TlsConnectTls13, RetryWithTwoShares) {
EnsureTlsSetup();
EXPECT_EQ(SECSuccess, SSL_SendAdditionalKeyShares(client_->ssl_fd(), 1));
client_->SetPacketFilter(std::make_shared<KeyShareReplayer>());
MakeTlsFilter<KeyShareReplayer>(client_);
static const std::vector<SSLNamedGroup> groups = {ssl_grp_ec_secp384r1,
ssl_grp_ec_secp521r1};
@ -238,9 +239,9 @@ TEST_P(TlsConnectTls13, RetryCallbackAcceptGroupMismatch) {
return ssl_hello_retry_accept;
};
auto capture = std::make_shared<TlsExtensionCapture>(ssl_tls13_cookie_xtn);
auto capture =
MakeTlsFilter<TlsExtensionCapture>(server_, ssl_tls13_cookie_xtn);
capture->SetHandshakeTypes({kTlsHandshakeHelloRetryRequest});
server_->SetPacketFilter(capture);
static const std::vector<SSLNamedGroup> groups = {ssl_grp_ec_secp384r1};
server_->ConfigNamedGroups(groups);
@ -359,14 +360,14 @@ SSLHelloRetryRequestAction RetryHello(PRBool firstHello,
TEST_P(TlsConnectTls13, RetryCallbackRetry) {
EnsureTlsSetup();
auto capture_hrr = std::make_shared<TlsInspectorRecordHandshakeMessage>(
ssl_hs_hello_retry_request);
auto capture_hrr = std::make_shared<TlsHandshakeRecorder>(
server_, ssl_hs_hello_retry_request);
auto capture_key_share =
std::make_shared<TlsExtensionCapture>(ssl_tls13_key_share_xtn);
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_->SetPacketFilter(std::make_shared<ChainedPacketFilter>(chain));
server_->SetFilter(std::make_shared<ChainedPacketFilter>(chain));
size_t cb_called = 0;
EXPECT_EQ(SECSuccess, SSL_HelloRetryRequestCallback(server_->ssl_fd(),
@ -383,8 +384,7 @@ TEST_P(TlsConnectTls13, RetryCallbackRetry) {
<< "no key_share extension expected";
auto capture_cookie =
std::make_shared<TlsExtensionCapture>(ssl_tls13_cookie_xtn);
client_->SetPacketFilter(capture_cookie);
MakeTlsFilter<TlsExtensionCapture>(client_, ssl_tls13_cookie_xtn);
Handshake();
CheckConnected();
@ -413,9 +413,8 @@ TEST_P(TlsConnectTls13, RetryCallbackRetryWithAdditionalShares) {
EXPECT_EQ(SECSuccess, SSL_SendAdditionalKeyShares(client_->ssl_fd(), 1));
auto capture_server =
std::make_shared<TlsExtensionCapture>(ssl_tls13_key_share_xtn);
MakeTlsFilter<TlsExtensionCapture>(server_, ssl_tls13_key_share_xtn);
capture_server->SetHandshakeTypes({kTlsHandshakeHelloRetryRequest});
server_->SetPacketFilter(capture_server);
size_t cb_called = 0;
EXPECT_EQ(SECSuccess, SSL_HelloRetryRequestCallback(server_->ssl_fd(),
@ -431,8 +430,7 @@ TEST_P(TlsConnectTls13, RetryCallbackRetryWithAdditionalShares) {
<< "no key_share extension expected from server";
auto capture_client_2nd =
std::make_shared<TlsExtensionCapture>(ssl_tls13_key_share_xtn);
client_->SetPacketFilter(capture_client_2nd);
MakeTlsFilter<TlsExtensionCapture>(client_, ssl_tls13_key_share_xtn);
Handshake();
CheckConnected();
@ -449,12 +447,12 @@ TEST_P(TlsConnectTls13, RetryCallbackRetryWithGroupMismatch) {
EnsureTlsSetup();
auto capture_cookie =
std::make_shared<TlsExtensionCapture>(ssl_tls13_cookie_xtn);
std::make_shared<TlsExtensionCapture>(server_, ssl_tls13_cookie_xtn);
capture_cookie->SetHandshakeTypes({kTlsHandshakeHelloRetryRequest});
auto capture_key_share =
std::make_shared<TlsExtensionCapture>(ssl_tls13_key_share_xtn);
std::make_shared<TlsExtensionCapture>(server_, ssl_tls13_key_share_xtn);
capture_key_share->SetHandshakeTypes({kTlsHandshakeHelloRetryRequest});
server_->SetPacketFilter(std::make_shared<ChainedPacketFilter>(
server_->SetFilter(std::make_shared<ChainedPacketFilter>(
ChainedPacketFilterInit{capture_cookie, capture_key_share}));
static const std::vector<SSLNamedGroup> groups = {ssl_grp_ec_secp384r1};
@ -493,9 +491,8 @@ TEST_P(TlsConnectTls13, RetryCallbackRetryWithToken) {
EnsureTlsSetup();
auto capture_key_share =
std::make_shared<TlsExtensionCapture>(ssl_tls13_key_share_xtn);
MakeTlsFilter<TlsExtensionCapture>(server_, ssl_tls13_key_share_xtn);
capture_key_share->SetHandshakeTypes({kTlsHandshakeHelloRetryRequest});
server_->SetPacketFilter(capture_key_share);
size_t cb_called = 0;
EXPECT_EQ(SECSuccess,
@ -513,9 +510,8 @@ TEST_P(TlsConnectTls13, RetryCallbackRetryWithTokenAndGroupMismatch) {
server_->ConfigNamedGroups(groups);
auto capture_key_share =
std::make_shared<TlsExtensionCapture>(ssl_tls13_key_share_xtn);
MakeTlsFilter<TlsExtensionCapture>(server_, ssl_tls13_key_share_xtn);
capture_key_share->SetHandshakeTypes({kTlsHandshakeHelloRetryRequest});
server_->SetPacketFilter(capture_key_share);
size_t cb_called = 0;
EXPECT_EQ(SECSuccess,
@ -589,8 +585,7 @@ TEST_P(TlsConnectTls13, RetryStatefulDropCookie) {
EnsureTlsSetup();
TriggerHelloRetryRequest(client_, server_);
client_->SetPacketFilter(
std::make_shared<TlsExtensionDropper>(ssl_tls13_cookie_xtn));
MakeTlsFilter<TlsExtensionDropper>(client_, ssl_tls13_cookie_xtn);
ExpectAlert(server_, kTlsAlertMissingExtension);
Handshake();
@ -603,8 +598,8 @@ TEST_F(TlsConnectStreamTls13, RetryStatelessDamageFirstClientHello) {
ConfigureSelfEncrypt();
EnsureTlsSetup();
auto damage_ch = std::make_shared<TlsExtensionInjector>(0xfff3, DataBuffer());
client_->SetPacketFilter(damage_ch);
auto damage_ch =
MakeTlsFilter<TlsExtensionInjector>(client_, 0xfff3, DataBuffer());
TriggerHelloRetryRequest(client_, server_);
MakeNewServer();
@ -625,8 +620,8 @@ TEST_F(TlsConnectStreamTls13, RetryStatelessDamageSecondClientHello) {
TriggerHelloRetryRequest(client_, server_);
MakeNewServer();
auto damage_ch = std::make_shared<TlsExtensionInjector>(0xfff3, DataBuffer());
client_->SetPacketFilter(damage_ch);
auto damage_ch =
MakeTlsFilter<TlsExtensionInjector>(client_, 0xfff3, DataBuffer());
// Key exchange fails when the handshake continues because client and server
// disagree about the transcript.
@ -640,7 +635,7 @@ TEST_F(TlsConnectStreamTls13, RetryStatelessDamageSecondClientHello) {
// 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<TlsInspectorRecordHandshakeMessage>& capture_hrr) {
std::shared_ptr<TlsHandshakeRecorder>& capture_hrr) {
uint32_t tmp;
size_t offset = 2 + 32; // skip version + server_random
ASSERT_TRUE(
@ -657,9 +652,8 @@ TEST_P(TlsConnectTls13, RetryStatelessDisableSuiteClient) {
ConfigureSelfEncrypt();
EnsureTlsSetup();
auto capture_hrr = std::make_shared<TlsInspectorRecordHandshakeMessage>(
ssl_hs_hello_retry_request);
server_->SetPacketFilter(capture_hrr);
auto capture_hrr =
MakeTlsFilter<TlsHandshakeRecorder>(server_, ssl_hs_hello_retry_request);
TriggerHelloRetryRequest(client_, server_);
MakeNewServer();
@ -678,9 +672,8 @@ TEST_P(TlsConnectTls13, RetryStatelessDisableSuiteServer) {
ConfigureSelfEncrypt();
EnsureTlsSetup();
auto capture_hrr = std::make_shared<TlsInspectorRecordHandshakeMessage>(
ssl_hs_hello_retry_request);
server_->SetPacketFilter(capture_hrr);
auto capture_hrr =
MakeTlsFilter<TlsHandshakeRecorder>(server_, ssl_hs_hello_retry_request);
TriggerHelloRetryRequest(client_, server_);
MakeNewServer();
@ -761,8 +754,8 @@ TEST_F(TlsConnectStreamTls13, RetryWithDifferentCipherSuite) {
static const std::vector<SSLNamedGroup> groups = {ssl_grp_ec_secp384r1};
server_->ConfigNamedGroups(groups);
// Then switch out the default suite (TLS_AES_128_GCM_SHA256).
server_->SetPacketFilter(std::make_shared<SelectedCipherSuiteReplacer>(
TLS_CHACHA20_POLY1305_SHA256));
MakeTlsFilter<SelectedCipherSuiteReplacer>(server_,
TLS_CHACHA20_POLY1305_SHA256);
client_->ExpectSendAlert(kTlsAlertIllegalParameter);
server_->ExpectSendAlert(kTlsAlertBadRecordMac);
@ -777,7 +770,7 @@ 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();
}
@ -833,9 +826,9 @@ TEST_P(TlsKeyExchange13,
EXPECT_EQ(SECSuccess, SSL_SendAdditionalKeyShares(client_->ssl_fd(), 1));
auto capture_server =
std::make_shared<TlsExtensionCapture>(ssl_tls13_key_share_xtn);
std::make_shared<TlsExtensionCapture>(server_, ssl_tls13_key_share_xtn);
capture_server->SetHandshakeTypes({kTlsHandshakeHelloRetryRequest});
server_->SetPacketFilter(std::make_shared<ChainedPacketFilter>(
server_->SetFilter(std::make_shared<ChainedPacketFilter>(
ChainedPacketFilterInit{capture_hrr_, capture_server}));
size_t cb_called = 0;

View file

@ -20,8 +20,8 @@ static const std::string keylog_env = "SSLKEYLOGFILE=" + keylog_file_path;
class KeyLogFileTest : public TlsConnectGeneric {
public:
void SetUp() {
TlsConnectTestBase::SetUp();
void SetUp() override {
TlsConnectGeneric::SetUp();
// Remove previous results (if any).
(void)remove(keylog_file_path.c_str());
PR_SetEnv(keylog_env.c_str());

View file

@ -56,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,
@ -86,9 +87,9 @@ class TlsAlertRecorder : public TlsRecordFilter {
class HelloTruncator : public TlsHandshakeFilter {
public:
HelloTruncator()
HelloTruncator(const std::shared_ptr<TlsAgent>& agent)
: TlsHandshakeFilter(
{kTlsHandshakeClientHello, kTlsHandshakeServerHello}) {}
agent, {kTlsHandshakeClientHello, kTlsHandshakeServerHello}) {}
PacketFilter::Action FilterHandshake(const HandshakeHeader& header,
const DataBuffer& input,
DataBuffer* output) override {
@ -99,9 +100,8 @@ 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_, kTlsAlertDecodeError);
EXPECT_EQ(kTlsAlertFatal, alert_recorder->level());
@ -109,9 +109,8 @@ TEST_P(TlsConnectGeneric, CaptureAlertServer) {
}
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());
@ -120,9 +119,8 @@ 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_);
StartConnect();
@ -173,7 +171,8 @@ TEST_P(TlsConnectGeneric, ConnectSendReceive) {
class SaveTlsRecord : public TlsRecordFilter {
public:
SaveTlsRecord(size_t index) : index_(index), count_(0), contents_() {}
SaveTlsRecord(const std::shared_ptr<TlsAgent>& agent, size_t index)
: TlsRecordFilter(agent), index_(index), count_(0), contents_() {}
const DataBuffer& contents() const { return contents_; }
@ -198,8 +197,8 @@ class SaveTlsRecord : public TlsRecordFilter {
TEST_F(TlsConnectStreamTls13, DecryptRecordClient) {
EnsureTlsSetup();
// 0 = ClientHello, 1 = Finished, 2 = SendReceive, 3 = SendBuffer
auto saved = std::make_shared<SaveTlsRecord>(3);
client_->SetTlsRecordFilter(saved);
auto saved = MakeTlsFilter<SaveTlsRecord>(client_, 3);
saved->EnableDecryption();
Connect();
SendReceive();
@ -215,8 +214,8 @@ TEST_F(TlsConnectStreamTls13, DecryptRecordServer) {
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 = std::make_shared<SaveTlsRecord>(3);
server_->SetTlsRecordFilter(saved);
auto saved = MakeTlsFilter<SaveTlsRecord>(server_, 3);
saved->EnableDecryption();
Connect();
SendReceive();
@ -228,7 +227,8 @@ TEST_F(TlsConnectStreamTls13, DecryptRecordServer) {
class DropTlsRecord : public TlsRecordFilter {
public:
DropTlsRecord(size_t index) : index_(index), count_(0) {}
DropTlsRecord(const std::shared_ptr<TlsAgent>& agent, size_t index)
: TlsRecordFilter(agent), index_(index), count_(0) {}
protected:
PacketFilter::Action FilterRecord(const TlsRecordHeader& header,
@ -253,7 +253,8 @@ TEST_F(TlsConnectStreamTls13, DropRecordServer) {
SSL_ENABLE_SESSION_TICKETS, PR_FALSE));
// 0 = ServerHello, 1 = other handshake, 2 = first write
server_->SetTlsRecordFilter(std::make_shared<DropTlsRecord>(2));
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();
@ -263,7 +264,8 @@ TEST_F(TlsConnectStreamTls13, DropRecordServer) {
TEST_F(TlsConnectStreamTls13, DropRecordClient) {
EnsureTlsSetup();
// 0 = ClientHello, 1 = Finished, 2 = first write
client_->SetTlsRecordFilter(std::make_shared<DropTlsRecord>(2));
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();
@ -371,7 +373,8 @@ TEST_P(TlsHolddownTest, TestDtlsHolddownExpiryResumption) {
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 {
@ -388,14 +391,14 @@ 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>());
MakeTlsFilter<TlsPreCCSHeaderInjector>(server_);
StartConnect();
ExpectAlert(client_, kTlsAlertUnexpectedMessage);
Handshake();
@ -476,8 +479,7 @@ TEST_F(TlsConnectTest, OneNRecordSplitting) {
ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_0);
EnsureTlsSetup();
ConnectWithCipherSuite(TLS_RSA_WITH_AES_128_CBC_SHA);
auto records = std::make_shared<TlsRecordRecorder>();
server_->SetPacketFilter(records);
auto records = MakeTlsFilter<TlsRecordRecorder>(server_);
// This should be split into 1, 16384 and 20.
DataBuffer big_buffer;
big_buffer.Allocate(1 + 16384 + 20);
@ -535,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

View file

@ -103,8 +103,8 @@ TEST_P(TlsPaddingTest, LastByteOfPadWrong) {
class RecordReplacer : public TlsRecordFilter {
public:
RecordReplacer(size_t size)
: TlsRecordFilter(), enabled_(false), size_(size) {}
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,
@ -135,8 +135,8 @@ TEST_F(TlsConnectStreamTls13, LargeRecord) {
EnsureTlsSetup();
const size_t record_limit = 16384;
auto replacer = std::make_shared<RecordReplacer>(record_limit);
client_->SetTlsRecordFilter(replacer);
auto replacer = MakeTlsFilter<RecordReplacer>(client_, record_limit);
replacer->EnableDecryption();
Connect();
replacer->Enable();
@ -149,8 +149,8 @@ TEST_F(TlsConnectStreamTls13, TooLargeRecord) {
EnsureTlsSetup();
const size_t record_limit = 16384;
auto replacer = std::make_shared<RecordReplacer>(record_limit + 1);
client_->SetTlsRecordFilter(replacer);
auto replacer = MakeTlsFilter<RecordReplacer>(client_, record_limit + 1);
replacer->EnableDecryption();
Connect();
replacer->Enable();
@ -177,4 +177,4 @@ auto kTrueFalse = ::testing::ValuesIn(kTrueFalseArr);
INSTANTIATE_TEST_CASE_P(TlsPadding, TlsPaddingTest,
::testing::Combine(kContentSizes, kTrueFalse));
} // namespace nspr_test
} // namespace nss_test

View file

@ -60,7 +60,7 @@ TEST_P(TlsConnectGenericPre13, ConnectResumed) {
Connect();
}
TEST_P(TlsConnectGeneric, ConnectClientCacheDisabled) {
TEST_P(TlsConnectGenericResumption, ConnectClientCacheDisabled) {
ConfigureSessionCache(RESUME_NONE, RESUME_SESSIONID);
Connect();
SendReceive();
@ -71,7 +71,7 @@ TEST_P(TlsConnectGeneric, ConnectClientCacheDisabled) {
SendReceive();
}
TEST_P(TlsConnectGeneric, ConnectServerCacheDisabled) {
TEST_P(TlsConnectGenericResumption, ConnectServerCacheDisabled) {
ConfigureSessionCache(RESUME_SESSIONID, RESUME_NONE);
Connect();
SendReceive();
@ -82,7 +82,7 @@ TEST_P(TlsConnectGeneric, ConnectServerCacheDisabled) {
SendReceive();
}
TEST_P(TlsConnectGeneric, ConnectSessionCacheDisabled) {
TEST_P(TlsConnectGenericResumption, ConnectSessionCacheDisabled) {
ConfigureSessionCache(RESUME_NONE, RESUME_NONE);
Connect();
SendReceive();
@ -93,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();
@ -106,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);
@ -120,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();
@ -133,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);
@ -147,7 +147,7 @@ TEST_P(TlsConnectGeneric, ConnectResumeClientServerTicketOnly) {
SendReceive();
}
TEST_P(TlsConnectGeneric, ConnectResumeClientBothServerNone) {
TEST_P(TlsConnectGenericResumption, ConnectResumeClientBothServerNone) {
ConfigureSessionCache(RESUME_BOTH, RESUME_NONE);
Connect();
SendReceive();
@ -159,7 +159,7 @@ TEST_P(TlsConnectGeneric, ConnectResumeClientBothServerNone) {
SendReceive();
}
TEST_P(TlsConnectGeneric, ConnectResumeClientNoneServerBoth) {
TEST_P(TlsConnectGenericResumption, ConnectResumeClientNoneServerBoth) {
ConfigureSessionCache(RESUME_NONE, RESUME_BOTH);
Connect();
SendReceive();
@ -202,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);
@ -219,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) {
@ -245,8 +244,7 @@ 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);
auto capture = MakeTlsFilter<TlsExtensionCapture>(client_, xtn);
StartConnect();
client_->Handshake();
EXPECT_TRUE(capture->captured());
@ -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());
@ -356,26 +352,24 @@ TEST_P(TlsConnectGenericPre13, ConnectEcdheTwiceReuseKey) {
// This test parses the ServerKeyExchange, which isn't in 1.3
TEST_P(TlsConnectGenericPre13, ConnectEcdheTwiceNewKey) {
server_->SetOption(SSL_REUSE_SERVER_ECDHE_KEY, PR_FALSE);
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();
server_->SetOption(SSL_REUSE_SERVER_ECDHE_KEY, PR_FALSE);
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 different.
EXPECT_FALSE((dhe1.public_key_.len() == dhe2.public_key_.len()) &&
@ -397,7 +391,7 @@ TEST_P(TlsConnectTls13, TestTls13ResumeDifferentGroup) {
server_->ConfigNamedGroups(kFFDHEGroups);
Connect();
CheckKeys(ssl_kea_dh, ssl_grp_ffdhe_2048, ssl_auth_rsa_sign,
ssl_sig_rsa_pss_sha256);
ssl_sig_rsa_pss_rsae_sha256);
}
// We need to enable different cipher suites at different times in the following
@ -417,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();
@ -434,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();
@ -468,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);
@ -490,8 +484,10 @@ TEST_P(TlsConnectStream, TestResumptionOverrideCipher) {
class SelectedVersionReplacer : public TlsHandshakeFilter {
public:
SelectedVersionReplacer(uint16_t version)
: TlsHandshakeFilter({kTlsHandshakeServerHello}), version_(version) {}
SelectedVersionReplacer(const std::shared_ptr<TlsAgent>& agent,
uint16_t version)
: TlsHandshakeFilter(agent, {kTlsHandshakeServerHello}),
version_(version) {}
protected:
PacketFilter::Action FilterHandshake(const HandshakeHeader& header,
@ -543,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);
@ -567,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_rsa_pss_sha256);
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());
@ -584,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_rsa_pss_sha256);
ssl_sig_rsa_pss_rsae_sha256);
ASSERT_LT(0U, c2->extension().len());
ScopedCERTCertificate cert2(SSL_PeerCertificate(client_->ssl_fd()));
@ -656,9 +651,9 @@ TEST_F(TlsConnectTest, TestTls13ResumptionDuplicateNSTWithToken) {
ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
auto nst_capture = std::make_shared<TlsInspectorRecordHandshakeMessage>(
ssl_hs_new_session_ticket);
server_->SetTlsRecordFilter(nst_capture);
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.
@ -679,8 +674,7 @@ TEST_F(TlsConnectTest, TestTls13ResumptionDuplicateNSTWithToken) {
ExpectResumption(RESUME_TICKET);
auto psk_capture =
std::make_shared<TlsExtensionCapture>(ssl_tls13_pre_shared_key_xtn);
client_->SetPacketFilter(psk_capture);
MakeTlsFilter<TlsExtensionCapture>(client_, ssl_tls13_pre_shared_key_xtn);
Connect();
SendReceive();
@ -696,9 +690,9 @@ TEST_F(TlsConnectTest, SendSessionTicketWithTicketsDisabled) {
EXPECT_EQ(SECSuccess, SSL_OptionSet(server_->ssl_fd(),
SSL_ENABLE_SESSION_TICKETS, PR_FALSE));
auto nst_capture = std::make_shared<TlsInspectorRecordHandshakeMessage>(
ssl_hs_new_session_ticket);
server_->SetTlsRecordFilter(nst_capture);
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";
@ -715,8 +709,7 @@ TEST_F(TlsConnectTest, SendSessionTicketWithTicketsDisabled) {
ExpectResumption(RESUME_TICKET);
auto psk_capture =
std::make_shared<TlsExtensionCapture>(ssl_tls13_pre_shared_key_xtn);
client_->SetPacketFilter(psk_capture);
MakeTlsFilter<TlsExtensionCapture>(client_, ssl_tls13_pre_shared_key_xtn);
Connect();
SendReceive();
@ -819,20 +812,20 @@ 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));
filters.push_back(
std::make_shared<SelectedVersionReplacer>(SSL_LIBRARY_VERSION_TLS_1_2));
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<TlsExtensionDropper>(ssl_tls13_supported_versions_xtn));
filters.push_back(
std::make_shared<TlsExtensionDropper>(ssl_tls13_key_share_xtn));
filters.push_back(
std::make_shared<TlsExtensionDropper>(ssl_tls13_pre_shared_key_xtn));
server_->SetPacketFilter(std::make_shared<ChainedPacketFilter>(filters));
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
@ -845,13 +838,13 @@ TEST_F(TlsConnectTest, TestTls13ResumptionForcedDowngrade) {
server_->CheckErrorCode(SSL_ERROR_BAD_MAC_READ);
}
TEST_P(TlsConnectGeneric, ReConnectTicket) {
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_sha256);
ssl_sig_rsa_pss_rsae_sha256);
// Resume
Reset();
ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH);
@ -859,7 +852,7 @@ TEST_P(TlsConnectGeneric, ReConnectTicket) {
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_sha256);
ssl_auth_rsa_sign, ssl_sig_rsa_pss_rsae_sha256);
}
TEST_P(TlsConnectGenericPre13, ReConnectCache) {
@ -868,22 +861,22 @@ TEST_P(TlsConnectGenericPre13, ReConnectCache) {
Connect();
SendReceive();
CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_rsa_sign,
ssl_sig_rsa_pss_sha256);
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_sha256);
ssl_auth_rsa_sign, ssl_sig_rsa_pss_rsae_sha256);
}
TEST_P(TlsConnectGeneric, ReConnectAgainTicket) {
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_sha256);
ssl_sig_rsa_pss_rsae_sha256);
// Resume
Reset();
ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH);
@ -891,7 +884,7 @@ TEST_P(TlsConnectGeneric, ReConnectAgainTicket) {
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_sha256);
ssl_auth_rsa_sign, ssl_sig_rsa_pss_rsae_sha256);
// Resume connection again
Reset();
ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH);
@ -899,7 +892,140 @@ TEST_P(TlsConnectGeneric, ReConnectAgainTicket) {
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_sha256);
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

View file

@ -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
@ -92,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);
}
};
@ -105,9 +113,14 @@ 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();
server_->SetFilter(filter);
ExpectAlert(client_, kTlsAlertUnexpectedMessage);
ConnectExpectFail();
client_->CheckErrorCode(error);
@ -115,8 +128,8 @@ class Tls13SkipTest : public TlsConnectTestBase,
}
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);
@ -129,48 +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>(ChainedPacketFilterInit{
std::make_shared<TlsHandshakeSkipFilter>(kTlsHandshakeCertificate),
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);
}
@ -178,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(

View file

@ -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,8 +67,7 @@ TEST_P(TlsConnectStreamPre13, ConnectStaticRSABogusPMSVersionDetect) {
// ConnectStaticRSABogusPMSVersionDetect.
TEST_P(TlsConnectGenericPre13, ConnectStaticRSABogusPMSVersionIgnore) {
EnableOnlyStaticRsaCiphers();
client_->SetPacketFilter(
std::make_shared<TlsInspectorClientHelloVersionChanger>(server_));
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_));
MakeTlsFilter<TlsClientHelloVersionChanger>(client_, server_);
server_->SetOption(SSL_ROLLBACK_DETECTION, PR_FALSE);
Connect();
}
} // namespace nspr_test
} // namespace nss_test

View file

@ -67,10 +67,7 @@ class Tls13CompatTest : public TlsConnectStreamTls13 {
private:
struct Recorders {
Recorders()
: records_(new TlsRecordRecorder()),
hello_(new TlsInspectorRecordHandshakeMessage(std::set<uint8_t>(
{kTlsHandshakeClientHello, kTlsHandshakeServerHello}))) {}
Recorders() : records_(nullptr), hello_(nullptr) {}
uint8_t session_id_length() const {
// session_id is always after version (2) and random (32).
@ -91,12 +88,22 @@ class Tls13CompatTest : public TlsConnectStreamTls13 {
}
void Install(std::shared_ptr<TlsAgent>& agent) {
agent->SetPacketFilter(std::make_shared<ChainedPacketFilter>(
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<TlsInspectorRecordHandshakeMessage> hello_;
std::shared_ptr<TlsHandshakeRecorder> hello_;
};
void CheckRecordsAreTls12(const std::string& agent,
@ -171,16 +178,20 @@ TEST_F(Tls13CompatTest, EnabledStatelessHrr) {
server_->StartConnect();
client_->Handshake();
server_->Handshake();
// The server should send CCS before HRR.
CheckForCCS(false, true);
// A new server should just work, but not send another CCS.
// A new server should complete the handshake, and not send CCS.
MakeNewServer();
InstallFilters();
server_->ConfigNamedGroups({ssl_grp_ec_secp384r1});
Handshake();
CheckConnected();
CheckForCompatHandshake();
CheckRecordVersions();
CheckHelloVersions();
CheckForCCS(true, false);
}
TEST_F(Tls13CompatTest, EnabledHrrZeroRtt) {
@ -262,10 +273,8 @@ TEST_F(TlsConnectStreamTls13, ChangeCipherSpecBeforeClientHello12) {
TEST_F(TlsConnectDatagram13, CompatModeDtlsClient) {
EnsureTlsSetup();
client_->SetOption(SSL_ENABLE_TLS13_COMPAT_MODE, PR_TRUE);
auto client_records = std::make_shared<TlsRecordRecorder>();
client_->SetPacketFilter(client_records);
auto server_records = std::make_shared<TlsRecordRecorder>();
server_->SetPacketFilter(server_records);
auto client_records = MakeTlsFilter<TlsRecordRecorder>(client_);
auto server_records = MakeTlsFilter<TlsRecordRecorder>(server_);
Connect();
ASSERT_EQ(2U, client_records->count()); // CH, Fin
@ -283,7 +292,8 @@ TEST_F(TlsConnectDatagram13, CompatModeDtlsClient) {
class AddSessionIdFilter : public TlsHandshakeFilter {
public:
AddSessionIdFilter() : TlsHandshakeFilter({ssl_hs_client_hello}) {}
AddSessionIdFilter(const std::shared_ptr<TlsAgent>& client)
: TlsHandshakeFilter(client, {ssl_hs_client_hello}) {}
protected:
PacketFilter::Action FilterHandshake(const HandshakeHeader& header,
@ -303,14 +313,14 @@ class AddSessionIdFilter : public TlsHandshakeFilter {
// mode. It should be ignored instead.
TEST_F(TlsConnectDatagram13, CompatModeDtlsServer) {
EnsureTlsSetup();
auto client_records = std::make_shared<TlsRecordRecorder>();
client_->SetPacketFilter(
auto client_records = std::make_shared<TlsRecordRecorder>(client_);
client_->SetFilter(
std::make_shared<ChainedPacketFilter>(ChainedPacketFilterInit(
{client_records, std::make_shared<AddSessionIdFilter>()})));
auto server_hello = std::make_shared<TlsInspectorRecordHandshakeMessage>(
kTlsHandshakeServerHello);
auto server_records = std::make_shared<TlsRecordRecorder>();
server_->SetPacketFilter(std::make_shared<ChainedPacketFilter>(
{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();
@ -334,4 +344,20 @@ TEST_F(TlsConnectDatagram13, CompatModeDtlsServer) {
EXPECT_EQ(0U, session_id_len);
}
} // nss_test
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

View file

@ -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,10 +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_);
filter_ = MakeTlsFilter<SSLv2ClientHelloFilter>(client_, version_);
}
void SetExpectedVersion(uint16_t version) {

View file

@ -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,
@ -177,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);
@ -214,12 +207,10 @@ 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<TlsExtensionCapture>(ssl_tls13_supported_versions_xtn);
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();

View file

@ -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();
}

View file

@ -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");

View file

@ -74,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();
@ -176,6 +178,6 @@ class Poller {
timers_;
};
} // end of namespace
} // namespace nss_test
#endif

View file

@ -12,6 +12,7 @@
#include "sslerr.h"
#include "sslexp.h"
#include "sslproto.h"
#include "tls_filter.h"
#include "tls_parser.h"
extern "C" {
@ -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,7 +75,8 @@ TlsAgent::TlsAgent(const std::string& name, Role role,
handshake_callback_(),
auth_certificate_callback_(),
sni_callback_(),
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_);
@ -182,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);
@ -207,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_);
@ -386,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;

View file

@ -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;
@ -80,18 +82,10 @@ class TlsAgent : public PollTarget {
adapter_->SetPeer(peer->adapter_);
}
// Set a filter that can access plaintext (TLS 1.3 only).
void SetTlsRecordFilter(std::shared_ptr<TlsRecordFilter> filter) {
filter->SetAgent(this);
adapter_->SetPacketFilter(filter);
filter->EnableDecryption();
}
void SetPacketFilter(std::shared_ptr<PacketFilter> filter) {
void SetFilter(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,
@ -165,6 +159,24 @@ class TlsAgent : public PollTarget {
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_; }
@ -382,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_;
@ -393,6 +406,7 @@ class TlsAgent : public PollTarget {
AuthCertificateCallbackFunction auth_certificate_callback_;
SniCallbackFunction sni_callback_;
bool skip_version_checks_;
std::vector<uint8_t> resumption_token_;
};
inline std::ostream& operator<<(std::ostream& stream,
@ -443,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_;

View file

@ -197,7 +197,6 @@ 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();
@ -230,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();
@ -290,6 +291,7 @@ 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();
}
@ -402,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;
@ -670,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.
@ -754,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(

View file

@ -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,7 +55,7 @@ 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
@ -208,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<
@ -273,7 +319,7 @@ 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);

View file

@ -452,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.
@ -763,7 +763,7 @@ PacketFilter::Action AfterRecordN::FilterRecord(const TlsRecordHeader& header,
if (counter_++ == record_) {
DataBuffer buf;
header.Write(&buf, 0, body);
src_.lock()->SendDirect(buf);
agent()->SendDirect(buf);
dest_.lock()->Handshake();
func_();
return DROP;
@ -772,7 +772,7 @@ 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) {
EXPECT_EQ(SECSuccess,
@ -808,7 +808,7 @@ PacketFilter::Action SelectiveRecordDropFilter::FilterRecord(
return pattern;
}
PacketFilter::Action TlsInspectorClientHelloVersionSetter::FilterHandshake(
PacketFilter::Action TlsClientHelloVersionSetter::FilterHandshake(
const HandshakeHeader& header, const DataBuffer& input,
DataBuffer* output) {
*output = input;

View file

@ -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:
@ -71,19 +71,27 @@ struct TlsRecord {
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),
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);
@ -126,7 +134,7 @@ 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.
@ -175,9 +183,13 @@ inline std::ostream& operator<<(std::ostream& stream,
// records and that they don't span records or anything crazy like that.
class TlsHandshakeFilter : public TlsRecordFilter {
public:
TlsHandshakeFilter() : handshake_types_(), preceding_fragment_() {}
TlsHandshakeFilter(const std::set<uint8_t>& types)
: handshake_types_(types), preceding_fragment_() {}
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
@ -229,12 +241,14 @@ class TlsHandshakeFilter : public TlsRecordFilter {
};
// 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)
: TlsHandshakeFilter({handshake_type}), buffer_() {}
TlsInspectorRecordHandshakeMessage(const std::set<uint8_t>& handshake_types)
: TlsHandshakeFilter(handshake_types), 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,
@ -251,9 +265,10 @@ class TlsInspectorRecordHandshakeMessage : public TlsHandshakeFilter {
// 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)
: TlsHandshakeFilter({handshake_type}), buffer_(replacement) {}
: TlsHandshakeFilter(agent, {handshake_type}), buffer_(replacement) {}
virtual PacketFilter::Action FilterHandshake(const HandshakeHeader& header,
const DataBuffer& input,
@ -266,9 +281,11 @@ class TlsInspectorReplaceHandshakeMessage : public TlsHandshakeFilter {
// Make a copy of each record of a given type.
class TlsRecordRecorder : public TlsRecordFilter {
public:
TlsRecordRecorder(uint8_t ct) : filter_(true), ct_(ct), records_() {}
TlsRecordRecorder()
: filter_(false),
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,
@ -289,7 +306,9 @@ class TlsRecordRecorder : public TlsRecordFilter {
// 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,
@ -302,6 +321,8 @@ class TlsConversationRecorder : public TlsRecordFilter {
// 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);
@ -338,13 +359,15 @@ typedef std::function<bool(TlsParser* parser, const TlsVersioned& header)>
class TlsExtensionFilter : public TlsHandshakeFilter {
public:
TlsExtensionFilter()
: TlsHandshakeFilter({kTlsHandshakeClientHello, kTlsHandshakeServerHello,
TlsExtensionFilter(const std::shared_ptr<TlsAgent>& agent)
: TlsHandshakeFilter(agent,
{kTlsHandshakeClientHello, kTlsHandshakeServerHello,
kTlsHandshakeHelloRetryRequest,
kTlsHandshakeEncryptedExtensions}) {}
TlsExtensionFilter(const std::set<uint8_t>& types)
: TlsHandshakeFilter(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);
@ -365,8 +388,13 @@ class TlsExtensionFilter : public TlsHandshakeFilter {
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_; }
@ -385,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;
@ -398,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;
@ -408,8 +439,9 @@ class TlsExtensionDropper : public TlsExtensionFilter {
class TlsExtensionInjector : public TlsHandshakeFilter {
public:
TlsExtensionInjector(uint16_t ext, const DataBuffer& data)
: extension_(ext), data_(data) {}
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,
@ -426,16 +458,20 @@ 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_;
@ -444,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)
: TlsHandshakeFilter({kTlsHandshakeClientKeyExchange}), 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,
@ -477,14 +515,16 @@ class SelectiveDropFilter : public PacketFilter {
// datagram, we just drop one.
class SelectiveRecordDropFilter : public TlsRecordFilter {
public:
SelectiveRecordDropFilter(uint32_t pattern, bool enabled = true)
: pattern_(pattern), counter_(0) {
SelectiveRecordDropFilter(const std::shared_ptr<TlsAgent>& agent,
uint32_t pattern, bool enabled = true)
: TlsRecordFilter(agent), pattern_(pattern), counter_(0) {
if (!enabled) {
Disable();
}
}
SelectiveRecordDropFilter(std::initializer_list<size_t> records)
: SelectiveRecordDropFilter(ToPattern(records), true) {}
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;
@ -509,10 +549,12 @@ class SelectiveRecordDropFilter : public TlsRecordFilter {
};
// Set the version number in the ClientHello.
class TlsInspectorClientHelloVersionSetter : public TlsHandshakeFilter {
class TlsClientHelloVersionSetter : public TlsHandshakeFilter {
public:
TlsInspectorClientHelloVersionSetter(uint16_t version)
: TlsHandshakeFilter({kTlsHandshakeClientHello}), 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,
@ -525,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 {
@ -545,8 +588,10 @@ class TlsLastByteDamager : public TlsHandshakeFilter {
class SelectedCipherSuiteReplacer : public TlsHandshakeFilter {
public:
SelectedCipherSuiteReplacer(uint16_t suite)
: TlsHandshakeFilter({kTlsHandshakeServerHello}), cipher_suite_(suite) {}
SelectedCipherSuiteReplacer(const std::shared_ptr<TlsAgent>& agent,
uint16_t suite)
: TlsHandshakeFilter(agent, {kTlsHandshakeServerHello}),
cipher_suite_(suite) {}
protected:
PacketFilter::Action FilterHandshake(const HandshakeHeader& header,

View file

@ -37,6 +37,8 @@ NSS build tool options:
--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

View file

@ -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);

View file

@ -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);
}
/* First obtain the slot info */
/* avoid repeated calls to check token status within set interval */
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 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;
}
slot->lastTokenPing = PR_IntervalNow();
return PR_TRUE;
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->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);

View file

@ -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 {

View file

@ -32,7 +32,7 @@ nssCryptokiObject_Create(
/* a failure here indicates a device error */
return (nssCryptokiObject *)NULL;
}
if (cert_template[0].ulValueLen == 0) {
if (cert_template[0].ulValueLen == 0 || !cert_template[0].pValue) {
nss_ZFreeIf(cert_template[1].pValue);
return (nssCryptokiObject *)NULL;
}

View file

@ -519,18 +519,16 @@ ifndef NSS_DISABLE_CHACHAPOLY
else
EXTRA_SRCS += poly1305.c
endif
ifneq (1,$(CC_IS_GCC))
EXTRA_SRCS += chacha20.c
VERIFIED_SRCS += Hacl_Chacha20.c
else
EXTRA_SRCS += chacha20_vec.c
endif
else
EXTRA_SRCS += poly1305.c
EXTRA_SRCS += chacha20.c
VERIFIED_SRCS += Hacl_Chacha20.c
ifeq ($(CPU_ARCH),aarch64)
EXTRA_SRCS += Hacl_Poly1305_64.c
else
EXTRA_SRCS += poly1305.c
endif
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 aarch64,$(CPU_ARCH)))

View file

@ -80,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_ */

View file

@ -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;
}

View file

@ -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/. */
/* Adopted from the public domain code in NaCl by djb. */
#include <string.h>
#include <stdio.h>
#include "chacha20.h"
#include "verified/Hacl_Chacha20.h"
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)
{
Hacl_Chacha20_chacha20(out, (uint8_t *)in, inLen, (uint8_t *)key, (uint8_t *)nonce, counter);
}

View file

@ -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_ */

View file

@ -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];
}
}
}

View file

@ -12,25 +12,28 @@
#include "seccomon.h"
#include "secerr.h"
#include "blapit.h"
#include "blapii.h"
#ifndef NSS_DISABLE_CHACHAPOLY
#if defined(HAVE_INT128_SUPPORT) && (defined(NSS_X86_OR_X64) || defined(__aarch64__))
#include "verified/Hacl_Poly1305_64.h"
#else
#include "poly1305.h"
#endif
#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)
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));
@ -46,7 +49,8 @@ Poly1305Do(unsigned char *out, const unsigned char *ad, unsigned int adLen,
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);
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);
@ -68,6 +72,8 @@ Poly1305Do(unsigned char *out, const unsigned char *ad, unsigned int adLen,
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,
@ -165,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,
@ -191,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);
@ -233,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

View file

@ -90,7 +90,7 @@ EXTRA_SHARED_LIBS += \
endif
endif
ifeq ($(OS_ARCH), Linux)
ifeq (,$(filter-out DragonFly FreeBSD Linux NetBSD OpenBSD, $(OS_TARGET)))
CFLAGS += -std=gnu99
endif

View file

@ -4,7 +4,7 @@
#include "blapi.h"
#include "blapit.h"
#include "chacha20.h"
#include "Hacl_Chacha20.h"
#include "nssilock.h"
#include "seccomon.h"
#include "secerr.h"
@ -99,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);

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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

Some files were not shown because too many files have changed in this diff Show more