blob: d57339f08bc866159c1024dfeb517f739d87dc58 [file] [log] [blame]
David Benjamin025b3d32014-07-01 19:53:04 -04001/* Copyright (c) 2014, Google Inc.
2 *
3 * Permission to use, copy, modify, and/or distribute this software for any
4 * purpose with or without fee is hereby granted, provided that the above
5 * copyright notice and this permission notice appear in all copies.
6 *
7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14
David Benjamin4cc36ad2015-12-19 14:23:26 -050015#if !defined(__STDC_FORMAT_MACROS)
16#define __STDC_FORMAT_MACROS
17#endif
18
Adam Langleyded93582014-07-31 15:23:51 -070019#include <openssl/base.h>
20
21#if !defined(OPENSSL_WINDOWS)
David Benjamin025b3d32014-07-01 19:53:04 -040022#include <arpa/inet.h>
David Benjamin1d5c83e2014-07-22 19:20:02 -040023#include <netinet/in.h>
David Benjamin87c8a642015-02-21 01:54:29 -050024#include <netinet/tcp.h>
David Benjamin1d5c83e2014-07-22 19:20:02 -040025#include <signal.h>
26#include <sys/socket.h>
David Benjamin0abd6f22015-12-04 21:49:53 -050027#include <sys/time.h>
David Benjamin8f2c20e2014-07-09 09:30:38 -040028#include <unistd.h>
David Benjamin87c8a642015-02-21 01:54:29 -050029#else
30#include <io.h>
David Benjamina353cdb2016-06-09 16:48:33 -040031OPENSSL_MSVC_PRAGMA(warning(push, 3))
Adam Langley3e719312015-03-20 16:32:23 -070032#include <winsock2.h>
33#include <ws2tcpip.h>
David Benjamina353cdb2016-06-09 16:48:33 -040034OPENSSL_MSVC_PRAGMA(warning(pop))
David Benjamin87c8a642015-02-21 01:54:29 -050035
David Benjamin4fec04b2016-10-10 14:56:47 -040036OPENSSL_MSVC_PRAGMA(comment(lib, "Ws2_32.lib"))
Adam Langleyded93582014-07-31 15:23:51 -070037#endif
38
David Benjamin585d7a42016-06-02 14:58:00 -040039#include <assert.h>
David Benjamin4cc36ad2015-12-19 14:23:26 -050040#include <inttypes.h>
Adam Langley2b2d66d2015-01-30 17:08:37 -080041#include <string.h>
David Benjamin025b3d32014-07-01 19:53:04 -040042
David Benjaminabbbee12016-10-31 19:20:42 -040043#include <openssl/aead.h>
David Benjamin025b3d32014-07-01 19:53:04 -040044#include <openssl/bio.h>
David Benjamin48cae082014-10-27 01:06:24 -040045#include <openssl/buf.h>
David Benjamin8f2c20e2014-07-09 09:30:38 -040046#include <openssl/bytestring.h>
David Benjamind98452d2015-06-16 14:16:23 -040047#include <openssl/cipher.h>
David Benjamin7a1eefd2015-10-17 23:39:22 -040048#include <openssl/crypto.h>
David Benjaminf0e935d2016-09-06 18:10:19 -040049#include <openssl/digest.h>
Brian Smith83a82982015-04-09 16:21:10 -100050#include <openssl/err.h>
Matt Braithwaited17d74d2016-08-17 20:10:28 -070051#include <openssl/evp.h>
David Benjamind98452d2015-06-16 14:16:23 -040052#include <openssl/hmac.h>
David Benjamin98193672016-03-25 18:07:11 -040053#include <openssl/nid.h>
David Benjamind98452d2015-06-16 14:16:23 -040054#include <openssl/rand.h>
David Benjamin1d5c83e2014-07-22 19:20:02 -040055#include <openssl/ssl.h>
Matt Braithwaited17d74d2016-08-17 20:10:28 -070056#include <openssl/x509.h>
David Benjamin1d5c83e2014-07-22 19:20:02 -040057
David Benjamin45fb1be2015-03-22 16:31:27 -040058#include <memory>
Steven Valdez0d62f262015-09-04 12:41:04 -040059#include <string>
David Benjaminc565ebb2015-04-03 04:06:36 -040060#include <vector>
David Benjamin45fb1be2015-03-22 16:31:27 -040061
Steven Valdezcb966542016-08-17 16:56:14 -040062#include "../../crypto/internal.h"
David Benjamin43ec06f2014-08-05 02:28:57 -040063#include "async_bio.h"
David Benjamin6fd297b2014-08-11 18:43:38 -040064#include "packeted_bio.h"
David Benjamin5a593af2014-08-11 19:51:50 -040065#include "test_config.h"
David Benjamin43ec06f2014-08-05 02:28:57 -040066
David Benjamin87c8a642015-02-21 01:54:29 -050067
Adam Langleyd519bf62016-12-12 11:16:44 -080068static CRYPTO_BUFFER_POOL *g_pool = nullptr;
69
David Benjamin87c8a642015-02-21 01:54:29 -050070#if !defined(OPENSSL_WINDOWS)
71static int closesocket(int sock) {
72 return close(sock);
73}
74
75static void PrintSocketError(const char *func) {
76 perror(func);
77}
78#else
79static void PrintSocketError(const char *func) {
80 fprintf(stderr, "%s: %d\n", func, WSAGetLastError());
81}
82#endif
83
David Benjaminc273d2c2015-02-09 12:59:46 -050084static int Usage(const char *program) {
David Benjamina7f333d2015-02-09 02:37:18 -050085 fprintf(stderr, "Usage: %s [flags...]\n", program);
David Benjamin1d5c83e2014-07-22 19:20:02 -040086 return 1;
87}
David Benjamin025b3d32014-07-01 19:53:04 -040088
David Benjamin2d445c02015-02-09 13:03:50 -050089struct TestState {
David Benjamin6c2563e2015-04-03 03:47:47 -040090 // async_bio is async BIO which pauses reads and writes.
91 BIO *async_bio = nullptr;
David Benjamin585d7a42016-06-02 14:58:00 -040092 // packeted_bio is the packeted BIO which simulates read timeouts.
93 BIO *packeted_bio = nullptr;
Matt Braithwaited17d74d2016-08-17 20:10:28 -070094 bssl::UniquePtr<EVP_PKEY> channel_id;
David Benjamin0d4db502015-03-23 18:46:05 -040095 bool cert_ready = false;
Matt Braithwaited17d74d2016-08-17 20:10:28 -070096 bssl::UniquePtr<SSL_SESSION> session;
97 bssl::UniquePtr<SSL_SESSION> pending_session;
David Benjamin0d4db502015-03-23 18:46:05 -040098 bool early_callback_called = false;
David Benjamin87e4acd2015-04-02 19:57:35 -040099 bool handshake_done = false;
David Benjaminb4d65fd2015-05-29 17:11:21 -0400100 // private_key is the underlying private key used when testing custom keys.
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700101 bssl::UniquePtr<EVP_PKEY> private_key;
nagendra modadugu3398dbf2015-08-07 14:07:52 -0700102 std::vector<uint8_t> private_key_result;
103 // private_key_retries is the number of times an asynchronous private key
104 // operation has been retried.
105 unsigned private_key_retries = 0;
David Benjaminba4594a2015-06-18 18:36:15 -0400106 bool got_new_session = false;
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700107 bssl::UniquePtr<SSL_SESSION> new_session;
David Benjamin25fe85b2016-08-09 20:00:32 -0400108 bool ticket_decrypt_done = false;
109 bool alpn_select_done = false;
Steven Valdez2d850622017-01-11 11:34:52 -0500110 bool is_resume = false;
Alessandro Ghedini958346a2016-12-20 19:42:15 +0000111 bool early_callback_ready = false;
David Benjamind9e07012015-02-09 03:04:34 -0500112};
113
David Benjamin2d445c02015-02-09 13:03:50 -0500114static void TestStateExFree(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
Adam Langley09505632015-07-30 18:10:13 -0700115 int index, long argl, void *argp) {
David Benjamin2d445c02015-02-09 13:03:50 -0500116 delete ((TestState *)ptr);
David Benjamind9e07012015-02-09 03:04:34 -0500117}
118
119static int g_config_index = 0;
David Benjamin2d445c02015-02-09 13:03:50 -0500120static int g_state_index = 0;
David Benjamin5a593af2014-08-11 19:51:50 -0400121
David Benjamin7e7a82d2016-05-20 20:12:42 -0400122static bool SetTestConfig(SSL *ssl, const TestConfig *config) {
David Benjamind9e07012015-02-09 03:04:34 -0500123 return SSL_set_ex_data(ssl, g_config_index, (void *)config) == 1;
David Benjamin5a593af2014-08-11 19:51:50 -0400124}
125
David Benjamin7e7a82d2016-05-20 20:12:42 -0400126static const TestConfig *GetTestConfig(const SSL *ssl) {
David Benjamind9e07012015-02-09 03:04:34 -0500127 return (const TestConfig *)SSL_get_ex_data(ssl, g_config_index);
David Benjamin5a593af2014-08-11 19:51:50 -0400128}
129
David Benjamin22050932015-11-23 13:44:48 -0500130static bool SetTestState(SSL *ssl, std::unique_ptr<TestState> state) {
131 // |SSL_set_ex_data| takes ownership of |state| only on success.
132 if (SSL_set_ex_data(ssl, g_state_index, state.get()) == 1) {
133 state.release();
David Benjamind9e07012015-02-09 03:04:34 -0500134 return true;
135 }
136 return false;
137}
138
David Benjamin87e4acd2015-04-02 19:57:35 -0400139static TestState *GetTestState(const SSL *ssl) {
David Benjamin2d445c02015-02-09 13:03:50 -0500140 return (TestState *)SSL_get_ex_data(ssl, g_state_index);
David Benjamin83f90402015-01-27 01:09:43 -0500141}
142
David Benjamin2c516452016-11-15 10:16:54 +0900143static bool LoadCertificate(bssl::UniquePtr<X509> *out_x509,
144 bssl::UniquePtr<STACK_OF(X509)> *out_chain,
145 const std::string &file) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700146 bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_file()));
David Benjaminacb6dcc2016-03-10 09:15:01 -0500147 if (!bio || !BIO_read_filename(bio.get(), file.c_str())) {
David Benjamin2c516452016-11-15 10:16:54 +0900148 return false;
David Benjaminacb6dcc2016-03-10 09:15:01 -0500149 }
David Benjamin2c516452016-11-15 10:16:54 +0900150
151 out_x509->reset(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
152 if (!*out_x509) {
153 return false;
154 }
155
156 out_chain->reset(sk_X509_new_null());
157 if (!*out_chain) {
158 return false;
159 }
160
161 // Keep reading the certificate chain.
162 for (;;) {
163 bssl::UniquePtr<X509> cert(
164 PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
165 if (!cert) {
166 break;
167 }
168
169 if (!sk_X509_push(out_chain->get(), cert.get())) {
170 return false;
171 }
172 cert.release(); // sk_X509_push takes ownership.
173 }
174
175 uint32_t err = ERR_peek_last_error();
176 if (ERR_GET_LIB(err) != ERR_LIB_PEM ||
177 ERR_GET_REASON(err) != PEM_R_NO_START_LINE) {
178 return false;
179}
180
181 ERR_clear_error();
182 return true;
David Benjaminacb6dcc2016-03-10 09:15:01 -0500183}
184
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700185static bssl::UniquePtr<EVP_PKEY> LoadPrivateKey(const std::string &file) {
186 bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_file()));
David Benjamina7f333d2015-02-09 02:37:18 -0500187 if (!bio || !BIO_read_filename(bio.get(), file.c_str())) {
188 return nullptr;
David Benjamina08e49d2014-08-24 01:46:07 -0400189 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700190 return bssl::UniquePtr<EVP_PKEY>(
191 PEM_read_bio_PrivateKey(bio.get(), NULL, NULL, NULL));
David Benjamina08e49d2014-08-24 01:46:07 -0400192}
193
Adam Langley2ff79332017-02-28 13:45:39 -0800194static bool FromHexDigit(uint8_t *out, char c) {
195 if ('0' <= c && c <= '9') {
196 *out = c - '0';
197 return true;
198 }
199 if ('a' <= c && c <= 'f') {
200 *out = c - 'a' + 10;
201 return true;
202 }
203 if ('A' <= c && c <= 'F') {
204 *out = c - 'A' + 10;
205 return true;
206 }
207 return false;
208}
209
210static bool HexDecode(std::string *out, const std::string &in) {
211 if ((in.size() & 1) != 0) {
212 return false;
213 }
214
215 std::unique_ptr<uint8_t[]> buf(new uint8_t[in.size() / 2]);
216 for (size_t i = 0; i < in.size() / 2; i++) {
217 uint8_t high, low;
218 if (!FromHexDigit(&high, in[i*2]) ||
219 !FromHexDigit(&low, in[i*2+1])) {
220 return false;
221 }
222 buf[i] = (high << 4) | low;
223 }
224
225 out->assign(reinterpret_cast<const char *>(buf.get()), in.size() / 2);
226 return true;
227}
228
229static std::vector<std::string> SplitParts(const std::string &in,
230 const char delim) {
231 std::vector<std::string> ret;
232 size_t start = 0;
233
234 for (size_t i = 0; i < in.size(); i++) {
235 if (in[i] == delim) {
236 ret.push_back(in.substr(start, i - start));
237 start = i + 1;
238 }
239 }
240
241 ret.push_back(in.substr(start, std::string::npos));
242 return ret;
243}
244
245static std::vector<std::string> DecodeHexStrings(
246 const std::string &hex_strings) {
247 std::vector<std::string> ret;
248 const std::vector<std::string> parts = SplitParts(hex_strings, ',');
249
250 for (const auto &part : parts) {
251 std::string binary;
252 if (!HexDecode(&binary, part)) {
253 fprintf(stderr, "Bad hex string: %s\n", part.c_str());
254 return ret;
255 }
256
257 ret.push_back(binary);
258 }
259
260 return ret;
261}
262
263static bssl::UniquePtr<STACK_OF(X509_NAME)> DecodeHexX509Names(
264 const std::string &hex_names) {
265 const std::vector<std::string> der_names = DecodeHexStrings(hex_names);
266 bssl::UniquePtr<STACK_OF(X509_NAME)> ret(sk_X509_NAME_new_null());
267
268 for (const auto &der_name : der_names) {
269 const uint8_t *const data =
270 reinterpret_cast<const uint8_t *>(der_name.data());
271 const uint8_t *derp = data;
272 bssl::UniquePtr<X509_NAME> name(
273 d2i_X509_NAME(nullptr, &derp, der_name.size()));
274 if (!name || derp != data + der_name.size()) {
275 fprintf(stderr, "Failed to parse X509_NAME.\n");
276 return nullptr;
277 }
278
279 if (!sk_X509_NAME_push(ret.get(), name.get())) {
280 return nullptr;
281 }
282 name.release();
283 }
284
285 return ret;
286}
287
David Benjaminb4d65fd2015-05-29 17:11:21 -0400288static ssl_private_key_result_t AsyncPrivateKeySign(
289 SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out,
David Benjamind3440b42016-07-14 14:52:41 -0400290 uint16_t signature_algorithm, const uint8_t *in, size_t in_len) {
David Benjaminb4d65fd2015-05-29 17:11:21 -0400291 TestState *test_state = GetTestState(ssl);
nagendra modadugu3398dbf2015-08-07 14:07:52 -0700292 if (!test_state->private_key_result.empty()) {
David Benjaminb4d65fd2015-05-29 17:11:21 -0400293 fprintf(stderr, "AsyncPrivateKeySign called with operation pending.\n");
294 abort();
295 }
296
David Benjamin69522112017-03-28 15:38:29 -0500297 bssl::UniquePtr<EVP_PKEY_CTX> ctx(
298 EVP_PKEY_CTX_new(test_state->private_key.get(), nullptr));
299 if (!ctx ||
300 !EVP_PKEY_sign_init(ctx.get())) {
301 return ssl_private_key_failure;
302 }
303
David Benjamind3440b42016-07-14 14:52:41 -0400304 // Determine the hash.
305 const EVP_MD *md;
306 switch (signature_algorithm) {
307 case SSL_SIGN_RSA_PKCS1_SHA1:
308 case SSL_SIGN_ECDSA_SHA1:
309 md = EVP_sha1();
310 break;
311 case SSL_SIGN_RSA_PKCS1_SHA256:
312 case SSL_SIGN_ECDSA_SECP256R1_SHA256:
313 case SSL_SIGN_RSA_PSS_SHA256:
314 md = EVP_sha256();
315 break;
316 case SSL_SIGN_RSA_PKCS1_SHA384:
317 case SSL_SIGN_ECDSA_SECP384R1_SHA384:
318 case SSL_SIGN_RSA_PSS_SHA384:
319 md = EVP_sha384();
320 break;
321 case SSL_SIGN_RSA_PKCS1_SHA512:
322 case SSL_SIGN_ECDSA_SECP521R1_SHA512:
323 case SSL_SIGN_RSA_PSS_SHA512:
324 md = EVP_sha512();
325 break;
326 case SSL_SIGN_RSA_PKCS1_MD5_SHA1:
327 md = EVP_md5_sha1();
328 break;
David Benjamin69522112017-03-28 15:38:29 -0500329 case SSL_SIGN_ED25519:
330 md = nullptr;
331 break;
David Benjamind3440b42016-07-14 14:52:41 -0400332 default:
333 fprintf(stderr, "Unknown signature algorithm %04x.\n",
334 signature_algorithm);
335 return ssl_private_key_failure;
336 }
337
David Benjamin69522112017-03-28 15:38:29 -0500338 if (md != nullptr &&
339 !EVP_PKEY_CTX_set_signature_md(ctx.get(), md)) {
David Benjaminb4d65fd2015-05-29 17:11:21 -0400340 return ssl_private_key_failure;
341 }
342
David Benjamind3440b42016-07-14 14:52:41 -0400343 // Configure additional signature parameters.
344 switch (signature_algorithm) {
345 case SSL_SIGN_RSA_PSS_SHA256:
346 case SSL_SIGN_RSA_PSS_SHA384:
347 case SSL_SIGN_RSA_PSS_SHA512:
David Benjamin69522112017-03-28 15:38:29 -0500348 if (!EVP_PKEY_CTX_set_rsa_padding(ctx.get(), RSA_PKCS1_PSS_PADDING) ||
349 !EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx.get(),
David Benjamind3440b42016-07-14 14:52:41 -0400350 -1 /* salt len = hash len */)) {
351 return ssl_private_key_failure;
352 }
353 }
354
David Benjaminb4d65fd2015-05-29 17:11:21 -0400355 // Write the signature into |test_state|.
356 size_t len = 0;
David Benjamin69522112017-03-28 15:38:29 -0500357 if (!EVP_PKEY_sign_message(ctx.get(), nullptr, &len, in, in_len)) {
David Benjaminb4d65fd2015-05-29 17:11:21 -0400358 return ssl_private_key_failure;
359 }
nagendra modadugu3398dbf2015-08-07 14:07:52 -0700360 test_state->private_key_result.resize(len);
David Benjamin69522112017-03-28 15:38:29 -0500361 if (!EVP_PKEY_sign_message(ctx.get(), test_state->private_key_result.data(),
362 &len, in, in_len)) {
David Benjaminb4d65fd2015-05-29 17:11:21 -0400363 return ssl_private_key_failure;
364 }
nagendra modadugu3398dbf2015-08-07 14:07:52 -0700365 test_state->private_key_result.resize(len);
David Benjaminb4d65fd2015-05-29 17:11:21 -0400366
David Benjamind3440b42016-07-14 14:52:41 -0400367 // The signature will be released asynchronously in |AsyncPrivateKeyComplete|.
David Benjaminb4d65fd2015-05-29 17:11:21 -0400368 return ssl_private_key_retry;
369}
370
nagendra modadugu3398dbf2015-08-07 14:07:52 -0700371static ssl_private_key_result_t AsyncPrivateKeyDecrypt(
372 SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out,
373 const uint8_t *in, size_t in_len) {
374 TestState *test_state = GetTestState(ssl);
375 if (!test_state->private_key_result.empty()) {
376 fprintf(stderr,
377 "AsyncPrivateKeyDecrypt called with operation pending.\n");
378 abort();
379 }
380
David Benjamin758d1272015-11-20 17:47:25 -0500381 RSA *rsa = EVP_PKEY_get0_RSA(test_state->private_key.get());
382 if (rsa == NULL) {
nagendra modadugu3398dbf2015-08-07 14:07:52 -0700383 fprintf(stderr,
384 "AsyncPrivateKeyDecrypt called with incorrect key type.\n");
385 abort();
386 }
nagendra modadugu3398dbf2015-08-07 14:07:52 -0700387 test_state->private_key_result.resize(RSA_size(rsa));
David Benjaminef14b2d2015-11-11 14:01:27 -0800388 if (!RSA_decrypt(rsa, out_len, test_state->private_key_result.data(),
nagendra modadugu3398dbf2015-08-07 14:07:52 -0700389 RSA_size(rsa), in, in_len, RSA_NO_PADDING)) {
390 return ssl_private_key_failure;
391 }
392
393 test_state->private_key_result.resize(*out_len);
394
David Benjamind3440b42016-07-14 14:52:41 -0400395 // The decryption will be released asynchronously in |AsyncPrivateComplete|.
nagendra modadugu3398dbf2015-08-07 14:07:52 -0700396 return ssl_private_key_retry;
397}
398
David Benjamind3440b42016-07-14 14:52:41 -0400399static ssl_private_key_result_t AsyncPrivateKeyComplete(
nagendra modadugu3398dbf2015-08-07 14:07:52 -0700400 SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out) {
401 TestState *test_state = GetTestState(ssl);
402 if (test_state->private_key_result.empty()) {
403 fprintf(stderr,
David Benjamind3440b42016-07-14 14:52:41 -0400404 "AsyncPrivateKeyComplete called without operation pending.\n");
nagendra modadugu3398dbf2015-08-07 14:07:52 -0700405 abort();
406 }
407
408 if (test_state->private_key_retries < 2) {
409 // Only return the decryption on the second attempt, to test both incomplete
410 // |decrypt| and |decrypt_complete|.
411 return ssl_private_key_retry;
412 }
413
414 if (max_out < test_state->private_key_result.size()) {
415 fprintf(stderr, "Output buffer too small.\n");
416 return ssl_private_key_failure;
417 }
David Benjamin17cf2cb2016-12-13 01:07:13 -0500418 OPENSSL_memcpy(out, test_state->private_key_result.data(),
419 test_state->private_key_result.size());
nagendra modadugu3398dbf2015-08-07 14:07:52 -0700420 *out_len = test_state->private_key_result.size();
421
422 test_state->private_key_result.clear();
423 test_state->private_key_retries = 0;
David Benjaminb4d65fd2015-05-29 17:11:21 -0400424 return ssl_private_key_success;
425}
426
427static const SSL_PRIVATE_KEY_METHOD g_async_private_key_method = {
David Benjamina232a712017-03-30 15:51:53 -0500428 nullptr /* type */,
429 nullptr /* max_signature_len */,
David Benjaminb4d65fd2015-05-29 17:11:21 -0400430 AsyncPrivateKeySign,
David Benjamind3440b42016-07-14 14:52:41 -0400431 nullptr /* sign_digest */,
nagendra modadugu3398dbf2015-08-07 14:07:52 -0700432 AsyncPrivateKeyDecrypt,
David Benjamind3440b42016-07-14 14:52:41 -0400433 AsyncPrivateKeyComplete,
David Benjaminb4d65fd2015-05-29 17:11:21 -0400434};
435
Steven Valdez0d62f262015-09-04 12:41:04 -0400436template<typename T>
Adam Langley10f97f32016-07-12 08:09:33 -0700437struct Free {
Steven Valdez0d62f262015-09-04 12:41:04 -0400438 void operator()(T *buf) {
439 free(buf);
440 }
441};
442
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700443static bool GetCertificate(SSL *ssl, bssl::UniquePtr<X509> *out_x509,
David Benjamin2c516452016-11-15 10:16:54 +0900444 bssl::UniquePtr<STACK_OF(X509)> *out_chain,
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700445 bssl::UniquePtr<EVP_PKEY> *out_pkey) {
David Benjamin7e7a82d2016-05-20 20:12:42 -0400446 const TestConfig *config = GetTestConfig(ssl);
Steven Valdez0d62f262015-09-04 12:41:04 -0400447
448 if (!config->digest_prefs.empty()) {
Adam Langley10f97f32016-07-12 08:09:33 -0700449 std::unique_ptr<char, Free<char>> digest_prefs(
Steven Valdez0d62f262015-09-04 12:41:04 -0400450 strdup(config->digest_prefs.c_str()));
Steven Valdez0d62f262015-09-04 12:41:04 -0400451 std::vector<int> digest_list;
452
453 for (;;) {
Adam Langley67251f22015-09-23 15:01:07 -0700454 char *token =
455 strtok(digest_list.empty() ? digest_prefs.get() : nullptr, ",");
Steven Valdez0d62f262015-09-04 12:41:04 -0400456 if (token == nullptr) {
457 break;
458 }
459
460 digest_list.push_back(EVP_MD_type(EVP_get_digestbyname(token)));
461 }
462
463 if (!SSL_set_private_key_digest_prefs(ssl, digest_list.data(),
464 digest_list.size())) {
465 return false;
466 }
467 }
468
David Benjaminca3d5452016-07-14 12:51:01 -0400469 if (!config->signing_prefs.empty()) {
470 std::vector<uint16_t> u16s(config->signing_prefs.begin(),
471 config->signing_prefs.end());
472 if (!SSL_set_signing_algorithm_prefs(ssl, u16s.data(), u16s.size())) {
473 return false;
474 }
475 }
476
David Benjaminb4d65fd2015-05-29 17:11:21 -0400477 if (!config->key_file.empty()) {
David Benjaminacb6dcc2016-03-10 09:15:01 -0500478 *out_pkey = LoadPrivateKey(config->key_file.c_str());
479 if (!*out_pkey) {
David Benjaminb4d65fd2015-05-29 17:11:21 -0400480 return false;
481 }
David Benjamin41fdbcd2015-02-09 03:13:35 -0500482 }
David Benjamin2c516452016-11-15 10:16:54 +0900483 if (!config->cert_file.empty() &&
484 !LoadCertificate(out_x509, out_chain, config->cert_file.c_str())) {
485 return false;
David Benjamin41fdbcd2015-02-09 03:13:35 -0500486 }
Paul Lietaraeeff2c2015-08-12 11:47:11 +0100487 if (!config->ocsp_response.empty() &&
Alessandro Ghedini559f0642016-12-07 12:55:32 +0000488 !SSL_set_ocsp_response(ssl, (const uint8_t *)config->ocsp_response.data(),
489 config->ocsp_response.size())) {
Paul Lietaraeeff2c2015-08-12 11:47:11 +0100490 return false;
491 }
David Benjamin41fdbcd2015-02-09 03:13:35 -0500492 return true;
493}
494
David Benjaminacb6dcc2016-03-10 09:15:01 -0500495static bool InstallCertificate(SSL *ssl) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700496 bssl::UniquePtr<X509> x509;
David Benjamin2c516452016-11-15 10:16:54 +0900497 bssl::UniquePtr<STACK_OF(X509)> chain;
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700498 bssl::UniquePtr<EVP_PKEY> pkey;
David Benjamin2c516452016-11-15 10:16:54 +0900499 if (!GetCertificate(ssl, &x509, &chain, &pkey)) {
David Benjaminacb6dcc2016-03-10 09:15:01 -0500500 return false;
501 }
502
503 if (pkey) {
504 TestState *test_state = GetTestState(ssl);
David Benjamin7e7a82d2016-05-20 20:12:42 -0400505 const TestConfig *config = GetTestConfig(ssl);
David Benjaminacb6dcc2016-03-10 09:15:01 -0500506 if (config->async) {
507 test_state->private_key = std::move(pkey);
508 SSL_set_private_key_method(ssl, &g_async_private_key_method);
509 } else if (!SSL_use_PrivateKey(ssl, pkey.get())) {
510 return false;
511 }
512 }
513
514 if (x509 && !SSL_use_certificate(ssl, x509.get())) {
515 return false;
516 }
517
David Benjamin2c516452016-11-15 10:16:54 +0900518 if (sk_X509_num(chain.get()) > 0 &&
519 !SSL_set1_chain(ssl, chain.get())) {
520 return false;
521 }
522
David Benjaminacb6dcc2016-03-10 09:15:01 -0500523 return true;
524}
525
Alessandro Ghedini57e81e62017-03-14 23:36:00 +0000526static enum ssl_select_cert_result_t SelectCertificateCallback(
527 const SSL_CLIENT_HELLO *client_hello) {
David Benjamin731058e2016-12-03 23:15:13 -0500528 const TestConfig *config = GetTestConfig(client_hello->ssl);
529 GetTestState(client_hello->ssl)->early_callback_called = true;
David Benjamin5a593af2014-08-11 19:51:50 -0400530
David Benjamin6f5c0f42015-02-24 01:23:21 -0500531 if (!config->expected_server_name.empty()) {
532 const uint8_t *extension_data;
533 size_t extension_len;
534 CBS extension, server_name_list, host_name;
535 uint8_t name_type;
536
David Benjamin731058e2016-12-03 23:15:13 -0500537 if (!SSL_early_callback_ctx_extension_get(
538 client_hello, TLSEXT_TYPE_server_name, &extension_data,
539 &extension_len)) {
David Benjamin6f5c0f42015-02-24 01:23:21 -0500540 fprintf(stderr, "Could not find server_name extension.\n");
Alessandro Ghedini57e81e62017-03-14 23:36:00 +0000541 return ssl_select_cert_error;
David Benjamin6f5c0f42015-02-24 01:23:21 -0500542 }
543
544 CBS_init(&extension, extension_data, extension_len);
545 if (!CBS_get_u16_length_prefixed(&extension, &server_name_list) ||
546 CBS_len(&extension) != 0 ||
547 !CBS_get_u8(&server_name_list, &name_type) ||
548 name_type != TLSEXT_NAMETYPE_host_name ||
549 !CBS_get_u16_length_prefixed(&server_name_list, &host_name) ||
550 CBS_len(&server_name_list) != 0) {
551 fprintf(stderr, "Could not decode server_name extension.\n");
Alessandro Ghedini57e81e62017-03-14 23:36:00 +0000552 return ssl_select_cert_error;
David Benjamin6f5c0f42015-02-24 01:23:21 -0500553 }
554
555 if (!CBS_mem_equal(&host_name,
556 (const uint8_t*)config->expected_server_name.data(),
557 config->expected_server_name.size())) {
558 fprintf(stderr, "Server name mismatch.\n");
559 }
David Benjamin7b030512014-07-08 17:30:11 -0400560 }
David Benjamin8f2c20e2014-07-09 09:30:38 -0400561
David Benjamin6f5c0f42015-02-24 01:23:21 -0500562 if (config->fail_early_callback) {
Alessandro Ghedini57e81e62017-03-14 23:36:00 +0000563 return ssl_select_cert_error;
David Benjamin7b030512014-07-08 17:30:11 -0400564 }
David Benjamin8f2c20e2014-07-09 09:30:38 -0400565
David Benjamin6f5c0f42015-02-24 01:23:21 -0500566 // Install the certificate in the early callback.
567 if (config->use_early_callback) {
Alessandro Ghedini958346a2016-12-20 19:42:15 +0000568 bool early_callback_ready =
569 GetTestState(client_hello->ssl)->early_callback_ready;
570 if (config->async && !early_callback_ready) {
David Benjamin6f5c0f42015-02-24 01:23:21 -0500571 // Install the certificate asynchronously.
Alessandro Ghedini57e81e62017-03-14 23:36:00 +0000572 return ssl_select_cert_retry;
David Benjamin6f5c0f42015-02-24 01:23:21 -0500573 }
David Benjamin731058e2016-12-03 23:15:13 -0500574 if (!InstallCertificate(client_hello->ssl)) {
Alessandro Ghedini57e81e62017-03-14 23:36:00 +0000575 return ssl_select_cert_error;
David Benjamin6f5c0f42015-02-24 01:23:21 -0500576 }
David Benjamin7b030512014-07-08 17:30:11 -0400577 }
Alessandro Ghedini57e81e62017-03-14 23:36:00 +0000578 return ssl_select_cert_success;
David Benjamin8f2c20e2014-07-09 09:30:38 -0400579}
David Benjamin025b3d32014-07-01 19:53:04 -0400580
David Benjamin5edfc8c2016-12-10 15:46:58 -0500581static bool CheckCertificateRequest(SSL *ssl) {
582 const TestConfig *config = GetTestConfig(ssl);
583
584 if (!config->expected_certificate_types.empty()) {
585 const uint8_t *certificate_types;
586 size_t certificate_types_len =
587 SSL_get0_certificate_types(ssl, &certificate_types);
588 if (certificate_types_len != config->expected_certificate_types.size() ||
David Benjamin17cf2cb2016-12-13 01:07:13 -0500589 OPENSSL_memcmp(certificate_types,
590 config->expected_certificate_types.data(),
591 certificate_types_len) != 0) {
David Benjamin5edfc8c2016-12-10 15:46:58 -0500592 fprintf(stderr, "certificate types mismatch\n");
593 return false;
594 }
595 }
596
Adam Langley2ff79332017-02-28 13:45:39 -0800597 if (!config->expected_client_ca_list.empty()) {
598 bssl::UniquePtr<STACK_OF(X509_NAME)> expected =
599 DecodeHexX509Names(config->expected_client_ca_list);
600 const size_t num_expected = sk_X509_NAME_num(expected.get());
601
602 const STACK_OF(X509_NAME) *received = SSL_get_client_CA_list(ssl);
603 const size_t num_received = sk_X509_NAME_num(received);
604
605 if (num_received != num_expected) {
606 fprintf(stderr, "expected %u names in CertificateRequest but got %u\n",
607 static_cast<unsigned>(num_expected),
608 static_cast<unsigned>(num_received));
609 return false;
610 }
611
612 for (size_t i = 0; i < num_received; i++) {
613 if (X509_NAME_cmp(sk_X509_NAME_value(received, i),
614 sk_X509_NAME_value(expected.get(), i)) != 0) {
615 fprintf(stderr, "names in CertificateRequest differ at index #%d\n",
616 static_cast<unsigned>(i));
617 return false;
618 }
619 }
Adam Langleyd6c22ee2017-03-02 12:56:32 -0800620
621 STACK_OF(CRYPTO_BUFFER) *buffers = SSL_get0_server_requested_CAs(ssl);
622 if (sk_CRYPTO_BUFFER_num(buffers) != num_received) {
623 fprintf(stderr,
624 "Mismatch between SSL_get_server_requested_CAs and "
625 "SSL_get_client_CA_list.\n");
626 return false;
627 }
Adam Langley2ff79332017-02-28 13:45:39 -0800628 }
629
David Benjamin5edfc8c2016-12-10 15:46:58 -0500630 return true;
631}
632
David Benjaminacb6dcc2016-03-10 09:15:01 -0500633static int ClientCertCallback(SSL *ssl, X509 **out_x509, EVP_PKEY **out_pkey) {
David Benjamin5edfc8c2016-12-10 15:46:58 -0500634 if (!CheckCertificateRequest(ssl)) {
635 return -1;
636 }
637
David Benjamin7e7a82d2016-05-20 20:12:42 -0400638 if (GetTestConfig(ssl)->async && !GetTestState(ssl)->cert_ready) {
David Benjaminacb6dcc2016-03-10 09:15:01 -0500639 return -1;
640 }
641
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700642 bssl::UniquePtr<X509> x509;
David Benjamin2c516452016-11-15 10:16:54 +0900643 bssl::UniquePtr<STACK_OF(X509)> chain;
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700644 bssl::UniquePtr<EVP_PKEY> pkey;
David Benjamin2c516452016-11-15 10:16:54 +0900645 if (!GetCertificate(ssl, &x509, &chain, &pkey)) {
David Benjaminacb6dcc2016-03-10 09:15:01 -0500646 return -1;
647 }
648
649 // Return zero for no certificate.
650 if (!x509) {
651 return 0;
652 }
653
David Benjamin2c516452016-11-15 10:16:54 +0900654 // Chains and asynchronous private keys are not supported with client_cert_cb.
David Benjaminacb6dcc2016-03-10 09:15:01 -0500655 *out_x509 = x509.release();
656 *out_pkey = pkey.release();
657 return 1;
658}
659
David Benjamin5edfc8c2016-12-10 15:46:58 -0500660static int CertCallback(SSL *ssl, void *arg) {
661 const TestConfig *config = GetTestConfig(ssl);
662
663 // Check the CertificateRequest metadata is as expected.
664 if (!SSL_is_server(ssl) && !CheckCertificateRequest(ssl)) {
665 return -1;
666 }
667
668 if (config->fail_cert_callback) {
669 return 0;
670 }
671
672 // The certificate will be installed via other means.
673 if (!config->async || config->use_early_callback) {
674 return 1;
675 }
676
677 if (!GetTestState(ssl)->cert_ready) {
678 return -1;
679 }
680 if (!InstallCertificate(ssl)) {
681 return 0;
682 }
683 return 1;
684}
685
Paul Lietar8f1c2682015-08-18 12:21:54 +0100686static int VerifySucceed(X509_STORE_CTX *store_ctx, void *arg) {
687 SSL* ssl = (SSL*)X509_STORE_CTX_get_ex_data(store_ctx,
688 SSL_get_ex_data_X509_STORE_CTX_idx());
David Benjamin7e7a82d2016-05-20 20:12:42 -0400689 const TestConfig *config = GetTestConfig(ssl);
Paul Lietar8f1c2682015-08-18 12:21:54 +0100690
691 if (!config->expected_ocsp_response.empty()) {
692 const uint8_t *data;
693 size_t len;
694 SSL_get0_ocsp_response(ssl, &data, &len);
695 if (len == 0) {
696 fprintf(stderr, "OCSP response not available in verify callback\n");
697 return 0;
698 }
699 }
700
David Benjamin67666e72014-07-12 15:47:52 -0400701 return 1;
702}
703
Paul Lietar8f1c2682015-08-18 12:21:54 +0100704static int VerifyFail(X509_STORE_CTX *store_ctx, void *arg) {
705 store_ctx->error = X509_V_ERR_APPLICATION_VERIFICATION;
706 return 0;
707}
708
David Benjaminc273d2c2015-02-09 12:59:46 -0500709static int NextProtosAdvertisedCallback(SSL *ssl, const uint8_t **out,
710 unsigned int *out_len, void *arg) {
David Benjamin7e7a82d2016-05-20 20:12:42 -0400711 const TestConfig *config = GetTestConfig(ssl);
David Benjaminc273d2c2015-02-09 12:59:46 -0500712 if (config->advertise_npn.empty()) {
David Benjamin1f5f62b2014-07-12 16:18:02 -0400713 return SSL_TLSEXT_ERR_NOACK;
David Benjaminc273d2c2015-02-09 12:59:46 -0500714 }
David Benjamin1f5f62b2014-07-12 16:18:02 -0400715
David Benjamin5a593af2014-08-11 19:51:50 -0400716 *out = (const uint8_t*)config->advertise_npn.data();
717 *out_len = config->advertise_npn.size();
David Benjamin1f5f62b2014-07-12 16:18:02 -0400718 return SSL_TLSEXT_ERR_OK;
719}
720
David Benjaminc273d2c2015-02-09 12:59:46 -0500721static int NextProtoSelectCallback(SSL* ssl, uint8_t** out, uint8_t* outlen,
David Benjamin8b368412015-03-14 01:54:17 -0400722 const uint8_t* in, unsigned inlen, void* arg) {
David Benjamin7e7a82d2016-05-20 20:12:42 -0400723 const TestConfig *config = GetTestConfig(ssl);
David Benjaminc273d2c2015-02-09 12:59:46 -0500724 if (config->select_next_proto.empty()) {
David Benjamin7e3305e2014-07-28 14:52:32 -0400725 return SSL_TLSEXT_ERR_NOACK;
David Benjaminc273d2c2015-02-09 12:59:46 -0500726 }
David Benjamin7e3305e2014-07-28 14:52:32 -0400727
David Benjamin5a593af2014-08-11 19:51:50 -0400728 *out = (uint8_t*)config->select_next_proto.data();
729 *outlen = config->select_next_proto.size();
David Benjamin7e3305e2014-07-28 14:52:32 -0400730 return SSL_TLSEXT_ERR_OK;
731}
732
David Benjaminc273d2c2015-02-09 12:59:46 -0500733static int AlpnSelectCallback(SSL* ssl, const uint8_t** out, uint8_t* outlen,
734 const uint8_t* in, unsigned inlen, void* arg) {
David Benjamin25fe85b2016-08-09 20:00:32 -0400735 if (GetTestState(ssl)->alpn_select_done) {
736 fprintf(stderr, "AlpnSelectCallback called after completion.\n");
737 exit(1);
738 }
739
740 GetTestState(ssl)->alpn_select_done = true;
741
David Benjamin7e7a82d2016-05-20 20:12:42 -0400742 const TestConfig *config = GetTestConfig(ssl);
David Benjamin594e7d22016-03-17 17:49:56 -0400743 if (config->decline_alpn) {
David Benjaminae2888f2014-09-06 12:58:58 -0400744 return SSL_TLSEXT_ERR_NOACK;
David Benjaminc273d2c2015-02-09 12:59:46 -0500745 }
David Benjaminae2888f2014-09-06 12:58:58 -0400746
747 if (!config->expected_advertised_alpn.empty() &&
748 (config->expected_advertised_alpn.size() != inlen ||
David Benjamin17cf2cb2016-12-13 01:07:13 -0500749 OPENSSL_memcmp(config->expected_advertised_alpn.data(), in, inlen) !=
750 0)) {
David Benjaminae2888f2014-09-06 12:58:58 -0400751 fprintf(stderr, "bad ALPN select callback inputs\n");
752 exit(1);
753 }
754
755 *out = (const uint8_t*)config->select_alpn.data();
756 *outlen = config->select_alpn.size();
Steven Valdez2d850622017-01-11 11:34:52 -0500757 if (GetTestState(ssl)->is_resume && config->select_resume_alpn.size() > 0) {
758 *out = (const uint8_t*)config->select_resume_alpn.data();
759 *outlen = config->select_resume_alpn.size();
760 }
David Benjaminae2888f2014-09-06 12:58:58 -0400761 return SSL_TLSEXT_ERR_OK;
762}
763
David Benjaminc273d2c2015-02-09 12:59:46 -0500764static unsigned PskClientCallback(SSL *ssl, const char *hint,
765 char *out_identity,
766 unsigned max_identity_len,
767 uint8_t *out_psk, unsigned max_psk_len) {
David Benjamin7e7a82d2016-05-20 20:12:42 -0400768 const TestConfig *config = GetTestConfig(ssl);
David Benjamin48cae082014-10-27 01:06:24 -0400769
David Benjamin78679342016-09-16 19:42:05 -0400770 if (config->psk_identity.empty()) {
771 if (hint != nullptr) {
772 fprintf(stderr, "Server PSK hint was non-null.\n");
773 return 0;
774 }
775 } else if (hint == nullptr ||
776 strcmp(hint, config->psk_identity.c_str()) != 0) {
David Benjamin48cae082014-10-27 01:06:24 -0400777 fprintf(stderr, "Server PSK hint did not match.\n");
778 return 0;
779 }
780
781 // Account for the trailing '\0' for the identity.
782 if (config->psk_identity.size() >= max_identity_len ||
783 config->psk.size() > max_psk_len) {
784 fprintf(stderr, "PSK buffers too small\n");
785 return 0;
786 }
787
788 BUF_strlcpy(out_identity, config->psk_identity.c_str(),
789 max_identity_len);
David Benjamin17cf2cb2016-12-13 01:07:13 -0500790 OPENSSL_memcpy(out_psk, config->psk.data(), config->psk.size());
David Benjamin48cae082014-10-27 01:06:24 -0400791 return config->psk.size();
792}
793
David Benjaminc273d2c2015-02-09 12:59:46 -0500794static unsigned PskServerCallback(SSL *ssl, const char *identity,
795 uint8_t *out_psk, unsigned max_psk_len) {
David Benjamin7e7a82d2016-05-20 20:12:42 -0400796 const TestConfig *config = GetTestConfig(ssl);
David Benjamin48cae082014-10-27 01:06:24 -0400797
798 if (strcmp(identity, config->psk_identity.c_str()) != 0) {
799 fprintf(stderr, "Client PSK identity did not match.\n");
800 return 0;
801 }
802
803 if (config->psk.size() > max_psk_len) {
804 fprintf(stderr, "PSK buffers too small\n");
805 return 0;
806 }
807
David Benjamin17cf2cb2016-12-13 01:07:13 -0500808 OPENSSL_memcpy(out_psk, config->psk.data(), config->psk.size());
David Benjamin48cae082014-10-27 01:06:24 -0400809 return config->psk.size();
810}
811
David Benjamin1b22f852016-10-27 16:36:32 -0400812static timeval g_clock;
813
David Benjamin4d2e7ce2015-05-08 13:29:45 -0400814static void CurrentTimeCallback(const SSL *ssl, timeval *out_clock) {
David Benjamin1b22f852016-10-27 16:36:32 -0400815 *out_clock = g_clock;
David Benjamin377fc312015-01-26 00:22:12 -0500816}
817
David Benjaminc273d2c2015-02-09 12:59:46 -0500818static void ChannelIdCallback(SSL *ssl, EVP_PKEY **out_pkey) {
David Benjamin2d445c02015-02-09 13:03:50 -0500819 *out_pkey = GetTestState(ssl)->channel_id.release();
David Benjamind9e07012015-02-09 03:04:34 -0500820}
821
David Benjaminc273d2c2015-02-09 12:59:46 -0500822static SSL_SESSION *GetSessionCallback(SSL *ssl, uint8_t *data, int len,
823 int *copy) {
David Benjamin2d445c02015-02-09 13:03:50 -0500824 TestState *async_state = GetTestState(ssl);
David Benjamin1b8b6912015-02-09 04:28:16 -0500825 if (async_state->session) {
826 *copy = 0;
827 return async_state->session.release();
828 } else if (async_state->pending_session) {
829 return SSL_magic_pending_session_ptr();
830 } else {
831 return NULL;
832 }
833}
834
David Benjamin731058e2016-12-03 23:15:13 -0500835static int DDoSCallback(const SSL_CLIENT_HELLO *client_hello) {
836 const TestConfig *config = GetTestConfig(client_hello->ssl);
Adam Langley524e7172015-02-20 16:04:00 -0800837 static int callback_num = 0;
838
839 callback_num++;
840 if (config->fail_ddos_callback ||
841 (config->fail_second_ddos_callback && callback_num == 2)) {
842 return 0;
843 }
844 return 1;
845}
846
David Benjamin87e4acd2015-04-02 19:57:35 -0400847static void InfoCallback(const SSL *ssl, int type, int val) {
848 if (type == SSL_CB_HANDSHAKE_DONE) {
David Benjamin7e7a82d2016-05-20 20:12:42 -0400849 if (GetTestConfig(ssl)->handshake_never_done) {
David Benjamin7a4aaa42016-09-20 17:58:14 -0400850 fprintf(stderr, "Handshake unexpectedly completed.\n");
David Benjamin87e4acd2015-04-02 19:57:35 -0400851 // Abort before any expected error code is printed, to ensure the overall
852 // test fails.
853 abort();
854 }
855 GetTestState(ssl)->handshake_done = true;
David Benjamin25fe85b2016-08-09 20:00:32 -0400856
857 // Callbacks may be called again on a new handshake.
858 GetTestState(ssl)->ticket_decrypt_done = false;
859 GetTestState(ssl)->alpn_select_done = false;
David Benjamin87e4acd2015-04-02 19:57:35 -0400860 }
861}
862
David Benjaminba4594a2015-06-18 18:36:15 -0400863static int NewSessionCallback(SSL *ssl, SSL_SESSION *session) {
864 GetTestState(ssl)->got_new_session = true;
Steven Valdez4aa154e2016-07-29 14:32:55 -0400865 GetTestState(ssl)->new_session.reset(session);
David Benjaminba4594a2015-06-18 18:36:15 -0400866 return 1;
867}
868
David Benjamind98452d2015-06-16 14:16:23 -0400869static int TicketKeyCallback(SSL *ssl, uint8_t *key_name, uint8_t *iv,
870 EVP_CIPHER_CTX *ctx, HMAC_CTX *hmac_ctx,
871 int encrypt) {
David Benjamin25fe85b2016-08-09 20:00:32 -0400872 if (!encrypt) {
873 if (GetTestState(ssl)->ticket_decrypt_done) {
874 fprintf(stderr, "TicketKeyCallback called after completion.\n");
875 return -1;
876 }
877
878 GetTestState(ssl)->ticket_decrypt_done = true;
879 }
880
David Benjamind98452d2015-06-16 14:16:23 -0400881 // This is just test code, so use the all-zeros key.
882 static const uint8_t kZeros[16] = {0};
883
884 if (encrypt) {
David Benjamin17cf2cb2016-12-13 01:07:13 -0500885 OPENSSL_memcpy(key_name, kZeros, sizeof(kZeros));
David Benjamind98452d2015-06-16 14:16:23 -0400886 RAND_bytes(iv, 16);
David Benjamin17cf2cb2016-12-13 01:07:13 -0500887 } else if (OPENSSL_memcmp(key_name, kZeros, 16) != 0) {
David Benjamind98452d2015-06-16 14:16:23 -0400888 return 0;
889 }
890
891 if (!HMAC_Init_ex(hmac_ctx, kZeros, sizeof(kZeros), EVP_sha256(), NULL) ||
892 !EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, kZeros, iv, encrypt)) {
893 return -1;
894 }
895
896 if (!encrypt) {
David Benjamin7e7a82d2016-05-20 20:12:42 -0400897 return GetTestConfig(ssl)->renew_ticket ? 2 : 1;
David Benjamind98452d2015-06-16 14:16:23 -0400898 }
899 return 1;
900}
901
Adam Langley09505632015-07-30 18:10:13 -0700902// kCustomExtensionValue is the extension value that the custom extension
903// callbacks will add.
Adam Langleyc5b23a12015-07-30 18:19:26 -0700904static const uint16_t kCustomExtensionValue = 1234;
Adam Langley09505632015-07-30 18:10:13 -0700905static void *const kCustomExtensionAddArg =
906 reinterpret_cast<void *>(kCustomExtensionValue);
907static void *const kCustomExtensionParseArg =
908 reinterpret_cast<void *>(kCustomExtensionValue + 1);
909static const char kCustomExtensionContents[] = "custom extension";
910
911static int CustomExtensionAddCallback(SSL *ssl, unsigned extension_value,
912 const uint8_t **out, size_t *out_len,
913 int *out_alert_value, void *add_arg) {
914 if (extension_value != kCustomExtensionValue ||
915 add_arg != kCustomExtensionAddArg) {
916 abort();
917 }
918
David Benjamin7e7a82d2016-05-20 20:12:42 -0400919 if (GetTestConfig(ssl)->custom_extension_skip) {
Adam Langley09505632015-07-30 18:10:13 -0700920 return 0;
921 }
David Benjamin7e7a82d2016-05-20 20:12:42 -0400922 if (GetTestConfig(ssl)->custom_extension_fail_add) {
Adam Langley09505632015-07-30 18:10:13 -0700923 return -1;
924 }
925
926 *out = reinterpret_cast<const uint8_t*>(kCustomExtensionContents);
927 *out_len = sizeof(kCustomExtensionContents) - 1;
928
929 return 1;
930}
931
932static void CustomExtensionFreeCallback(SSL *ssl, unsigned extension_value,
933 const uint8_t *out, void *add_arg) {
934 if (extension_value != kCustomExtensionValue ||
935 add_arg != kCustomExtensionAddArg ||
936 out != reinterpret_cast<const uint8_t *>(kCustomExtensionContents)) {
937 abort();
938 }
939}
940
941static int CustomExtensionParseCallback(SSL *ssl, unsigned extension_value,
942 const uint8_t *contents,
943 size_t contents_len,
944 int *out_alert_value, void *parse_arg) {
945 if (extension_value != kCustomExtensionValue ||
946 parse_arg != kCustomExtensionParseArg) {
947 abort();
948 }
949
950 if (contents_len != sizeof(kCustomExtensionContents) - 1 ||
David Benjamin17cf2cb2016-12-13 01:07:13 -0500951 OPENSSL_memcmp(contents, kCustomExtensionContents, contents_len) != 0) {
Adam Langley09505632015-07-30 18:10:13 -0700952 *out_alert_value = SSL_AD_DECODE_ERROR;
953 return 0;
954 }
955
956 return 1;
957}
958
David Benjamin8b176712016-10-27 21:51:24 -0400959static int ServerNameCallback(SSL *ssl, int *out_alert, void *arg) {
960 // SNI must be accessible from the SNI callback.
961 const TestConfig *config = GetTestConfig(ssl);
962 const char *server_name = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
963 if (server_name == nullptr ||
964 std::string(server_name) != config->expected_server_name) {
965 fprintf(stderr, "servername mismatch (got %s; want %s)\n", server_name,
966 config->expected_server_name.c_str());
967 return SSL_TLSEXT_ERR_ALERT_FATAL;
968 }
969
970 return SSL_TLSEXT_ERR_OK;
971}
972
David Benjamin87c8a642015-02-21 01:54:29 -0500973// Connect returns a new socket connected to localhost on |port| or -1 on
974// error.
975static int Connect(uint16_t port) {
976 int sock = socket(AF_INET, SOCK_STREAM, 0);
977 if (sock == -1) {
978 PrintSocketError("socket");
979 return -1;
980 }
981 int nodelay = 1;
982 if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
983 reinterpret_cast<const char*>(&nodelay), sizeof(nodelay)) != 0) {
984 PrintSocketError("setsockopt");
985 closesocket(sock);
986 return -1;
987 }
988 sockaddr_in sin;
David Benjamin17cf2cb2016-12-13 01:07:13 -0500989 OPENSSL_memset(&sin, 0, sizeof(sin));
David Benjamin87c8a642015-02-21 01:54:29 -0500990 sin.sin_family = AF_INET;
991 sin.sin_port = htons(port);
992 if (!inet_pton(AF_INET, "127.0.0.1", &sin.sin_addr)) {
993 PrintSocketError("inet_pton");
994 closesocket(sock);
995 return -1;
996 }
997 if (connect(sock, reinterpret_cast<const sockaddr*>(&sin),
998 sizeof(sin)) != 0) {
999 PrintSocketError("connect");
1000 closesocket(sock);
1001 return -1;
1002 }
1003 return sock;
1004}
1005
1006class SocketCloser {
1007 public:
1008 explicit SocketCloser(int sock) : sock_(sock) {}
1009 ~SocketCloser() {
1010 // Half-close and drain the socket before releasing it. This seems to be
1011 // necessary for graceful shutdown on Windows. It will also avoid write
1012 // failures in the test runner.
1013#if defined(OPENSSL_WINDOWS)
1014 shutdown(sock_, SD_SEND);
1015#else
1016 shutdown(sock_, SHUT_WR);
1017#endif
1018 while (true) {
1019 char buf[1024];
1020 if (recv(sock_, buf, sizeof(buf), 0) <= 0) {
1021 break;
1022 }
1023 }
1024 closesocket(sock_);
1025 }
1026
1027 private:
1028 const int sock_;
1029};
1030
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001031static bssl::UniquePtr<SSL_CTX> SetupCtx(const TestConfig *config) {
1032 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(
David Benjamina7f333d2015-02-09 02:37:18 -05001033 config->is_dtls ? DTLS_method() : TLS_method()));
1034 if (!ssl_ctx) {
1035 return nullptr;
David Benjamin025b3d32014-07-01 19:53:04 -04001036 }
1037
Adam Langleyd519bf62016-12-12 11:16:44 -08001038 SSL_CTX_set0_buffer_pool(ssl_ctx.get(), g_pool);
1039
David Benjamin3cfeb952017-03-01 16:48:38 -05001040 // Enable SSL 3.0 and TLS 1.3 for tests.
David Benjamin2dc02042016-09-19 19:57:37 -04001041 if (!config->is_dtls &&
David Benjamin3cfeb952017-03-01 16:48:38 -05001042 (!SSL_CTX_set_min_proto_version(ssl_ctx.get(), SSL3_VERSION) ||
1043 !SSL_CTX_set_max_proto_version(ssl_ctx.get(), TLS1_3_VERSION))) {
David Benjamin2dc02042016-09-19 19:57:37 -04001044 return nullptr;
Nick Harper1fd39d82016-06-14 18:14:35 -07001045 }
1046
Adam Langleycef75832015-09-03 14:51:12 -07001047 std::string cipher_list = "ALL";
1048 if (!config->cipher.empty()) {
1049 cipher_list = config->cipher;
1050 SSL_CTX_set_options(ssl_ctx.get(), SSL_OP_CIPHER_SERVER_PREFERENCE);
1051 }
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -08001052 if (!SSL_CTX_set_strict_cipher_list(ssl_ctx.get(), cipher_list.c_str())) {
Adam Langleycef75832015-09-03 14:51:12 -07001053 return nullptr;
1054 }
1055
David Benjamin1b8b6912015-02-09 04:28:16 -05001056 if (config->async && config->is_server) {
1057 // Disable the internal session cache. To test asynchronous session lookup,
1058 // we use an external session cache.
1059 SSL_CTX_set_session_cache_mode(
1060 ssl_ctx.get(), SSL_SESS_CACHE_BOTH | SSL_SESS_CACHE_NO_INTERNAL);
David Benjaminc273d2c2015-02-09 12:59:46 -05001061 SSL_CTX_sess_set_get_cb(ssl_ctx.get(), GetSessionCallback);
David Benjamin1b8b6912015-02-09 04:28:16 -05001062 } else {
1063 SSL_CTX_set_session_cache_mode(ssl_ctx.get(), SSL_SESS_CACHE_BOTH);
1064 }
David Benjamin1d5c83e2014-07-22 19:20:02 -04001065
David Benjamind4c2bce2015-10-17 12:28:18 -04001066 SSL_CTX_set_select_certificate_cb(ssl_ctx.get(), SelectCertificateCallback);
David Benjamin8f2c20e2014-07-09 09:30:38 -04001067
David Benjaminacb6dcc2016-03-10 09:15:01 -05001068 if (config->use_old_client_cert_callback) {
1069 SSL_CTX_set_client_cert_cb(ssl_ctx.get(), ClientCertCallback);
1070 }
1071
David Benjamin1f5f62b2014-07-12 16:18:02 -04001072 SSL_CTX_set_next_protos_advertised_cb(
David Benjaminc273d2c2015-02-09 12:59:46 -05001073 ssl_ctx.get(), NextProtosAdvertisedCallback, NULL);
David Benjaminae2888f2014-09-06 12:58:58 -04001074 if (!config->select_next_proto.empty()) {
David Benjaminc273d2c2015-02-09 12:59:46 -05001075 SSL_CTX_set_next_proto_select_cb(ssl_ctx.get(), NextProtoSelectCallback,
David Benjamina7f333d2015-02-09 02:37:18 -05001076 NULL);
David Benjaminae2888f2014-09-06 12:58:58 -04001077 }
1078
Steven Valdez2d850622017-01-11 11:34:52 -05001079 if (!config->select_alpn.empty() || !config->select_resume_alpn.empty() ||
1080 config->decline_alpn) {
David Benjaminc273d2c2015-02-09 12:59:46 -05001081 SSL_CTX_set_alpn_select_cb(ssl_ctx.get(), AlpnSelectCallback, NULL);
David Benjaminae2888f2014-09-06 12:58:58 -04001082 }
David Benjamin1f5f62b2014-07-12 16:18:02 -04001083
David Benjaminc273d2c2015-02-09 12:59:46 -05001084 SSL_CTX_set_channel_id_cb(ssl_ctx.get(), ChannelIdCallback);
David Benjamina08e49d2014-08-24 01:46:07 -04001085
David Benjamin1b22f852016-10-27 16:36:32 -04001086 SSL_CTX_set_current_time_cb(ssl_ctx.get(), CurrentTimeCallback);
David Benjamin377fc312015-01-26 00:22:12 -05001087
David Benjamin87e4acd2015-04-02 19:57:35 -04001088 SSL_CTX_set_info_callback(ssl_ctx.get(), InfoCallback);
David Benjaminba4594a2015-06-18 18:36:15 -04001089 SSL_CTX_sess_set_new_cb(ssl_ctx.get(), NewSessionCallback);
David Benjamin87e4acd2015-04-02 19:57:35 -04001090
David Benjamind98452d2015-06-16 14:16:23 -04001091 if (config->use_ticket_callback) {
1092 SSL_CTX_set_tlsext_ticket_key_cb(ssl_ctx.get(), TicketKeyCallback);
1093 }
1094
Adam Langley09505632015-07-30 18:10:13 -07001095 if (config->enable_client_custom_extension &&
1096 !SSL_CTX_add_client_custom_ext(
1097 ssl_ctx.get(), kCustomExtensionValue, CustomExtensionAddCallback,
1098 CustomExtensionFreeCallback, kCustomExtensionAddArg,
1099 CustomExtensionParseCallback, kCustomExtensionParseArg)) {
1100 return nullptr;
1101 }
1102
1103 if (config->enable_server_custom_extension &&
1104 !SSL_CTX_add_server_custom_ext(
1105 ssl_ctx.get(), kCustomExtensionValue, CustomExtensionAddCallback,
1106 CustomExtensionFreeCallback, kCustomExtensionAddArg,
1107 CustomExtensionParseCallback, kCustomExtensionParseArg)) {
1108 return nullptr;
1109 }
1110
Paul Lietar8f1c2682015-08-18 12:21:54 +01001111 if (config->verify_fail) {
1112 SSL_CTX_set_cert_verify_callback(ssl_ctx.get(), VerifyFail, NULL);
1113 } else {
1114 SSL_CTX_set_cert_verify_callback(ssl_ctx.get(), VerifySucceed, NULL);
1115 }
1116
Paul Lietar4fac72e2015-09-09 13:44:55 +01001117 if (!config->signed_cert_timestamps.empty() &&
1118 !SSL_CTX_set_signed_cert_timestamp_list(
1119 ssl_ctx.get(), (const uint8_t *)config->signed_cert_timestamps.data(),
1120 config->signed_cert_timestamps.size())) {
1121 return nullptr;
1122 }
1123
Adam Langley2ff79332017-02-28 13:45:39 -08001124 if (!config->use_client_ca_list.empty()) {
1125 if (config->use_client_ca_list == "<NULL>") {
1126 SSL_CTX_set_client_CA_list(ssl_ctx.get(), nullptr);
1127 } else {
1128 bssl::UniquePtr<STACK_OF(X509_NAME)> names =
1129 DecodeHexX509Names(config->use_client_ca_list);
1130 SSL_CTX_set_client_CA_list(ssl_ctx.get(), names.release());
1131 }
David Benjamin2f8935d2016-07-13 19:47:39 -04001132 }
1133
David Benjamin65ac9972016-09-02 21:35:25 -04001134 if (config->enable_grease) {
1135 SSL_CTX_set_grease_enabled(ssl_ctx.get(), 1);
1136 }
1137
David Benjamin8b176712016-10-27 21:51:24 -04001138 if (!config->expected_server_name.empty()) {
1139 SSL_CTX_set_tlsext_servername_callback(ssl_ctx.get(), ServerNameCallback);
1140 }
1141
David Benjamin4199b0d2016-11-01 13:58:25 -04001142 if (!config->ticket_key.empty() &&
1143 !SSL_CTX_set_tlsext_ticket_keys(ssl_ctx.get(), config->ticket_key.data(),
1144 config->ticket_key.size())) {
1145 return nullptr;
1146 }
1147
Steven Valdez08b65f42016-12-07 15:29:45 -05001148 if (config->enable_early_data) {
1149 SSL_CTX_set_early_data_enabled(ssl_ctx.get(), 1);
1150 }
1151
David Benjaminc8ff30c2017-04-04 13:52:36 -04001152 if (config->allow_unknown_alpn_protos) {
1153 SSL_CTX_set_allow_unknown_alpn_protos(ssl_ctx.get(), 1);
1154 }
1155
David Benjamin69522112017-03-28 15:38:29 -05001156 if (config->enable_ed25519) {
1157 SSL_CTX_set_ed25519_enabled(ssl_ctx.get(), 1);
1158 }
1159
David Benjamin71c21b42017-04-14 17:05:40 -04001160 if (!config->verify_prefs.empty()) {
1161 std::vector<uint16_t> u16s(config->verify_prefs.begin(),
1162 config->verify_prefs.end());
1163 if (!SSL_CTX_set_verify_algorithm_prefs(ssl_ctx.get(), u16s.data(),
1164 u16s.size())) {
1165 return nullptr;
1166 }
1167 }
1168
David Benjamin1d5c83e2014-07-22 19:20:02 -04001169 return ssl_ctx;
David Benjamin1d5c83e2014-07-22 19:20:02 -04001170}
1171
David Benjamin40f101b2015-02-20 11:23:42 -05001172// RetryAsync is called after a failed operation on |ssl| with return code
1173// |ret|. If the operation should be retried, it simulates one asynchronous
David Benjamin6c2563e2015-04-03 03:47:47 -04001174// event and returns true. Otherwise it returns false.
1175static bool RetryAsync(SSL *ssl, int ret) {
David Benjamin43ec06f2014-08-05 02:28:57 -04001176 // No error; don't retry.
1177 if (ret >= 0) {
David Benjamin40f101b2015-02-20 11:23:42 -05001178 return false;
David Benjamin025b3d32014-07-01 19:53:04 -04001179 }
David Benjamin83f90402015-01-27 01:09:43 -05001180
David Benjamin6c2563e2015-04-03 03:47:47 -04001181 TestState *test_state = GetTestState(ssl);
Matt Braithwaite6278e242016-06-14 08:18:22 -07001182 assert(GetTestConfig(ssl)->async);
David Benjamin83f90402015-01-27 01:09:43 -05001183
David Benjamin585d7a42016-06-02 14:58:00 -04001184 if (test_state->packeted_bio != nullptr &&
1185 PacketedBioAdvanceClock(test_state->packeted_bio)) {
David Benjamin13e81fc2015-11-02 17:16:13 -05001186 // The DTLS retransmit logic silently ignores write failures. So the test
1187 // may progress, allow writes through synchronously.
David Benjamin585d7a42016-06-02 14:58:00 -04001188 AsyncBioEnforceWriteQuota(test_state->async_bio, false);
David Benjamin13e81fc2015-11-02 17:16:13 -05001189 int timeout_ret = DTLSv1_handle_timeout(ssl);
David Benjamin585d7a42016-06-02 14:58:00 -04001190 AsyncBioEnforceWriteQuota(test_state->async_bio, true);
David Benjamin13e81fc2015-11-02 17:16:13 -05001191
1192 if (timeout_ret < 0) {
David Benjaminc565ebb2015-04-03 04:06:36 -04001193 fprintf(stderr, "Error retransmitting.\n");
David Benjamin40f101b2015-02-20 11:23:42 -05001194 return false;
David Benjamin83f90402015-01-27 01:09:43 -05001195 }
David Benjamin40f101b2015-02-20 11:23:42 -05001196 return true;
David Benjamin83f90402015-01-27 01:09:43 -05001197 }
1198
David Benjamin43ec06f2014-08-05 02:28:57 -04001199 // See if we needed to read or write more. If so, allow one byte through on
1200 // the appropriate end to maximally stress the state machine.
David Benjamind9e07012015-02-09 03:04:34 -05001201 switch (SSL_get_error(ssl, ret)) {
1202 case SSL_ERROR_WANT_READ:
David Benjamin6c2563e2015-04-03 03:47:47 -04001203 AsyncBioAllowRead(test_state->async_bio, 1);
David Benjamin40f101b2015-02-20 11:23:42 -05001204 return true;
David Benjamind9e07012015-02-09 03:04:34 -05001205 case SSL_ERROR_WANT_WRITE:
David Benjamin6c2563e2015-04-03 03:47:47 -04001206 AsyncBioAllowWrite(test_state->async_bio, 1);
David Benjamin40f101b2015-02-20 11:23:42 -05001207 return true;
David Benjamin9d0847a2015-02-16 03:57:55 -05001208 case SSL_ERROR_WANT_CHANNEL_ID_LOOKUP: {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001209 bssl::UniquePtr<EVP_PKEY> pkey =
1210 LoadPrivateKey(GetTestConfig(ssl)->send_channel_id);
David Benjamin9d0847a2015-02-16 03:57:55 -05001211 if (!pkey) {
David Benjamin40f101b2015-02-20 11:23:42 -05001212 return false;
David Benjamin9d0847a2015-02-16 03:57:55 -05001213 }
David Benjamin6c2563e2015-04-03 03:47:47 -04001214 test_state->channel_id = std::move(pkey);
David Benjamin40f101b2015-02-20 11:23:42 -05001215 return true;
David Benjamin9d0847a2015-02-16 03:57:55 -05001216 }
David Benjamin41fdbcd2015-02-09 03:13:35 -05001217 case SSL_ERROR_WANT_X509_LOOKUP:
David Benjamin6c2563e2015-04-03 03:47:47 -04001218 test_state->cert_ready = true;
David Benjamin40f101b2015-02-20 11:23:42 -05001219 return true;
David Benjamin1b8b6912015-02-09 04:28:16 -05001220 case SSL_ERROR_PENDING_SESSION:
David Benjamin6c2563e2015-04-03 03:47:47 -04001221 test_state->session = std::move(test_state->pending_session);
David Benjamin40f101b2015-02-20 11:23:42 -05001222 return true;
David Benjamin6f5c0f42015-02-24 01:23:21 -05001223 case SSL_ERROR_PENDING_CERTIFICATE:
Alessandro Ghedini958346a2016-12-20 19:42:15 +00001224 test_state->early_callback_ready = true;
1225 return true;
David Benjaminb4d65fd2015-05-29 17:11:21 -04001226 case SSL_ERROR_WANT_PRIVATE_KEY_OPERATION:
nagendra modadugu3398dbf2015-08-07 14:07:52 -07001227 test_state->private_key_retries++;
David Benjaminb4d65fd2015-05-29 17:11:21 -04001228 return true;
David Benjamind9e07012015-02-09 03:04:34 -05001229 default:
David Benjamin40f101b2015-02-20 11:23:42 -05001230 return false;
David Benjamin025b3d32014-07-01 19:53:04 -04001231 }
David Benjamin025b3d32014-07-01 19:53:04 -04001232}
1233
David Benjamin6c2563e2015-04-03 03:47:47 -04001234// DoRead reads from |ssl|, resolving any asynchronous operations. It returns
1235// the result value of the final |SSL_read| call.
1236static int DoRead(SSL *ssl, uint8_t *out, size_t max_out) {
David Benjamin7e7a82d2016-05-20 20:12:42 -04001237 const TestConfig *config = GetTestConfig(ssl);
David Benjamin13e81fc2015-11-02 17:16:13 -05001238 TestState *test_state = GetTestState(ssl);
David Benjamin6c2563e2015-04-03 03:47:47 -04001239 int ret;
1240 do {
David Benjamin13e81fc2015-11-02 17:16:13 -05001241 if (config->async) {
1242 // The DTLS retransmit logic silently ignores write failures. So the test
1243 // may progress, allow writes through synchronously. |SSL_read| may
1244 // trigger a retransmit, so disconnect the write quota.
1245 AsyncBioEnforceWriteQuota(test_state->async_bio, false);
1246 }
David Benjaminf3fbade2016-09-19 13:08:16 -04001247 ret = config->peek_then_read ? SSL_peek(ssl, out, max_out)
1248 : SSL_read(ssl, out, max_out);
David Benjamin13e81fc2015-11-02 17:16:13 -05001249 if (config->async) {
1250 AsyncBioEnforceWriteQuota(test_state->async_bio, true);
1251 }
David Benjamin7bb1d292016-11-01 19:45:06 -04001252
1253 // Run the exporter after each read. This is to test that the exporter fails
1254 // during a renegotiation.
1255 if (config->use_exporter_between_reads) {
1256 uint8_t buf;
1257 if (!SSL_export_keying_material(ssl, &buf, 1, NULL, 0, NULL, 0, 0)) {
1258 fprintf(stderr, "failed to export keying material\n");
1259 return -1;
1260 }
1261 }
David Benjamin6c2563e2015-04-03 03:47:47 -04001262 } while (config->async && RetryAsync(ssl, ret));
David Benjaminf3fbade2016-09-19 13:08:16 -04001263
1264 if (config->peek_then_read && ret > 0) {
1265 std::unique_ptr<uint8_t[]> buf(new uint8_t[static_cast<size_t>(ret)]);
1266
1267 // SSL_peek should synchronously return the same data.
1268 int ret2 = SSL_peek(ssl, buf.get(), ret);
1269 if (ret2 != ret ||
David Benjamin17cf2cb2016-12-13 01:07:13 -05001270 OPENSSL_memcmp(buf.get(), out, ret) != 0) {
David Benjaminf3fbade2016-09-19 13:08:16 -04001271 fprintf(stderr, "First and second SSL_peek did not match.\n");
1272 return -1;
1273 }
1274
1275 // SSL_read should synchronously return the same data and consume it.
1276 ret2 = SSL_read(ssl, buf.get(), ret);
1277 if (ret2 != ret ||
David Benjamin17cf2cb2016-12-13 01:07:13 -05001278 OPENSSL_memcmp(buf.get(), out, ret) != 0) {
David Benjaminf3fbade2016-09-19 13:08:16 -04001279 fprintf(stderr, "SSL_peek and SSL_read did not match.\n");
1280 return -1;
1281 }
1282 }
1283
David Benjamin6c2563e2015-04-03 03:47:47 -04001284 return ret;
1285}
1286
1287// WriteAll writes |in_len| bytes from |in| to |ssl|, resolving any asynchronous
1288// operations. It returns the result of the final |SSL_write| call.
David Benjaminbbba9392017-04-06 12:54:12 -04001289static int WriteAll(SSL *ssl, const void *in_, size_t in_len) {
1290 const uint8_t *in = reinterpret_cast<const uint8_t *>(in_);
David Benjamin7e7a82d2016-05-20 20:12:42 -04001291 const TestConfig *config = GetTestConfig(ssl);
David Benjamin6c2563e2015-04-03 03:47:47 -04001292 int ret;
1293 do {
1294 ret = SSL_write(ssl, in, in_len);
1295 if (ret > 0) {
1296 in += ret;
1297 in_len -= ret;
1298 }
1299 } while ((config->async && RetryAsync(ssl, ret)) || (ret > 0 && in_len > 0));
1300 return ret;
1301}
1302
David Benjamin30789da2015-08-29 22:56:45 -04001303// DoShutdown calls |SSL_shutdown|, resolving any asynchronous operations. It
1304// returns the result of the final |SSL_shutdown| call.
1305static int DoShutdown(SSL *ssl) {
David Benjamin7e7a82d2016-05-20 20:12:42 -04001306 const TestConfig *config = GetTestConfig(ssl);
David Benjamin30789da2015-08-29 22:56:45 -04001307 int ret;
1308 do {
1309 ret = SSL_shutdown(ssl);
1310 } while (config->async && RetryAsync(ssl, ret));
1311 return ret;
1312}
1313
David Benjamin1d4f4c02016-07-26 18:03:08 -04001314// DoSendFatalAlert calls |SSL_send_fatal_alert|, resolving any asynchronous
1315// operations. It returns the result of the final |SSL_send_fatal_alert| call.
1316static int DoSendFatalAlert(SSL *ssl, uint8_t alert) {
1317 const TestConfig *config = GetTestConfig(ssl);
1318 int ret;
1319 do {
1320 ret = SSL_send_fatal_alert(ssl, alert);
1321 } while (config->async && RetryAsync(ssl, ret));
1322 return ret;
1323}
1324
Steven Valdez1e6f11a2016-07-27 11:10:52 -04001325static uint16_t GetProtocolVersion(const SSL *ssl) {
1326 uint16_t version = SSL_version(ssl);
1327 if (!SSL_is_dtls(ssl)) {
1328 return version;
1329 }
1330 return 0x0201 + ~version;
1331}
1332
David Benjamin91eab5c2015-06-18 18:35:46 -04001333// CheckHandshakeProperties checks, immediately after |ssl| completes its
1334// initial handshake (or False Starts), whether all the properties are
1335// consistent with the test configuration and invariants.
1336static bool CheckHandshakeProperties(SSL *ssl, bool is_resume) {
David Benjamin7e7a82d2016-05-20 20:12:42 -04001337 const TestConfig *config = GetTestConfig(ssl);
David Benjamin91eab5c2015-06-18 18:35:46 -04001338
1339 if (SSL_get_current_cipher(ssl) == nullptr) {
1340 fprintf(stderr, "null cipher after handshake\n");
1341 return false;
1342 }
1343
1344 if (is_resume &&
1345 (!!SSL_session_reused(ssl) == config->expect_session_miss)) {
1346 fprintf(stderr, "session was%s reused\n",
1347 SSL_session_reused(ssl) ? "" : " not");
1348 return false;
1349 }
1350
Steven Valdez681eb6a2016-12-19 13:19:29 -05001351 bool expect_handshake_done =
1352 (is_resume || !config->false_start) &&
1353 !(config->is_server && SSL_early_data_accepted(ssl));
David Benjamin91eab5c2015-06-18 18:35:46 -04001354 if (expect_handshake_done != GetTestState(ssl)->handshake_done) {
1355 fprintf(stderr, "handshake was%s completed\n",
1356 GetTestState(ssl)->handshake_done ? "" : " not");
1357 return false;
1358 }
1359
David Benjaminba4594a2015-06-18 18:36:15 -04001360 if (expect_handshake_done && !config->is_server) {
1361 bool expect_new_session =
1362 !config->expect_no_session &&
Steven Valdez143e8b32016-07-11 13:19:03 -04001363 (!SSL_session_reused(ssl) || config->expect_ticket_renewal) &&
Steven Valdez1e6f11a2016-07-27 11:10:52 -04001364 // Session tickets are sent post-handshake in TLS 1.3.
1365 GetProtocolVersion(ssl) < TLS1_3_VERSION;
David Benjaminba4594a2015-06-18 18:36:15 -04001366 if (expect_new_session != GetTestState(ssl)->got_new_session) {
1367 fprintf(stderr,
David Benjamindd6fed92015-10-23 17:41:12 -04001368 "new session was%s cached, but we expected the opposite\n",
David Benjaminba4594a2015-06-18 18:36:15 -04001369 GetTestState(ssl)->got_new_session ? "" : " not");
1370 return false;
1371 }
1372 }
1373
David Benjaminb5c58db2017-01-28 01:39:29 -05001374 if (!is_resume) {
1375 if (config->expect_session_id && !GetTestState(ssl)->got_new_session) {
1376 fprintf(stderr, "session was not cached on the server.\n");
1377 return false;
1378 }
1379 if (config->expect_no_session_id && GetTestState(ssl)->got_new_session) {
1380 fprintf(stderr, "session was unexpectedly cached on the server.\n");
1381 return false;
1382 }
1383 }
1384
David Benjamin91eab5c2015-06-18 18:35:46 -04001385 if (config->is_server && !GetTestState(ssl)->early_callback_called) {
1386 fprintf(stderr, "early callback not called\n");
1387 return false;
1388 }
1389
1390 if (!config->expected_server_name.empty()) {
1391 const char *server_name =
1392 SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
David Benjamin8b176712016-10-27 21:51:24 -04001393 if (server_name == nullptr ||
1394 server_name != config->expected_server_name) {
David Benjamin91eab5c2015-06-18 18:35:46 -04001395 fprintf(stderr, "servername mismatch (got %s; want %s)\n",
1396 server_name, config->expected_server_name.c_str());
1397 return false;
1398 }
1399 }
1400
David Benjamin91eab5c2015-06-18 18:35:46 -04001401 if (!config->expected_next_proto.empty()) {
1402 const uint8_t *next_proto;
1403 unsigned next_proto_len;
1404 SSL_get0_next_proto_negotiated(ssl, &next_proto, &next_proto_len);
1405 if (next_proto_len != config->expected_next_proto.size() ||
David Benjamin17cf2cb2016-12-13 01:07:13 -05001406 OPENSSL_memcmp(next_proto, config->expected_next_proto.data(),
1407 next_proto_len) != 0) {
David Benjamin91eab5c2015-06-18 18:35:46 -04001408 fprintf(stderr, "negotiated next proto mismatch\n");
1409 return false;
1410 }
1411 }
1412
Steven Valdez2d850622017-01-11 11:34:52 -05001413 std::string expected_alpn = config->expected_alpn;
1414 if (is_resume && !config->expected_resume_alpn.empty()) {
1415 expected_alpn = config->expected_resume_alpn;
1416 }
1417 bool expect_no_alpn = (!is_resume && config->expect_no_alpn) ||
1418 (is_resume && config->expect_no_resume_alpn);
1419 if (expect_no_alpn) {
1420 expected_alpn.clear();
1421 }
1422
1423 if (!expected_alpn.empty() || expect_no_alpn) {
David Benjamin91eab5c2015-06-18 18:35:46 -04001424 const uint8_t *alpn_proto;
1425 unsigned alpn_proto_len;
1426 SSL_get0_alpn_selected(ssl, &alpn_proto, &alpn_proto_len);
Steven Valdez2d850622017-01-11 11:34:52 -05001427 if (alpn_proto_len != expected_alpn.size() ||
1428 OPENSSL_memcmp(alpn_proto, expected_alpn.data(), alpn_proto_len) != 0) {
David Benjamin91eab5c2015-06-18 18:35:46 -04001429 fprintf(stderr, "negotiated alpn proto mismatch\n");
1430 return false;
1431 }
1432 }
1433
1434 if (!config->expected_channel_id.empty()) {
1435 uint8_t channel_id[64];
1436 if (!SSL_get_tls_channel_id(ssl, channel_id, sizeof(channel_id))) {
1437 fprintf(stderr, "no channel id negotiated\n");
1438 return false;
1439 }
1440 if (config->expected_channel_id.size() != 64 ||
David Benjamin17cf2cb2016-12-13 01:07:13 -05001441 OPENSSL_memcmp(config->expected_channel_id.data(), channel_id, 64) !=
1442 0) {
David Benjamin91eab5c2015-06-18 18:35:46 -04001443 fprintf(stderr, "channel id mismatch\n");
1444 return false;
1445 }
1446 }
1447
David Benjamind2610042017-01-03 10:49:28 -05001448 if (config->expect_extended_master_secret && !SSL_get_extms_support(ssl)) {
1449 fprintf(stderr, "No EMS for connection when expected\n");
1450 return false;
1451 }
1452
1453 if (config->expect_secure_renegotiation &&
1454 !SSL_get_secure_renegotiation_support(ssl)) {
1455 fprintf(stderr, "No secure renegotiation for connection when expected\n");
1456 return false;
1457 }
1458
1459 if (config->expect_no_secure_renegotiation &&
1460 SSL_get_secure_renegotiation_support(ssl)) {
1461 fprintf(stderr,
1462 "Secure renegotiation unexpectedly negotiated for connection\n");
1463 return false;
David Benjamin91eab5c2015-06-18 18:35:46 -04001464 }
1465
1466 if (!config->expected_ocsp_response.empty()) {
1467 const uint8_t *data;
1468 size_t len;
1469 SSL_get0_ocsp_response(ssl, &data, &len);
1470 if (config->expected_ocsp_response.size() != len ||
David Benjamin17cf2cb2016-12-13 01:07:13 -05001471 OPENSSL_memcmp(config->expected_ocsp_response.data(), data, len) != 0) {
David Benjamin91eab5c2015-06-18 18:35:46 -04001472 fprintf(stderr, "OCSP response mismatch\n");
1473 return false;
1474 }
1475 }
1476
1477 if (!config->expected_signed_cert_timestamps.empty()) {
1478 const uint8_t *data;
1479 size_t len;
1480 SSL_get0_signed_cert_timestamp_list(ssl, &data, &len);
1481 if (config->expected_signed_cert_timestamps.size() != len ||
David Benjamin17cf2cb2016-12-13 01:07:13 -05001482 OPENSSL_memcmp(config->expected_signed_cert_timestamps.data(), data,
1483 len) != 0) {
David Benjamin91eab5c2015-06-18 18:35:46 -04001484 fprintf(stderr, "SCT list mismatch\n");
1485 return false;
1486 }
1487 }
1488
Paul Lietar8f1c2682015-08-18 12:21:54 +01001489 if (config->expect_verify_result) {
1490 int expected_verify_result = config->verify_fail ?
1491 X509_V_ERR_APPLICATION_VERIFICATION :
1492 X509_V_OK;
1493
1494 if (SSL_get_verify_result(ssl) != expected_verify_result) {
1495 fprintf(stderr, "Wrong certificate verification result\n");
1496 return false;
1497 }
1498 }
1499
Nick Harper60edffd2016-06-21 15:19:24 -07001500 if (config->expect_peer_signature_algorithm != 0 &&
1501 config->expect_peer_signature_algorithm !=
1502 SSL_get_peer_signature_algorithm(ssl)) {
1503 fprintf(stderr, "Peer signature algorithm was %04x, wanted %04x.\n",
1504 SSL_get_peer_signature_algorithm(ssl),
1505 config->expect_peer_signature_algorithm);
David Benjamin6e807652015-11-02 12:02:20 -05001506 return false;
1507 }
1508
David Benjamin8a55ce42016-12-11 03:03:42 -05001509 int expect_curve_id = config->expect_curve_id;
1510 if (is_resume && config->expect_resume_curve_id != 0) {
1511 expect_curve_id = config->expect_resume_curve_id;
1512 }
1513 if (expect_curve_id != 0) {
David Benjamin9e68f192016-06-30 14:55:33 -04001514 uint16_t curve_id = SSL_get_curve_id(ssl);
David Benjamin8a55ce42016-12-11 03:03:42 -05001515 if (static_cast<uint16_t>(expect_curve_id) != curve_id) {
David Benjamin9e68f192016-06-30 14:55:33 -04001516 fprintf(stderr, "curve_id was %04x, wanted %04x\n", curve_id,
David Benjamin8a55ce42016-12-11 03:03:42 -05001517 static_cast<uint16_t>(expect_curve_id));
David Benjamin9e68f192016-06-30 14:55:33 -04001518 return false;
1519 }
1520 }
1521
David Benjaminabbbee12016-10-31 19:20:42 -04001522 uint16_t cipher_id =
1523 static_cast<uint16_t>(SSL_CIPHER_get_id(SSL_get_current_cipher(ssl)));
1524 if (config->expect_cipher_aes != 0 &&
1525 EVP_has_aes_hardware() &&
1526 static_cast<uint16_t>(config->expect_cipher_aes) != cipher_id) {
1527 fprintf(stderr, "Cipher ID was %04x, wanted %04x (has AES hardware)\n",
1528 cipher_id, static_cast<uint16_t>(config->expect_cipher_aes));
1529 return false;
1530 }
1531
1532 if (config->expect_cipher_no_aes != 0 &&
1533 !EVP_has_aes_hardware() &&
1534 static_cast<uint16_t>(config->expect_cipher_no_aes) != cipher_id) {
1535 fprintf(stderr, "Cipher ID was %04x, wanted %04x (no AES hardware)\n",
1536 cipher_id, static_cast<uint16_t>(config->expect_cipher_no_aes));
1537 return false;
1538 }
1539
Steven Valdez2d850622017-01-11 11:34:52 -05001540 if (is_resume) {
1541 if ((config->expect_accept_early_data && !SSL_early_data_accepted(ssl)) ||
1542 (config->expect_reject_early_data && SSL_early_data_accepted(ssl))) {
1543 fprintf(stderr,
1544 "Early data was%s accepted, but we expected the opposite\n",
1545 SSL_early_data_accepted(ssl) ? "" : " not");
1546 return false;
1547 }
1548 }
David Benjaminabbbee12016-10-31 19:20:42 -04001549
David Benjaminbb9e36e2016-08-03 14:14:47 -04001550 if (!config->psk.empty()) {
1551 if (SSL_get_peer_cert_chain(ssl) != nullptr) {
1552 fprintf(stderr, "Received peer certificate on a PSK cipher.\n");
1553 return false;
1554 }
1555 } else if (!config->is_server || config->require_any_client_certificate) {
1556 if (SSL_get_peer_cert_chain(ssl) == nullptr) {
1557 fprintf(stderr, "Received no peer certificate but expected one.\n");
David Benjamin91eab5c2015-06-18 18:35:46 -04001558 return false;
1559 }
1560 }
David Benjaminbb9e36e2016-08-03 14:14:47 -04001561
David Benjamin2c516452016-11-15 10:16:54 +09001562 if (!config->expect_peer_cert_file.empty()) {
1563 bssl::UniquePtr<X509> expect_leaf;
1564 bssl::UniquePtr<STACK_OF(X509)> expect_chain;
1565 if (!LoadCertificate(&expect_leaf, &expect_chain,
1566 config->expect_peer_cert_file)) {
1567 return false;
1568 }
1569
1570 // For historical reasons, clients report a chain with a leaf and servers
1571 // without.
1572 if (!config->is_server) {
1573 if (!sk_X509_insert(expect_chain.get(), expect_leaf.get(), 0)) {
1574 return false;
1575 }
1576 X509_up_ref(expect_leaf.get()); // sk_X509_push takes ownership.
1577 }
1578
1579 bssl::UniquePtr<X509> leaf(SSL_get_peer_certificate(ssl));
1580 STACK_OF(X509) *chain = SSL_get_peer_cert_chain(ssl);
1581 if (X509_cmp(leaf.get(), expect_leaf.get()) != 0) {
1582 fprintf(stderr, "Received a different leaf certificate than expected.\n");
1583 return false;
1584 }
1585
1586 if (sk_X509_num(chain) != sk_X509_num(expect_chain.get())) {
1587 fprintf(stderr, "Received a chain of length %zu instead of %zu.\n",
1588 sk_X509_num(chain), sk_X509_num(expect_chain.get()));
1589 return false;
1590 }
1591
1592 for (size_t i = 0; i < sk_X509_num(chain); i++) {
1593 if (X509_cmp(sk_X509_value(chain, i),
1594 sk_X509_value(expect_chain.get(), i)) != 0) {
1595 fprintf(stderr, "Chain certificate %zu did not match.\n",
1596 i + 1);
1597 return false;
1598 }
1599 }
1600 }
1601
David Benjaminbbaf3672016-11-17 10:53:09 +09001602 bool expected_sha256_client_cert = config->expect_sha256_client_cert_initial;
1603 if (is_resume) {
1604 expected_sha256_client_cert = config->expect_sha256_client_cert_resume;
1605 }
1606
1607 if (SSL_get_session(ssl)->peer_sha256_valid != expected_sha256_client_cert) {
1608 fprintf(stderr,
1609 "Unexpected SHA-256 client cert state: expected:%d is_resume:%d.\n",
1610 expected_sha256_client_cert, is_resume);
1611 return false;
1612 }
1613
1614 if (expected_sha256_client_cert &&
Adam Langley46db7af2017-02-01 15:49:37 -08001615 SSL_get_session(ssl)->certs != nullptr) {
David Benjaminbbaf3672016-11-17 10:53:09 +09001616 fprintf(stderr, "Have both client cert and SHA-256 hash: is_resume:%d.\n",
1617 is_resume);
1618 return false;
1619 }
1620
David Benjamin35ac5b72017-03-03 15:05:56 -05001621 if (is_resume && config->expect_ticket_age_skew != 0 &&
1622 SSL_get_ticket_age_skew(ssl) != config->expect_ticket_age_skew) {
1623 fprintf(stderr, "Ticket age skew was %" PRId32 ", wanted %d\n",
1624 SSL_get_ticket_age_skew(ssl), config->expect_ticket_age_skew);
1625 return false;
1626 }
1627
David Benjamin91eab5c2015-06-18 18:35:46 -04001628 return true;
1629}
1630
David Benjamin87c8a642015-02-21 01:54:29 -05001631// DoExchange runs a test SSL exchange against the peer. On success, it returns
1632// true and sets |*out_session| to the negotiated SSL session. If the test is a
1633// resumption attempt, |is_resume| is true and |session| is the session from the
1634// previous exchange.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001635static bool DoExchange(bssl::UniquePtr<SSL_SESSION> *out_session,
1636 SSL_CTX *ssl_ctx, const TestConfig *config,
1637 bool is_resume, SSL_SESSION *session) {
Steven Valdez2d850622017-01-11 11:34:52 -05001638 if (is_resume && config->enable_resume_early_data) {
1639 SSL_CTX_set_early_data_enabled(ssl_ctx, 1);
1640 }
1641
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001642 bssl::UniquePtr<SSL> ssl(SSL_new(ssl_ctx));
David Benjamina7f333d2015-02-09 02:37:18 -05001643 if (!ssl) {
David Benjamin40f101b2015-02-20 11:23:42 -05001644 return false;
David Benjamin025b3d32014-07-01 19:53:04 -04001645 }
1646
David Benjamin7e7a82d2016-05-20 20:12:42 -04001647 if (!SetTestConfig(ssl.get(), config) ||
David Benjamin2d445c02015-02-09 13:03:50 -05001648 !SetTestState(ssl.get(), std::unique_ptr<TestState>(new TestState))) {
David Benjamin40f101b2015-02-20 11:23:42 -05001649 return false;
Adam Langley69a01602014-11-17 17:26:55 -08001650 }
David Benjamin5a593af2014-08-11 19:51:50 -04001651
Steven Valdez2d850622017-01-11 11:34:52 -05001652 GetTestState(ssl.get())->is_resume = is_resume;
1653
Adam Langley5f0efe02015-02-20 13:03:16 -08001654 if (config->fallback_scsv &&
1655 !SSL_set_mode(ssl.get(), SSL_MODE_SEND_FALLBACK_SCSV)) {
1656 return false;
David Benjamin025b3d32014-07-01 19:53:04 -04001657 }
David Benjamina0486782016-10-06 19:11:32 -04001658 // Install the certificate synchronously if nothing else will handle it.
1659 if (!config->use_early_callback &&
1660 !config->use_old_client_cert_callback &&
1661 !config->async &&
1662 !InstallCertificate(ssl.get())) {
1663 return false;
David Benjamin5a593af2014-08-11 19:51:50 -04001664 }
David Benjamin5edfc8c2016-12-10 15:46:58 -05001665 if (!config->use_old_client_cert_callback) {
1666 SSL_set_cert_cb(ssl.get(), CertCallback, nullptr);
1667 }
David Benjamin5a593af2014-08-11 19:51:50 -04001668 if (config->require_any_client_certificate) {
David Benjamina7f333d2015-02-09 02:37:18 -05001669 SSL_set_verify(ssl.get(), SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
Paul Lietar8f1c2682015-08-18 12:21:54 +01001670 NULL);
1671 }
1672 if (config->verify_peer) {
1673 SSL_set_verify(ssl.get(), SSL_VERIFY_PEER, NULL);
David Benjamin5a593af2014-08-11 19:51:50 -04001674 }
1675 if (config->false_start) {
David Benjamined7c4752015-02-16 19:16:46 -05001676 SSL_set_mode(ssl.get(), SSL_MODE_ENABLE_FALSE_START);
David Benjamin5a593af2014-08-11 19:51:50 -04001677 }
1678 if (config->cbc_record_splitting) {
David Benjamina7f333d2015-02-09 02:37:18 -05001679 SSL_set_mode(ssl.get(), SSL_MODE_CBC_RECORD_SPLITTING);
David Benjamin5a593af2014-08-11 19:51:50 -04001680 }
1681 if (config->partial_write) {
David Benjamina7f333d2015-02-09 02:37:18 -05001682 SSL_set_mode(ssl.get(), SSL_MODE_ENABLE_PARTIAL_WRITE);
David Benjamin5a593af2014-08-11 19:51:50 -04001683 }
Steven Valdez4f94b1c2016-05-24 12:31:07 -04001684 if (config->no_tls13) {
1685 SSL_set_options(ssl.get(), SSL_OP_NO_TLSv1_3);
1686 }
David Benjamin5a593af2014-08-11 19:51:50 -04001687 if (config->no_tls12) {
David Benjamina7f333d2015-02-09 02:37:18 -05001688 SSL_set_options(ssl.get(), SSL_OP_NO_TLSv1_2);
David Benjamin5a593af2014-08-11 19:51:50 -04001689 }
1690 if (config->no_tls11) {
David Benjamina7f333d2015-02-09 02:37:18 -05001691 SSL_set_options(ssl.get(), SSL_OP_NO_TLSv1_1);
David Benjamin5a593af2014-08-11 19:51:50 -04001692 }
1693 if (config->no_tls1) {
David Benjamina7f333d2015-02-09 02:37:18 -05001694 SSL_set_options(ssl.get(), SSL_OP_NO_TLSv1);
David Benjamin5a593af2014-08-11 19:51:50 -04001695 }
1696 if (config->no_ssl3) {
David Benjamina7f333d2015-02-09 02:37:18 -05001697 SSL_set_options(ssl.get(), SSL_OP_NO_SSLv3);
David Benjamin5a593af2014-08-11 19:51:50 -04001698 }
Steven Valdez143e8b32016-07-11 13:19:03 -04001699 if (!config->expected_channel_id.empty() ||
1700 config->enable_channel_id) {
David Benjamineebd3c82016-12-06 17:43:58 -05001701 SSL_set_tls_channel_id_enabled(ssl.get(), 1);
David Benjamina08e49d2014-08-24 01:46:07 -04001702 }
1703 if (!config->send_channel_id.empty()) {
David Benjamineebd3c82016-12-06 17:43:58 -05001704 SSL_set_tls_channel_id_enabled(ssl.get(), 1);
David Benjamind9e07012015-02-09 03:04:34 -05001705 if (!config->async) {
David Benjaminc273d2c2015-02-09 12:59:46 -05001706 // The async case will be supplied by |ChannelIdCallback|.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001707 bssl::UniquePtr<EVP_PKEY> pkey = LoadPrivateKey(config->send_channel_id);
David Benjamind9e07012015-02-09 03:04:34 -05001708 if (!pkey || !SSL_set1_tls_channel_id(ssl.get(), pkey.get())) {
David Benjamin40f101b2015-02-20 11:23:42 -05001709 return false;
David Benjamind9e07012015-02-09 03:04:34 -05001710 }
David Benjamina08e49d2014-08-24 01:46:07 -04001711 }
David Benjamina08e49d2014-08-24 01:46:07 -04001712 }
David Benjamin9d0847a2015-02-16 03:57:55 -05001713 if (!config->host_name.empty() &&
1714 !SSL_set_tlsext_host_name(ssl.get(), config->host_name.c_str())) {
David Benjamin40f101b2015-02-20 11:23:42 -05001715 return false;
David Benjamine78bfde2014-09-06 12:45:15 -04001716 }
David Benjamin9d0847a2015-02-16 03:57:55 -05001717 if (!config->advertise_alpn.empty() &&
1718 SSL_set_alpn_protos(ssl.get(),
1719 (const uint8_t *)config->advertise_alpn.data(),
1720 config->advertise_alpn.size()) != 0) {
David Benjamin40f101b2015-02-20 11:23:42 -05001721 return false;
David Benjaminae2888f2014-09-06 12:58:58 -04001722 }
David Benjamin48cae082014-10-27 01:06:24 -04001723 if (!config->psk.empty()) {
David Benjaminc273d2c2015-02-09 12:59:46 -05001724 SSL_set_psk_client_callback(ssl.get(), PskClientCallback);
1725 SSL_set_psk_server_callback(ssl.get(), PskServerCallback);
David Benjamin48cae082014-10-27 01:06:24 -04001726 }
David Benjamin61f95272014-11-25 01:55:35 -05001727 if (!config->psk_identity.empty() &&
David Benjamina7f333d2015-02-09 02:37:18 -05001728 !SSL_use_psk_identity_hint(ssl.get(), config->psk_identity.c_str())) {
David Benjamin40f101b2015-02-20 11:23:42 -05001729 return false;
David Benjamin48cae082014-10-27 01:06:24 -04001730 }
David Benjamin61f95272014-11-25 01:55:35 -05001731 if (!config->srtp_profiles.empty() &&
David Benjamina7f333d2015-02-09 02:37:18 -05001732 !SSL_set_srtp_profiles(ssl.get(), config->srtp_profiles.c_str())) {
David Benjamin40f101b2015-02-20 11:23:42 -05001733 return false;
David Benjamin61f95272014-11-25 01:55:35 -05001734 }
David Benjamin26e1ff32017-02-14 20:13:00 -05001735 if (config->enable_ocsp_stapling) {
1736 SSL_enable_ocsp_stapling(ssl.get());
David Benjamin61f95272014-11-25 01:55:35 -05001737 }
David Benjamin26e1ff32017-02-14 20:13:00 -05001738 if (config->enable_signed_cert_timestamps) {
1739 SSL_enable_signed_cert_timestamps(ssl.get());
David Benjaminca6c8262014-11-15 19:06:08 -05001740 }
David Benjamin2dc02042016-09-19 19:57:37 -04001741 if (config->min_version != 0 &&
David Benjamine4706902016-09-20 15:12:23 -04001742 !SSL_set_min_proto_version(ssl.get(), (uint16_t)config->min_version)) {
David Benjamin2dc02042016-09-19 19:57:37 -04001743 return false;
David Benjamin1eb367c2014-12-12 18:17:51 -05001744 }
David Benjamin2dc02042016-09-19 19:57:37 -04001745 if (config->max_version != 0 &&
David Benjamine4706902016-09-20 15:12:23 -04001746 !SSL_set_max_proto_version(ssl.get(), (uint16_t)config->max_version)) {
David Benjamin2dc02042016-09-19 19:57:37 -04001747 return false;
David Benjamin1eb367c2014-12-12 18:17:51 -05001748 }
David Benjamin13be1de2015-01-11 16:29:36 -05001749 if (config->mtu != 0) {
David Benjamina7f333d2015-02-09 02:37:18 -05001750 SSL_set_options(ssl.get(), SSL_OP_NO_QUERY_MTU);
1751 SSL_set_mtu(ssl.get(), config->mtu);
David Benjamin13be1de2015-01-11 16:29:36 -05001752 }
Adam Langley524e7172015-02-20 16:04:00 -08001753 if (config->install_ddos_callback) {
1754 SSL_CTX_set_dos_protection_cb(ssl_ctx, DDoSCallback);
1755 }
David Benjamin1d5ef3b2015-10-12 19:54:18 -04001756 if (config->renegotiate_once) {
1757 SSL_set_renegotiate_mode(ssl.get(), ssl_renegotiate_once);
1758 }
1759 if (config->renegotiate_freely) {
1760 SSL_set_renegotiate_mode(ssl.get(), ssl_renegotiate_freely);
David Benjaminb16346b2015-04-08 19:16:58 -04001761 }
Adam Langley27a0d082015-11-03 13:34:10 -08001762 if (config->renegotiate_ignore) {
1763 SSL_set_renegotiate_mode(ssl.get(), ssl_renegotiate_ignore);
1764 }
David Benjamin30789da2015-08-29 22:56:45 -04001765 if (!config->check_close_notify) {
1766 SSL_set_quiet_shutdown(ssl.get(), 1);
1767 }
David Benjamin99fdfb92015-11-02 12:11:35 -05001768 if (config->p384_only) {
1769 int nid = NID_secp384r1;
1770 if (!SSL_set1_curves(ssl.get(), &nid, 1)) {
1771 return false;
1772 }
1773 }
David Benjamin8c2b3bf2015-12-18 20:55:44 -05001774 if (config->enable_all_curves) {
1775 static const int kAllCurves[] = {
Adam Langley764ab982017-03-10 18:01:30 -08001776 NID_secp224r1, NID_X9_62_prime256v1, NID_secp384r1,
1777 NID_secp521r1, NID_X25519,
David Benjamin8c2b3bf2015-12-18 20:55:44 -05001778 };
1779 if (!SSL_set1_curves(ssl.get(), kAllCurves,
Steven Valdezcb966542016-08-17 16:56:14 -04001780 OPENSSL_ARRAY_SIZE(kAllCurves))) {
David Benjamin8c2b3bf2015-12-18 20:55:44 -05001781 return false;
1782 }
1783 }
Taylor Brandstetter376a0fe2016-05-10 19:30:28 -07001784 if (config->initial_timeout_duration_ms > 0) {
1785 DTLSv1_set_initial_timeout_duration(ssl.get(),
1786 config->initial_timeout_duration_ms);
1787 }
David Benjamina252b342016-09-26 19:57:53 -04001788 if (config->max_cert_list > 0) {
1789 SSL_set_max_cert_list(ssl.get(), config->max_cert_list);
1790 }
David Benjaminbbaf3672016-11-17 10:53:09 +09001791 if (!is_resume && config->retain_only_sha256_client_cert_initial) {
1792 SSL_set_retain_only_sha256_of_client_certs(ssl.get(), 1);
1793 }
1794 if (is_resume && config->retain_only_sha256_client_cert_resume) {
1795 SSL_set_retain_only_sha256_of_client_certs(ssl.get(), 1);
1796 }
David Benjamine3fbb362017-01-06 16:19:28 -05001797 if (config->max_send_fragment > 0) {
1798 SSL_set_max_send_fragment(ssl.get(), config->max_send_fragment);
1799 }
David Benjamin025b3d32014-07-01 19:53:04 -04001800
David Benjamin87c8a642015-02-21 01:54:29 -05001801 int sock = Connect(config->port);
1802 if (sock == -1) {
1803 return false;
1804 }
1805 SocketCloser closer(sock);
1806
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001807 bssl::UniquePtr<BIO> bio(BIO_new_socket(sock, BIO_NOCLOSE));
David Benjamina7f333d2015-02-09 02:37:18 -05001808 if (!bio) {
David Benjamin40f101b2015-02-20 11:23:42 -05001809 return false;
David Benjamin43ec06f2014-08-05 02:28:57 -04001810 }
David Benjamin6fd297b2014-08-11 18:43:38 -04001811 if (config->is_dtls) {
David Benjamin11c82892017-02-23 20:40:31 -05001812 bssl::UniquePtr<BIO> packeted = PacketedBioCreate(&g_clock);
David Benjaminb7c5e842016-03-28 09:59:10 -04001813 if (!packeted) {
1814 return false;
1815 }
David Benjamin585d7a42016-06-02 14:58:00 -04001816 GetTestState(ssl.get())->packeted_bio = packeted.get();
David Benjamina7f333d2015-02-09 02:37:18 -05001817 BIO_push(packeted.get(), bio.release());
1818 bio = std::move(packeted);
David Benjamin6fd297b2014-08-11 18:43:38 -04001819 }
David Benjamin5a593af2014-08-11 19:51:50 -04001820 if (config->async) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001821 bssl::UniquePtr<BIO> async_scoped =
David Benjaminc273d2c2015-02-09 12:59:46 -05001822 config->is_dtls ? AsyncBioCreateDatagram() : AsyncBioCreate();
David Benjaminb7c5e842016-03-28 09:59:10 -04001823 if (!async_scoped) {
1824 return false;
1825 }
David Benjamina7f333d2015-02-09 02:37:18 -05001826 BIO_push(async_scoped.get(), bio.release());
David Benjamin6c2563e2015-04-03 03:47:47 -04001827 GetTestState(ssl.get())->async_bio = async_scoped.get();
David Benjamina7f333d2015-02-09 02:37:18 -05001828 bio = std::move(async_scoped);
David Benjamin43ec06f2014-08-05 02:28:57 -04001829 }
David Benjamina7f333d2015-02-09 02:37:18 -05001830 SSL_set_bio(ssl.get(), bio.get(), bio.get());
1831 bio.release(); // SSL_set_bio takes ownership.
David Benjamin43ec06f2014-08-05 02:28:57 -04001832
David Benjamin1d5c83e2014-07-22 19:20:02 -04001833 if (session != NULL) {
David Benjamin1b8b6912015-02-09 04:28:16 -05001834 if (!config->is_server) {
1835 if (SSL_set_session(ssl.get(), session) != 1) {
David Benjamin40f101b2015-02-20 11:23:42 -05001836 return false;
David Benjamin1b8b6912015-02-09 04:28:16 -05001837 }
1838 } else if (config->async) {
1839 // The internal session cache is disabled, so install the session
1840 // manually.
David Benjaminb9195402016-08-05 10:51:43 -04001841 SSL_SESSION_up_ref(session);
1842 GetTestState(ssl.get())->pending_session.reset(session);
David Benjamin1d5c83e2014-07-22 19:20:02 -04001843 }
1844 }
1845
David Benjamina07c0fc2015-05-13 13:19:42 -04001846 if (SSL_get_current_cipher(ssl.get()) != nullptr) {
1847 fprintf(stderr, "non-null cipher before handshake\n");
1848 return false;
1849 }
1850
David Benjamin4784b992017-03-25 18:22:19 -05001851 if (config->is_server) {
1852 SSL_set_accept_state(ssl.get());
David Benjamine0e7d0d2015-02-08 19:33:25 -05001853 } else {
David Benjamin4784b992017-03-25 18:22:19 -05001854 SSL_set_connect_state(ssl.get());
1855 }
1856
1857 int ret;
1858 if (!config->implicit_handshake) {
David Benjamine0e7d0d2015-02-08 19:33:25 -05001859 do {
David Benjamin4784b992017-03-25 18:22:19 -05001860 ret = SSL_do_handshake(ssl.get());
David Benjamin6c2563e2015-04-03 03:47:47 -04001861 } while (config->async && RetryAsync(ssl.get(), ret));
David Benjamin91eab5c2015-06-18 18:35:46 -04001862 if (ret != 1 ||
1863 !CheckHandshakeProperties(ssl.get(), is_resume)) {
David Benjamin40f101b2015-02-20 11:23:42 -05001864 return false;
David Benjamine0e7d0d2015-02-08 19:33:25 -05001865 }
David Benjamin025b3d32014-07-01 19:53:04 -04001866
David Benjamin8c26d752017-03-26 15:13:51 -05001867 if (config->handshake_twice) {
1868 do {
1869 ret = SSL_do_handshake(ssl.get());
1870 } while (config->async && RetryAsync(ssl.get(), ret));
1871 if (ret != 1) {
1872 return false;
1873 }
1874 }
1875
1876 // Skip the |config->async| logic as this should be a no-op.
1877 if (config->no_op_extra_handshake &&
1878 SSL_do_handshake(ssl.get()) != 1) {
1879 fprintf(stderr, "Extra SSL_do_handshake was not a no-op.\n");
1880 return false;
1881 }
1882
David Benjaminba4594a2015-06-18 18:36:15 -04001883 // Reset the state to assert later that the callback isn't called in
1884 // renegotations.
1885 GetTestState(ssl.get())->got_new_session = false;
David Benjamin61f95272014-11-25 01:55:35 -05001886 }
1887
David Benjaminc565ebb2015-04-03 04:06:36 -04001888 if (config->export_keying_material > 0) {
1889 std::vector<uint8_t> result(
1890 static_cast<size_t>(config->export_keying_material));
1891 if (!SSL_export_keying_material(
1892 ssl.get(), result.data(), result.size(),
1893 config->export_label.data(), config->export_label.size(),
1894 reinterpret_cast<const uint8_t*>(config->export_context.data()),
1895 config->export_context.size(), config->use_export_context)) {
1896 fprintf(stderr, "failed to export keying material\n");
1897 return false;
1898 }
1899 if (WriteAll(ssl.get(), result.data(), result.size()) < 0) {
1900 return false;
1901 }
1902 }
1903
Adam Langleyaf0e32c2015-06-03 09:57:23 -07001904 if (config->tls_unique) {
1905 uint8_t tls_unique[16];
1906 size_t tls_unique_len;
1907 if (!SSL_get_tls_unique(ssl.get(), tls_unique, &tls_unique_len,
1908 sizeof(tls_unique))) {
1909 fprintf(stderr, "failed to get tls-unique\n");
1910 return false;
1911 }
1912
1913 if (tls_unique_len != 12) {
1914 fprintf(stderr, "expected 12 bytes of tls-unique but got %u",
1915 static_cast<unsigned>(tls_unique_len));
1916 return false;
1917 }
1918
1919 if (WriteAll(ssl.get(), tls_unique, tls_unique_len) < 0) {
1920 return false;
1921 }
1922 }
1923
David Benjamin1d4f4c02016-07-26 18:03:08 -04001924 if (config->send_alert) {
1925 if (DoSendFatalAlert(ssl.get(), SSL_AD_DECOMPRESSION_FAILURE) < 0) {
1926 return false;
1927 }
1928 return true;
1929 }
1930
David Benjamin5a593af2014-08-11 19:51:50 -04001931 if (config->write_different_record_sizes) {
David Benjamin6fd297b2014-08-11 18:43:38 -04001932 if (config->is_dtls) {
1933 fprintf(stderr, "write_different_record_sizes not supported for DTLS\n");
David Benjamin40f101b2015-02-20 11:23:42 -05001934 return false;
David Benjamin6fd297b2014-08-11 18:43:38 -04001935 }
Kenny Root7fdeaf12014-08-05 15:23:37 -07001936 // This mode writes a number of different record sizes in an attempt to
1937 // trip up the CBC record splitting code.
Adam Langleybc949292015-06-18 21:32:44 -07001938 static const size_t kBufLen = 32769;
1939 std::unique_ptr<uint8_t[]> buf(new uint8_t[kBufLen]);
David Benjamin17cf2cb2016-12-13 01:07:13 -05001940 OPENSSL_memset(buf.get(), 0x42, kBufLen);
Kenny Root7fdeaf12014-08-05 15:23:37 -07001941 static const size_t kRecordSizes[] = {
1942 0, 1, 255, 256, 257, 16383, 16384, 16385, 32767, 32768, 32769};
Steven Valdezcb966542016-08-17 16:56:14 -04001943 for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kRecordSizes); i++) {
Kenny Root7fdeaf12014-08-05 15:23:37 -07001944 const size_t len = kRecordSizes[i];
Adam Langleybc949292015-06-18 21:32:44 -07001945 if (len > kBufLen) {
Kenny Root7fdeaf12014-08-05 15:23:37 -07001946 fprintf(stderr, "Bad kRecordSizes value.\n");
David Benjamin40f101b2015-02-20 11:23:42 -05001947 return false;
Kenny Root7fdeaf12014-08-05 15:23:37 -07001948 }
Adam Langleybc949292015-06-18 21:32:44 -07001949 if (WriteAll(ssl.get(), buf.get(), len) < 0) {
David Benjamin40f101b2015-02-20 11:23:42 -05001950 return false;
David Benjamin025b3d32014-07-01 19:53:04 -04001951 }
1952 }
Kenny Root7fdeaf12014-08-05 15:23:37 -07001953 } else {
David Benjaminbbba9392017-04-06 12:54:12 -04001954 static const char kInitialWrite[] = "hello";
1955 bool pending_initial_write = false;
David Benjamina1eaba12017-01-01 23:19:22 -05001956 if (config->read_with_unfinished_write) {
1957 if (!config->async) {
1958 fprintf(stderr, "-read-with-unfinished-write requires -async.\n");
1959 return false;
1960 }
1961
David Benjaminbbba9392017-04-06 12:54:12 -04001962 int write_ret =
1963 SSL_write(ssl.get(), kInitialWrite, strlen(kInitialWrite));
David Benjamina1eaba12017-01-01 23:19:22 -05001964 if (SSL_get_error(ssl.get(), write_ret) != SSL_ERROR_WANT_WRITE) {
1965 fprintf(stderr, "Failed to leave unfinished write.\n");
1966 return false;
1967 }
David Benjaminbbba9392017-04-06 12:54:12 -04001968 pending_initial_write = true;
1969 } else if (config->shim_writes_first) {
1970 if (WriteAll(ssl.get(), kInitialWrite, strlen(kInitialWrite)) < 0) {
David Benjamin6c2563e2015-04-03 03:47:47 -04001971 return false;
1972 }
David Benjamine58c4f52014-08-24 03:47:07 -04001973 }
David Benjamin30789da2015-08-29 22:56:45 -04001974 if (!config->shim_shuts_down) {
1975 for (;;) {
David Benjamin2c99d282015-09-01 10:23:00 -04001976 // Read only 512 bytes at a time in TLS to ensure records may be
1977 // returned in multiple reads.
David Benjamine3fbb362017-01-06 16:19:28 -05001978 size_t read_size = config->is_dtls ? 16384 : 512;
1979 if (config->read_size > 0) {
1980 read_size = config->read_size;
1981 }
1982 std::unique_ptr<uint8_t[]> buf(new uint8_t[read_size]);
1983
1984 int n = DoRead(ssl.get(), buf.get(), read_size);
David Benjamin30789da2015-08-29 22:56:45 -04001985 int err = SSL_get_error(ssl.get(), n);
1986 if (err == SSL_ERROR_ZERO_RETURN ||
1987 (n == 0 && err == SSL_ERROR_SYSCALL)) {
1988 if (n != 0) {
1989 fprintf(stderr, "Invalid SSL_get_error output\n");
1990 return false;
1991 }
1992 // Stop on either clean or unclean shutdown.
1993 break;
1994 } else if (err != SSL_ERROR_NONE) {
1995 if (n > 0) {
1996 fprintf(stderr, "Invalid SSL_get_error output\n");
1997 return false;
1998 }
1999 return false;
2000 }
2001 // Successfully read data.
2002 if (n <= 0) {
David Benjamin9a38e922015-01-22 16:06:11 -05002003 fprintf(stderr, "Invalid SSL_get_error output\n");
David Benjamin40f101b2015-02-20 11:23:42 -05002004 return false;
David Benjamin9a38e922015-01-22 16:06:11 -05002005 }
David Benjamin30789da2015-08-29 22:56:45 -04002006
2007 // After a successful read, with or without False Start, the handshake
Steven Valdez681eb6a2016-12-19 13:19:29 -05002008 // must be complete unless we are doing early data.
2009 if (!GetTestState(ssl.get())->handshake_done &&
2010 !SSL_early_data_accepted(ssl.get())) {
David Benjamin30789da2015-08-29 22:56:45 -04002011 fprintf(stderr, "handshake was not completed after SSL_read\n");
David Benjamin40f101b2015-02-20 11:23:42 -05002012 return false;
David Benjamin9a38e922015-01-22 16:06:11 -05002013 }
David Benjamin87e4acd2015-04-02 19:57:35 -04002014
David Benjaminbbba9392017-04-06 12:54:12 -04002015 // Clear the initial write, if unfinished.
2016 if (pending_initial_write) {
2017 if (WriteAll(ssl.get(), kInitialWrite, strlen(kInitialWrite)) < 0) {
2018 return false;
2019 }
2020 pending_initial_write = false;
2021 }
2022
David Benjamin30789da2015-08-29 22:56:45 -04002023 for (int i = 0; i < n; i++) {
2024 buf[i] ^= 0xff;
2025 }
Adam Langleya0a8dc22015-09-09 10:22:00 -07002026 if (WriteAll(ssl.get(), buf.get(), n) < 0) {
David Benjamin30789da2015-08-29 22:56:45 -04002027 return false;
2028 }
Kenny Root7fdeaf12014-08-05 15:23:37 -07002029 }
2030 }
David Benjamin025b3d32014-07-01 19:53:04 -04002031 }
2032
David Benjaminba4594a2015-06-18 18:36:15 -04002033 if (!config->is_server && !config->false_start &&
2034 !config->implicit_handshake &&
Steven Valdez1e6f11a2016-07-27 11:10:52 -04002035 // Session tickets are sent post-handshake in TLS 1.3.
2036 GetProtocolVersion(ssl.get()) < TLS1_3_VERSION &&
David Benjaminba4594a2015-06-18 18:36:15 -04002037 GetTestState(ssl.get())->got_new_session) {
2038 fprintf(stderr, "new session was established after the handshake\n");
2039 return false;
2040 }
2041
Steven Valdez1e6f11a2016-07-27 11:10:52 -04002042 if (GetProtocolVersion(ssl.get()) >= TLS1_3_VERSION && !config->is_server) {
2043 bool expect_new_session =
2044 !config->expect_no_session && !config->shim_shuts_down;
2045 if (expect_new_session != GetTestState(ssl.get())->got_new_session) {
2046 fprintf(stderr,
2047 "new session was%s cached, but we expected the opposite\n",
2048 GetTestState(ssl.get())->got_new_session ? "" : " not");
2049 return false;
2050 }
Steven Valdez08b65f42016-12-07 15:29:45 -05002051
2052 if (expect_new_session) {
2053 bool got_early_data_info =
2054 GetTestState(ssl.get())->new_session->ticket_max_early_data != 0;
2055 if (config->expect_early_data_info != got_early_data_info) {
2056 fprintf(
2057 stderr,
2058 "new session did%s include ticket_early_data_info, but we expected "
2059 "the opposite\n",
2060 got_early_data_info ? "" : " not");
2061 return false;
2062 }
2063 }
Steven Valdez1e6f11a2016-07-27 11:10:52 -04002064 }
2065
David Benjamin1d5c83e2014-07-22 19:20:02 -04002066 if (out_session) {
Steven Valdez4aa154e2016-07-29 14:32:55 -04002067 *out_session = std::move(GetTestState(ssl.get())->new_session);
David Benjamin1d5c83e2014-07-22 19:20:02 -04002068 }
2069
David Benjamin30789da2015-08-29 22:56:45 -04002070 ret = DoShutdown(ssl.get());
2071
2072 if (config->shim_shuts_down && config->check_close_notify) {
2073 // We initiate shutdown, so |SSL_shutdown| will return in two stages. First
2074 // it returns zero when our close_notify is sent, then one when the peer's
2075 // is received.
2076 if (ret != 0) {
2077 fprintf(stderr, "Unexpected SSL_shutdown result: %d != 0\n", ret);
2078 return false;
2079 }
2080 ret = DoShutdown(ssl.get());
2081 }
2082
2083 if (ret != 1) {
2084 fprintf(stderr, "Unexpected SSL_shutdown result: %d != 1\n", ret);
2085 return false;
2086 }
2087
David Benjamin324dce42015-10-12 19:49:00 -04002088 if (SSL_total_renegotiations(ssl.get()) !=
2089 config->expect_total_renegotiations) {
2090 fprintf(stderr, "Expected %d renegotiations, got %d\n",
2091 config->expect_total_renegotiations,
2092 SSL_total_renegotiations(ssl.get()));
2093 return false;
2094 }
2095
David Benjamin40f101b2015-02-20 11:23:42 -05002096 return true;
David Benjamin025b3d32014-07-01 19:53:04 -04002097}
David Benjamin1d5c83e2014-07-22 19:20:02 -04002098
David Benjaminff3a1492016-03-02 10:12:06 -05002099class StderrDelimiter {
2100 public:
2101 ~StderrDelimiter() { fprintf(stderr, "--- DONE ---\n"); }
2102};
2103
David Benjaminaac1e2d2016-12-06 22:35:41 -05002104int main(int argc, char **argv) {
David Benjaminff3a1492016-03-02 10:12:06 -05002105 // To distinguish ASan's output from ours, add a trailing message to stderr.
2106 // Anything following this line will be considered an error.
2107 StderrDelimiter delimiter;
2108
David Benjamin87c8a642015-02-21 01:54:29 -05002109#if defined(OPENSSL_WINDOWS)
2110 /* Initialize Winsock. */
2111 WORD wsa_version = MAKEWORD(2, 2);
2112 WSADATA wsa_data;
2113 int wsa_err = WSAStartup(wsa_version, &wsa_data);
2114 if (wsa_err != 0) {
2115 fprintf(stderr, "WSAStartup failed: %d\n", wsa_err);
2116 return 1;
2117 }
2118 if (wsa_data.wVersion != wsa_version) {
2119 fprintf(stderr, "Didn't get expected version: %x\n", wsa_data.wVersion);
2120 return 1;
2121 }
2122#else
David Benjamin1d5c83e2014-07-22 19:20:02 -04002123 signal(SIGPIPE, SIG_IGN);
Adam Langleyded93582014-07-31 15:23:51 -07002124#endif
David Benjamin1d5c83e2014-07-22 19:20:02 -04002125
David Benjamin7a1eefd2015-10-17 23:39:22 -04002126 CRYPTO_library_init();
David Benjamind9e07012015-02-09 03:04:34 -05002127 g_config_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
David Benjamin2d445c02015-02-09 13:03:50 -05002128 g_state_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, TestStateExFree);
David Benjamin6c2563e2015-04-03 03:47:47 -04002129 if (g_config_index < 0 || g_state_index < 0) {
David Benjaminae3e4872014-11-18 21:52:26 -05002130 return 1;
2131 }
David Benjamin5a593af2014-08-11 19:51:50 -04002132
2133 TestConfig config;
2134 if (!ParseConfig(argc - 1, argv + 1, &config)) {
David Benjaminc273d2c2015-02-09 12:59:46 -05002135 return Usage(argv[0]);
David Benjamin1d5c83e2014-07-22 19:20:02 -04002136 }
2137
Adam Langleyd519bf62016-12-12 11:16:44 -08002138 g_pool = CRYPTO_BUFFER_POOL_new();
2139
David Benjamin1b22f852016-10-27 16:36:32 -04002140 // Some code treats the zero time special, so initialize the clock to a
2141 // non-zero time.
2142 g_clock.tv_sec = 1234;
2143 g_clock.tv_usec = 1234;
2144
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002145 bssl::UniquePtr<SSL_CTX> ssl_ctx = SetupCtx(&config);
David Benjamina7f333d2015-02-09 02:37:18 -05002146 if (!ssl_ctx) {
Brian Smith83a82982015-04-09 16:21:10 -10002147 ERR_print_errors_fp(stderr);
David Benjamin1d5c83e2014-07-22 19:20:02 -04002148 return 1;
2149 }
2150
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002151 bssl::UniquePtr<SSL_SESSION> session;
David Benjamin46662482016-08-17 00:51:00 -04002152 for (int i = 0; i < config.resume_count + 1; i++) {
2153 bool is_resume = i > 0;
2154 if (is_resume && !config.is_server && !session) {
2155 fprintf(stderr, "No session to offer.\n");
2156 return 1;
2157 }
David Benjamin1d5c83e2014-07-22 19:20:02 -04002158
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002159 bssl::UniquePtr<SSL_SESSION> offer_session = std::move(session);
David Benjamin46662482016-08-17 00:51:00 -04002160 if (!DoExchange(&session, ssl_ctx.get(), &config, is_resume,
2161 offer_session.get())) {
2162 fprintf(stderr, "Connection %d failed.\n", i + 1);
2163 ERR_print_errors_fp(stderr);
2164 return 1;
2165 }
Steven Valdeza833c352016-11-01 13:39:36 -04002166
2167 if (config.resumption_delay != 0) {
2168 g_clock.tv_sec += config.resumption_delay;
2169 }
David Benjamin1d5c83e2014-07-22 19:20:02 -04002170 }
2171
David Benjamina7f333d2015-02-09 02:37:18 -05002172 return 0;
David Benjamin1d5c83e2014-07-22 19:20:02 -04002173}