8a8dab02bba5d86d778349555e1e009ef21d9674
[openssl.git] / test / handshake_helper.c
1 /*
2  * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the OpenSSL license (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9
10 #include <string.h>
11
12 #include <openssl/bio.h>
13 #include <openssl/x509_vfy.h>
14 #include <openssl/ssl.h>
15
16 #include "handshake_helper.h"
17
18 /*
19  * Since there appears to be no way to extract the sent/received alert
20  * from the SSL object directly, we use the info callback and stash
21  * the result in ex_data.
22  */
23 typedef struct handshake_ex_data {
24     int alert_sent;
25     int alert_received;
26     int session_ticket_do_not_call;
27     ssl_servername_t servername;
28 } HANDSHAKE_EX_DATA;
29
30 static int ex_data_idx;
31
32 static void info_cb(const SSL *s, int where, int ret)
33 {
34     if (where & SSL_CB_ALERT) {
35         HANDSHAKE_EX_DATA *ex_data =
36             (HANDSHAKE_EX_DATA*)(SSL_get_ex_data(s, ex_data_idx));
37         if (where & SSL_CB_WRITE) {
38             ex_data->alert_sent = ret;
39         } else {
40             ex_data->alert_received = ret;
41         }
42     }
43 }
44
45 /*
46  * Select the appropriate server CTX.
47  * Returns SSL_TLSEXT_ERR_OK if a match was found.
48  * If |ignore| is 1, returns SSL_TLSEXT_ERR_NOACK on mismatch.
49  * Otherwise, returns SSL_TLSEXT_ERR_ALERT_FATAL on mismatch.
50  * An empty SNI extension also returns SSL_TSLEXT_ERR_NOACK.
51  */
52 static int select_server_ctx(SSL *s, void *arg, int ignore)
53 {
54     const char *servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
55     HANDSHAKE_EX_DATA *ex_data =
56         (HANDSHAKE_EX_DATA*)(SSL_get_ex_data(s, ex_data_idx));
57
58     if (servername == NULL) {
59         ex_data->servername = SSL_TEST_SERVERNAME_SERVER1;
60         return SSL_TLSEXT_ERR_NOACK;
61     }
62
63     if (strcmp(servername, "server2") == 0) {
64         SSL_CTX *new_ctx = (SSL_CTX*)arg;
65         SSL_set_SSL_CTX(s, new_ctx);
66         /*
67          * Copy over all the SSL_CTX options - reasonable behavior
68          * allows testing of cases where the options between two
69          * contexts differ/conflict
70          */
71         SSL_clear_options(s, 0xFFFFFFFFL);
72         SSL_set_options(s, SSL_CTX_get_options(new_ctx));
73
74         ex_data->servername = SSL_TEST_SERVERNAME_SERVER2;
75         return SSL_TLSEXT_ERR_OK;
76     } else if (strcmp(servername, "server1") == 0) {
77         ex_data->servername = SSL_TEST_SERVERNAME_SERVER1;
78         return SSL_TLSEXT_ERR_OK;
79     } else if (ignore) {
80         ex_data->servername = SSL_TEST_SERVERNAME_SERVER1;
81         return SSL_TLSEXT_ERR_NOACK;
82     } else {
83         /* Don't set an explicit alert, to test library defaults. */
84         return SSL_TLSEXT_ERR_ALERT_FATAL;
85     }
86 }
87
88 /*
89  * (RFC 6066):
90  *  If the server understood the ClientHello extension but
91  *  does not recognize the server name, the server SHOULD take one of two
92  *  actions: either abort the handshake by sending a fatal-level
93  *  unrecognized_name(112) alert or continue the handshake.
94  *
95  * This behaviour is up to the application to configure; we test both
96  * configurations to ensure the state machine propagates the result
97  * correctly.
98  */
99 static int servername_ignore_cb(SSL *s, int *ad, void *arg)
100 {
101     return select_server_ctx(s, arg, 1);
102 }
103
104 static int servername_reject_cb(SSL *s, int *ad, void *arg)
105 {
106     return select_server_ctx(s, arg, 0);
107 }
108
109 static int verify_reject_cb(X509_STORE_CTX *ctx, void *arg) {
110     X509_STORE_CTX_set_error(ctx, X509_V_ERR_APPLICATION_VERIFICATION);
111     return 0;
112 }
113
114 static int verify_accept_cb(X509_STORE_CTX *ctx, void *arg) {
115     return 1;
116 }
117
118 static int broken_session_ticket_cb(SSL* s, unsigned char* key_name, unsigned char *iv,
119                                     EVP_CIPHER_CTX *ctx, HMAC_CTX *hctx, int enc)
120 {
121     return 0;
122 }
123
124 static int do_not_call_session_ticket_cb(SSL* s, unsigned char* key_name,
125                                          unsigned char *iv,
126                                          EVP_CIPHER_CTX *ctx,
127                                          HMAC_CTX *hctx, int enc)
128 {
129     HANDSHAKE_EX_DATA *ex_data =
130         (HANDSHAKE_EX_DATA*)(SSL_get_ex_data(s, ex_data_idx));
131     ex_data->session_ticket_do_not_call = 1;
132     return 0;
133 }
134
135 /*
136  * Configure callbacks and other properties that can't be set directly
137  * in the server/client CONF.
138  */
139 static void configure_handshake_ctx(SSL_CTX *server_ctx, SSL_CTX *server2_ctx,
140                                     SSL_CTX *client_ctx,
141                                     const SSL_TEST_CTX *test_ctx)
142 {
143     switch (test_ctx->client_verify_callback) {
144     case SSL_TEST_VERIFY_ACCEPT_ALL:
145         SSL_CTX_set_cert_verify_callback(client_ctx, &verify_accept_cb,
146                                          NULL);
147         break;
148     case SSL_TEST_VERIFY_REJECT_ALL:
149         SSL_CTX_set_cert_verify_callback(client_ctx, &verify_reject_cb,
150                                          NULL);
151         break;
152     default:
153         break;
154     }
155
156     /* link the two contexts for SNI purposes */
157     switch (test_ctx->servername_callback) {
158     case SSL_TEST_SERVERNAME_IGNORE_MISMATCH:
159         SSL_CTX_set_tlsext_servername_callback(server_ctx, servername_ignore_cb);
160         SSL_CTX_set_tlsext_servername_arg(server_ctx, server2_ctx);
161         break;
162     case SSL_TEST_SERVERNAME_REJECT_MISMATCH:
163         SSL_CTX_set_tlsext_servername_callback(server_ctx, servername_reject_cb);
164         SSL_CTX_set_tlsext_servername_arg(server_ctx, server2_ctx);
165         break;
166     default:
167         break;
168     }
169
170     /*
171      * The initial_ctx/session_ctx always handles the encrypt/decrypt of the
172      * session ticket. This ticket_key callback is assigned to the second
173      * session (assigned via SNI), and should never be invoked
174      */
175     if (server2_ctx != NULL)
176         SSL_CTX_set_tlsext_ticket_key_cb(server2_ctx,
177                                          do_not_call_session_ticket_cb);
178
179     if (test_ctx->session_ticket_expected == SSL_TEST_SESSION_TICKET_BROKEN) {
180         SSL_CTX_set_tlsext_ticket_key_cb(server_ctx, broken_session_ticket_cb);
181     }
182 }
183
184 /*
185  * Configure callbacks and other properties that can't be set directly
186  * in the server/client CONF.
187  */
188 static void configure_handshake_ssl(SSL *server, SSL *client,
189                                     const SSL_TEST_CTX *test_ctx)
190 {
191     if (test_ctx->servername != SSL_TEST_SERVERNAME_NONE)
192         SSL_set_tlsext_host_name(client,
193                                  ssl_servername_name(test_ctx->servername));
194 }
195
196
197 typedef enum {
198     PEER_SUCCESS,
199     PEER_RETRY,
200     PEER_ERROR
201 } peer_status_t;
202
203 static peer_status_t do_handshake_step(SSL *ssl)
204 {
205     int ret;
206
207     ret = SSL_do_handshake(ssl);
208
209     if (ret == 1) {
210         return PEER_SUCCESS;
211     } else if (ret == 0) {
212         return PEER_ERROR;
213     } else {
214         int error = SSL_get_error(ssl, ret);
215         /* Memory bios should never block with SSL_ERROR_WANT_WRITE. */
216         if (error == SSL_ERROR_WANT_READ)
217             return PEER_RETRY;
218         else
219             return PEER_ERROR;
220     }
221 }
222
223 typedef enum {
224     /* Both parties succeeded. */
225     HANDSHAKE_SUCCESS,
226     /* Client errored. */
227     CLIENT_ERROR,
228     /* Server errored. */
229     SERVER_ERROR,
230     /* Peers are in inconsistent state. */
231     INTERNAL_ERROR,
232     /* One or both peers not done. */
233     HANDSHAKE_RETRY
234 } handshake_status_t;
235
236 /*
237  * Determine the handshake outcome.
238  * last_status: the status of the peer to have acted last.
239  * previous_status: the status of the peer that didn't act last.
240  * client_spoke_last: 1 if the client went last.
241  */
242 static handshake_status_t handshake_status(peer_status_t last_status,
243                                            peer_status_t previous_status,
244                                            int client_spoke_last)
245 {
246     switch (last_status) {
247     case PEER_SUCCESS:
248         switch (previous_status) {
249         case PEER_SUCCESS:
250             /* Both succeeded. */
251             return HANDSHAKE_SUCCESS;
252         case PEER_RETRY:
253             /* Let the first peer finish. */
254             return HANDSHAKE_RETRY;
255         case PEER_ERROR:
256             /*
257              * Second peer succeeded despite the fact that the first peer
258              * already errored. This shouldn't happen.
259              */
260             return INTERNAL_ERROR;
261         }
262
263     case PEER_RETRY:
264         if (previous_status == PEER_RETRY) {
265             /* Neither peer is done. */
266             return HANDSHAKE_RETRY;
267         } else {
268             /*
269              * Deadlock: second peer is waiting for more input while first
270              * peer thinks they're done (no more input is coming).
271              */
272             return INTERNAL_ERROR;
273         }
274     case PEER_ERROR:
275         switch (previous_status) {
276         case PEER_SUCCESS:
277             /*
278              * First peer succeeded but second peer errored.
279              * TODO(emilia): we should be able to continue here (with some
280              * application data?) to ensure the first peer receives the
281              * alert / close_notify.
282              */
283             return client_spoke_last ? CLIENT_ERROR : SERVER_ERROR;
284         case PEER_RETRY:
285             /* We errored; let the peer finish. */
286             return HANDSHAKE_RETRY;
287         case PEER_ERROR:
288             /* Both peers errored. Return the one that errored first. */
289             return client_spoke_last ? SERVER_ERROR : CLIENT_ERROR;
290         }
291     }
292     /* Control should never reach here. */
293     return INTERNAL_ERROR;
294 }
295
296 HANDSHAKE_RESULT do_handshake(SSL_CTX *server_ctx, SSL_CTX *server2_ctx,
297                               SSL_CTX *client_ctx, const SSL_TEST_CTX *test_ctx)
298 {
299     SSL *server, *client;
300     BIO *client_to_server, *server_to_client;
301     HANDSHAKE_EX_DATA server_ex_data, client_ex_data;
302     HANDSHAKE_RESULT ret;
303     int client_turn = 1;
304     peer_status_t client_status = PEER_RETRY, server_status = PEER_RETRY;
305     handshake_status_t status = HANDSHAKE_RETRY;
306     unsigned char* tick = NULL;
307     size_t len = 0;
308     SSL_SESSION* sess = NULL;
309
310     configure_handshake_ctx(server_ctx, server2_ctx, client_ctx, test_ctx);
311
312     server = SSL_new(server_ctx);
313     client = SSL_new(client_ctx);
314     OPENSSL_assert(server != NULL && client != NULL);
315
316     configure_handshake_ssl(server, client, test_ctx);
317
318     memset(&server_ex_data, 0, sizeof(server_ex_data));
319     memset(&client_ex_data, 0, sizeof(client_ex_data));
320     memset(&ret, 0, sizeof(ret));
321     ret.result = SSL_TEST_INTERNAL_ERROR;
322
323     client_to_server = BIO_new(BIO_s_mem());
324     server_to_client = BIO_new(BIO_s_mem());
325
326     OPENSSL_assert(client_to_server != NULL && server_to_client != NULL);
327
328     /* Non-blocking bio. */
329     BIO_set_nbio(client_to_server, 1);
330     BIO_set_nbio(server_to_client, 1);
331
332     SSL_set_connect_state(client);
333     SSL_set_accept_state(server);
334
335     /* The bios are now owned by the SSL object. */
336     SSL_set_bio(client, server_to_client, client_to_server);
337     OPENSSL_assert(BIO_up_ref(server_to_client) > 0);
338     OPENSSL_assert(BIO_up_ref(client_to_server) > 0);
339     SSL_set_bio(server, client_to_server, server_to_client);
340
341     ex_data_idx = SSL_get_ex_new_index(0, "ex data", NULL, NULL, NULL);
342     OPENSSL_assert(ex_data_idx >= 0);
343
344     OPENSSL_assert(SSL_set_ex_data(server, ex_data_idx,
345                                    &server_ex_data) == 1);
346     OPENSSL_assert(SSL_set_ex_data(client, ex_data_idx,
347                                    &client_ex_data) == 1);
348
349     SSL_set_info_callback(server, &info_cb);
350     SSL_set_info_callback(client, &info_cb);
351
352     /*
353      * Half-duplex handshake loop.
354      * Client and server speak to each other synchronously in the same process.
355      * We use non-blocking BIOs, so whenever one peer blocks for read, it
356      * returns PEER_RETRY to indicate that it's the other peer's turn to write.
357      * The handshake succeeds once both peers have succeeded. If one peer
358      * errors out, we also let the other peer retry (and presumably fail).
359      */
360     for(;;) {
361         if (client_turn) {
362             client_status = do_handshake_step(client);
363             status = handshake_status(client_status, server_status,
364                                       1 /* client went last */);
365         } else {
366             server_status = do_handshake_step(server);
367             status = handshake_status(server_status, client_status,
368                                       0 /* server went last */);
369         }
370
371         switch (status) {
372         case HANDSHAKE_SUCCESS:
373             ret.result = SSL_TEST_SUCCESS;
374             goto err;
375         case CLIENT_ERROR:
376             ret.result = SSL_TEST_CLIENT_FAIL;
377             goto err;
378         case SERVER_ERROR:
379             ret.result = SSL_TEST_SERVER_FAIL;
380             goto err;
381         case INTERNAL_ERROR:
382             ret.result = SSL_TEST_INTERNAL_ERROR;
383             goto err;
384         case HANDSHAKE_RETRY:
385             /* Continue. */
386             client_turn ^= 1;
387             break;
388         }
389     }
390  err:
391     ret.server_alert_sent = server_ex_data.alert_sent;
392     ret.server_alert_received = client_ex_data.alert_received;
393     ret.client_alert_sent = client_ex_data.alert_sent;
394     ret.client_alert_received = server_ex_data.alert_received;
395     ret.server_protocol = SSL_version(server);
396     ret.client_protocol = SSL_version(client);
397     ret.servername = server_ex_data.servername;
398     if ((sess = SSL_get0_session(client)) != NULL)
399         SSL_SESSION_get0_ticket(sess, &tick, &len);
400     if (tick == NULL || len == 0)
401         ret.session_ticket = SSL_TEST_SESSION_TICKET_NO;
402     else
403         ret.session_ticket = SSL_TEST_SESSION_TICKET_YES;
404     ret.session_ticket_do_not_call = server_ex_data.session_ticket_do_not_call;
405
406     SSL_free(server);
407     SSL_free(client);
408     return ret;
409 }