@@ -2093,6 +2093,148 @@ static int test_psk_tickets(void)
2093
2093
2094
2094
return testresult ;
2095
2095
}
2096
+
2097
+ static int test_extra_tickets (int idx )
2098
+ {
2099
+ SSL_CTX * sctx = NULL , * cctx = NULL ;
2100
+ SSL * serverssl = NULL , * clientssl = NULL ;
2101
+ BIO * bretry = BIO_new (bio_s_always_retry ());
2102
+ BIO * tmp = NULL ;
2103
+ int testresult = 0 ;
2104
+ int stateful = 0 ;
2105
+ size_t nbytes ;
2106
+ unsigned char c , buf [1 ];
2107
+
2108
+ new_called = 0 ;
2109
+ do_cache = 1 ;
2110
+
2111
+ if (idx >= 3 ) {
2112
+ idx -= 3 ;
2113
+ stateful = 1 ;
2114
+ }
2115
+
2116
+ if (!TEST_ptr (bretry ) || !setup_ticket_test (stateful , idx , & sctx , & cctx ))
2117
+ goto end ;
2118
+ SSL_CTX_sess_set_new_cb (sctx , new_session_cb );
2119
+ /* setup_ticket_test() uses new_cachesession_cb which we don't need. */
2120
+ SSL_CTX_sess_set_new_cb (cctx , new_session_cb );
2121
+
2122
+ if (!TEST_true (create_ssl_objects (sctx , cctx , & serverssl ,
2123
+ & clientssl , NULL , NULL )))
2124
+ goto end ;
2125
+
2126
+ /*
2127
+ * Note that we have new_session_cb on both sctx and cctx, so new_called is
2128
+ * incremented by both client and server.
2129
+ */
2130
+ if (!TEST_true (create_ssl_connection (serverssl , clientssl ,
2131
+ SSL_ERROR_NONE ))
2132
+ /* Check we got the number of tickets we were expecting */
2133
+ || !TEST_int_eq (idx * 2 , new_called )
2134
+ || !TEST_true (SSL_new_session_ticket (serverssl ))
2135
+ || !TEST_true (SSL_new_session_ticket (serverssl ))
2136
+ || !TEST_int_eq (idx * 2 , new_called ))
2137
+ goto end ;
2138
+
2139
+ /* Now try a (real) write to actually send the tickets */
2140
+ c = '1' ;
2141
+ if (!TEST_true (SSL_write_ex (serverssl , & c , 1 , & nbytes ))
2142
+ || !TEST_size_t_eq (1 , nbytes )
2143
+ || !TEST_int_eq (idx * 2 + 2 , new_called )
2144
+ || !TEST_true (SSL_read_ex (clientssl , buf , sizeof (buf ), & nbytes ))
2145
+ || !TEST_int_eq (idx * 2 + 4 , new_called )
2146
+ || !TEST_int_eq (sizeof (buf ), nbytes )
2147
+ || !TEST_int_eq (c , buf [0 ])
2148
+ || !TEST_false (SSL_read_ex (clientssl , buf , sizeof (buf ), & nbytes )))
2149
+ goto end ;
2150
+
2151
+ /* Try with only requesting one new ticket, too */
2152
+ c = '2' ;
2153
+ new_called = 0 ;
2154
+ if (!TEST_true (SSL_new_session_ticket (serverssl ))
2155
+ || !TEST_true (SSL_write_ex (serverssl , & c , sizeof (c ), & nbytes ))
2156
+ || !TEST_size_t_eq (sizeof (c ), nbytes )
2157
+ || !TEST_int_eq (1 , new_called )
2158
+ || !TEST_true (SSL_read_ex (clientssl , buf , sizeof (buf ), & nbytes ))
2159
+ || !TEST_int_eq (2 , new_called )
2160
+ || !TEST_size_t_eq (sizeof (buf ), nbytes )
2161
+ || !TEST_int_eq (c , buf [0 ]))
2162
+ goto end ;
2163
+
2164
+ /* Do it again but use dummy writes to drive the ticket generation */
2165
+ c = '3' ;
2166
+ new_called = 0 ;
2167
+ if (!TEST_true (SSL_new_session_ticket (serverssl ))
2168
+ || !TEST_true (SSL_new_session_ticket (serverssl ))
2169
+ || !TEST_true (SSL_write_ex (serverssl , & c , 0 , & nbytes ))
2170
+ || !TEST_size_t_eq (0 , nbytes )
2171
+ || !TEST_int_eq (2 , new_called )
2172
+ || !TEST_false (SSL_read_ex (clientssl , buf , sizeof (buf ), & nbytes ))
2173
+ || !TEST_int_eq (4 , new_called ))
2174
+ goto end ;
2175
+
2176
+ /*
2177
+ * Use the always-retry BIO to exercise the logic that forces ticket
2178
+ * generation to wait until a record boundary.
2179
+ */
2180
+ c = '4' ;
2181
+ new_called = 0 ;
2182
+ tmp = SSL_get_wbio (serverssl );
2183
+ if (!TEST_ptr (tmp ) || !TEST_true (BIO_up_ref (tmp ))) {
2184
+ tmp = NULL ;
2185
+ goto end ;
2186
+ }
2187
+ SSL_set0_wbio (serverssl , bretry );
2188
+ bretry = NULL ;
2189
+ if (!TEST_false (SSL_write_ex (serverssl , & c , 1 , & nbytes ))
2190
+ || !TEST_int_eq (SSL_get_error (serverssl , 0 ), SSL_ERROR_WANT_WRITE )
2191
+ || !TEST_size_t_eq (nbytes , 0 ))
2192
+ goto end ;
2193
+ /* Restore a BIO that will let the write succeed */
2194
+ SSL_set0_wbio (serverssl , tmp );
2195
+ tmp = NULL ;
2196
+ /* These calls should just queue the request and not send anything. */
2197
+ if (!TEST_true (SSL_new_session_ticket (serverssl ))
2198
+ || !TEST_true (SSL_new_session_ticket (serverssl ))
2199
+ || !TEST_int_eq (0 , new_called ))
2200
+ goto end ;
2201
+ /* Re-do the write; still no tickets sent */
2202
+ if (!TEST_true (SSL_write_ex (serverssl , & c , 1 , & nbytes ))
2203
+ || !TEST_size_t_eq (1 , nbytes )
2204
+ || !TEST_int_eq (0 , new_called )
2205
+ || !TEST_true (SSL_read_ex (clientssl , buf , sizeof (buf ), & nbytes ))
2206
+ || !TEST_int_eq (0 , new_called )
2207
+ || !TEST_int_eq (sizeof (buf ), nbytes )
2208
+ || !TEST_int_eq (c , buf [0 ])
2209
+ || !TEST_false (SSL_read_ex (clientssl , buf , sizeof (buf ), & nbytes )))
2210
+ goto end ;
2211
+ /* Now the *next* write should send the tickets */
2212
+ c = '5' ;
2213
+ if (!TEST_true (SSL_write_ex (serverssl , & c , 1 , & nbytes ))
2214
+ || !TEST_size_t_eq (1 , nbytes )
2215
+ || !TEST_int_eq (2 , new_called )
2216
+ || !TEST_true (SSL_read_ex (clientssl , buf , sizeof (buf ), & nbytes ))
2217
+ || !TEST_int_eq (4 , new_called )
2218
+ || !TEST_int_eq (sizeof (buf ), nbytes )
2219
+ || !TEST_int_eq (c , buf [0 ])
2220
+ || !TEST_false (SSL_read_ex (clientssl , buf , sizeof (buf ), & nbytes )))
2221
+ goto end ;
2222
+
2223
+ SSL_shutdown (clientssl );
2224
+ SSL_shutdown (serverssl );
2225
+ testresult = 1 ;
2226
+
2227
+ end :
2228
+ BIO_free (bretry );
2229
+ BIO_free (tmp );
2230
+ SSL_free (serverssl );
2231
+ SSL_free (clientssl );
2232
+ SSL_CTX_free (sctx );
2233
+ SSL_CTX_free (cctx );
2234
+ clientssl = serverssl = NULL ;
2235
+ sctx = cctx = NULL ;
2236
+ return testresult ;
2237
+ }
2096
2238
#endif
2097
2239
2098
2240
#define USE_NULL 0
@@ -7395,6 +7537,7 @@ int setup_tests(void)
7395
7537
ADD_ALL_TESTS (test_stateful_tickets , 3 );
7396
7538
ADD_ALL_TESTS (test_stateless_tickets , 3 );
7397
7539
ADD_TEST (test_psk_tickets );
7540
+ ADD_ALL_TESTS (test_extra_tickets , 6 );
7398
7541
#endif
7399
7542
ADD_ALL_TESTS (test_ssl_set_bio , TOTAL_SSL_SET_BIO_TESTS );
7400
7543
ADD_TEST (test_ssl_bio_pop_next_bio );
0 commit comments