ce2a3dad135e4b5536cacc61954157b295f7f594
[platform/framework/web/crosswalk.git] / src / third_party / boringssl / src / ssl / test / bssl_shim.cc
1 /* 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
15 #include <openssl/base.h>
16
17 #if !defined(OPENSSL_WINDOWS)
18 #include <arpa/inet.h>
19 #include <netinet/in.h>
20 #include <signal.h>
21 #include <sys/socket.h>
22 #include <unistd.h>
23 #endif
24
25 #include <sys/types.h>
26
27 #include <openssl/bio.h>
28 #include <openssl/buf.h>
29 #include <openssl/bytestring.h>
30 #include <openssl/ssl.h>
31
32 #include "async_bio.h"
33 #include "packeted_bio.h"
34 #include "test_config.h"
35
36 static int usage(const char *program) {
37   fprintf(stderr, "Usage: %s [flags...]\n",
38           program);
39   return 1;
40 }
41
42 static int g_ex_data_index = 0;
43
44 static void SetConfigPtr(SSL *ssl, const TestConfig *config) {
45   SSL_set_ex_data(ssl, g_ex_data_index, (void *)config);
46 }
47
48 static const TestConfig *GetConfigPtr(SSL *ssl) {
49   return (const TestConfig *)SSL_get_ex_data(ssl, g_ex_data_index);
50 }
51
52 static EVP_PKEY *LoadPrivateKey(const std::string &file) {
53   BIO *bio = BIO_new(BIO_s_file());
54   if (bio == NULL) {
55     return NULL;
56   }
57   if (!BIO_read_filename(bio, file.c_str())) {
58     BIO_free(bio);
59     return NULL;
60   }
61   EVP_PKEY *pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL);
62   BIO_free(bio);
63   return pkey;
64 }
65
66 static int early_callback_called = 0;
67
68 static int select_certificate_callback(const struct ssl_early_callback_ctx *ctx) {
69   early_callback_called = 1;
70
71   const TestConfig *config = GetConfigPtr(ctx->ssl);
72
73   if (config->expected_server_name.empty()) {
74     return 1;
75   }
76
77   const uint8_t *extension_data;
78   size_t extension_len;
79   CBS extension, server_name_list, host_name;
80   uint8_t name_type;
81
82   if (!SSL_early_callback_ctx_extension_get(ctx, TLSEXT_TYPE_server_name,
83                                             &extension_data,
84                                             &extension_len)) {
85     fprintf(stderr, "Could not find server_name extension.\n");
86     return -1;
87   }
88
89   CBS_init(&extension, extension_data, extension_len);
90   if (!CBS_get_u16_length_prefixed(&extension, &server_name_list) ||
91       CBS_len(&extension) != 0 ||
92       !CBS_get_u8(&server_name_list, &name_type) ||
93       name_type != TLSEXT_NAMETYPE_host_name ||
94       !CBS_get_u16_length_prefixed(&server_name_list, &host_name) ||
95       CBS_len(&server_name_list) != 0) {
96     fprintf(stderr, "Could not decode server_name extension.\n");
97     return -1;
98   }
99
100   if (!CBS_mem_equal(&host_name,
101                      (const uint8_t*)config->expected_server_name.data(),
102                      config->expected_server_name.size())) {
103     fprintf(stderr, "Server name mismatch.\n");
104   }
105
106   return 1;
107 }
108
109 static int skip_verify(int preverify_ok, X509_STORE_CTX *store_ctx) {
110   return 1;
111 }
112
113 static int next_protos_advertised_callback(SSL *ssl,
114                                            const uint8_t **out,
115                                            unsigned int *out_len,
116                                            void *arg) {
117   const TestConfig *config = GetConfigPtr(ssl);
118   if (config->advertise_npn.empty())
119     return SSL_TLSEXT_ERR_NOACK;
120
121   *out = (const uint8_t*)config->advertise_npn.data();
122   *out_len = config->advertise_npn.size();
123   return SSL_TLSEXT_ERR_OK;
124 }
125
126 static int next_proto_select_callback(SSL* ssl,
127                                       uint8_t** out,
128                                       uint8_t* outlen,
129                                       const uint8_t* in,
130                                       unsigned inlen,
131                                       void* arg) {
132   const TestConfig *config = GetConfigPtr(ssl);
133   if (config->select_next_proto.empty())
134     return SSL_TLSEXT_ERR_NOACK;
135
136   *out = (uint8_t*)config->select_next_proto.data();
137   *outlen = config->select_next_proto.size();
138   return SSL_TLSEXT_ERR_OK;
139 }
140
141 static int alpn_select_callback(SSL* ssl,
142                                 const uint8_t** out,
143                                 uint8_t* outlen,
144                                 const uint8_t* in,
145                                 unsigned inlen,
146                                 void* arg) {
147   const TestConfig *config = GetConfigPtr(ssl);
148   if (config->select_alpn.empty())
149     return SSL_TLSEXT_ERR_NOACK;
150
151   if (!config->expected_advertised_alpn.empty() &&
152       (config->expected_advertised_alpn.size() != inlen ||
153        memcmp(config->expected_advertised_alpn.data(),
154               in, inlen) != 0)) {
155     fprintf(stderr, "bad ALPN select callback inputs\n");
156     exit(1);
157   }
158
159   *out = (const uint8_t*)config->select_alpn.data();
160   *outlen = config->select_alpn.size();
161   return SSL_TLSEXT_ERR_OK;
162 }
163
164 static int cookie_generate_callback(SSL *ssl, uint8_t *cookie, size_t *cookie_len) {
165   *cookie_len = 32;
166   memset(cookie, 42, *cookie_len);
167   return 1;
168 }
169
170 static int cookie_verify_callback(SSL *ssl, const uint8_t *cookie, size_t cookie_len) {
171   if (cookie_len != 32) {
172     fprintf(stderr, "Cookie length mismatch.\n");
173     return 0;
174   }
175   for (size_t i = 0; i < cookie_len; i++) {
176     if (cookie[i] != 42) {
177       fprintf(stderr, "Cookie mismatch.\n");
178       return 0;
179     }
180   }
181   return 1;
182 }
183
184 static unsigned psk_client_callback(SSL *ssl, const char *hint,
185                                     char *out_identity,
186                                     unsigned max_identity_len,
187                                     uint8_t *out_psk, unsigned max_psk_len) {
188   const TestConfig *config = GetConfigPtr(ssl);
189
190   if (strcmp(hint ? hint : "", config->psk_identity.c_str()) != 0) {
191     fprintf(stderr, "Server PSK hint did not match.\n");
192     return 0;
193   }
194
195   // Account for the trailing '\0' for the identity.
196   if (config->psk_identity.size() >= max_identity_len ||
197       config->psk.size() > max_psk_len) {
198     fprintf(stderr, "PSK buffers too small\n");
199     return 0;
200   }
201
202   BUF_strlcpy(out_identity, config->psk_identity.c_str(),
203               max_identity_len);
204   memcpy(out_psk, config->psk.data(), config->psk.size());
205   return config->psk.size();
206 }
207
208 static unsigned psk_server_callback(SSL *ssl, const char *identity,
209                                     uint8_t *out_psk, unsigned max_psk_len) {
210   const TestConfig *config = GetConfigPtr(ssl);
211
212   if (strcmp(identity, config->psk_identity.c_str()) != 0) {
213     fprintf(stderr, "Client PSK identity did not match.\n");
214     return 0;
215   }
216
217   if (config->psk.size() > max_psk_len) {
218     fprintf(stderr, "PSK buffers too small\n");
219     return 0;
220   }
221
222   memcpy(out_psk, config->psk.data(), config->psk.size());
223   return config->psk.size();
224 }
225
226 static SSL_CTX *setup_ctx(const TestConfig *config) {
227   SSL_CTX *ssl_ctx = NULL;
228   DH *dh = NULL;
229
230   const SSL_METHOD *method;
231   if (config->is_dtls) {
232     // TODO(davidben): Get DTLS 1.2 working and test the version negotiation
233     // codepath. This doesn't currently work because
234     // - Session resumption is broken: https://crbug.com/403378
235     // - DTLS hasn't been updated for EVP_AEAD.
236     if (config->is_server) {
237       method = DTLSv1_server_method();
238     } else {
239       method = DTLSv1_client_method();
240     }
241   } else {
242     if (config->is_server) {
243       method = SSLv23_server_method();
244     } else {
245       method = SSLv23_client_method();
246     }
247   }
248   ssl_ctx = SSL_CTX_new(method);
249   if (ssl_ctx == NULL) {
250     goto err;
251   }
252
253   if (config->is_dtls) {
254     // DTLS needs read-ahead to function on a datagram BIO.
255     //
256     // TODO(davidben): this should not be necessary. DTLS code should only
257     // expect a datagram BIO.
258     SSL_CTX_set_read_ahead(ssl_ctx, 1);
259   }
260
261   if (!SSL_CTX_set_ecdh_auto(ssl_ctx, 1)) {
262     goto err;
263   }
264
265   if (!SSL_CTX_set_cipher_list(ssl_ctx, "ALL")) {
266     goto err;
267   }
268
269   dh = DH_get_2048_256(NULL);
270   if (!SSL_CTX_set_tmp_dh(ssl_ctx, dh)) {
271     goto err;
272   }
273
274   SSL_CTX_set_session_cache_mode(ssl_ctx, SSL_SESS_CACHE_BOTH);
275
276   ssl_ctx->select_certificate_cb = select_certificate_callback;
277
278   SSL_CTX_set_next_protos_advertised_cb(
279       ssl_ctx, next_protos_advertised_callback, NULL);
280   if (!config->select_next_proto.empty()) {
281     SSL_CTX_set_next_proto_select_cb(ssl_ctx, next_proto_select_callback, NULL);
282   }
283
284   if (!config->select_alpn.empty()) {
285     SSL_CTX_set_alpn_select_cb(ssl_ctx, alpn_select_callback, NULL);
286   }
287
288   SSL_CTX_set_cookie_generate_cb(ssl_ctx, cookie_generate_callback);
289   SSL_CTX_set_cookie_verify_cb(ssl_ctx, cookie_verify_callback);
290
291   ssl_ctx->tlsext_channel_id_enabled_new = 1;
292
293   DH_free(dh);
294   return ssl_ctx;
295
296  err:
297   if (dh != NULL) {
298     DH_free(dh);
299   }
300   if (ssl_ctx != NULL) {
301     SSL_CTX_free(ssl_ctx);
302   }
303   return NULL;
304 }
305
306 static int retry_async(SSL *ssl, int ret, BIO *bio) {
307   // No error; don't retry.
308   if (ret >= 0) {
309     return 0;
310   }
311   // See if we needed to read or write more. If so, allow one byte through on
312   // the appropriate end to maximally stress the state machine.
313   int err = SSL_get_error(ssl, ret);
314   if (err == SSL_ERROR_WANT_READ) {
315     async_bio_allow_read(bio, 1);
316     return 1;
317   } else if (err == SSL_ERROR_WANT_WRITE) {
318     async_bio_allow_write(bio, 1);
319     return 1;
320   }
321   return 0;
322 }
323
324 static int do_exchange(SSL_SESSION **out_session,
325                        SSL_CTX *ssl_ctx,
326                        const TestConfig *config,
327                        bool is_resume,
328                        int fd,
329                        SSL_SESSION *session) {
330   early_callback_called = 0;
331
332   SSL *ssl = SSL_new(ssl_ctx);
333   if (ssl == NULL) {
334     BIO_print_errors_fp(stdout);
335     return 1;
336   }
337
338   SetConfigPtr(ssl, config);
339
340   if (config->fallback_scsv) {
341     if (!SSL_enable_fallback_scsv(ssl)) {
342       BIO_print_errors_fp(stdout);
343       return 1;
344     }
345   }
346   if (!config->key_file.empty()) {
347     if (!SSL_use_PrivateKey_file(ssl, config->key_file.c_str(),
348                                  SSL_FILETYPE_PEM)) {
349       BIO_print_errors_fp(stdout);
350       return 1;
351     }
352   }
353   if (!config->cert_file.empty()) {
354     if (!SSL_use_certificate_file(ssl, config->cert_file.c_str(),
355                                   SSL_FILETYPE_PEM)) {
356       BIO_print_errors_fp(stdout);
357       return 1;
358     }
359   }
360   if (config->require_any_client_certificate) {
361     SSL_set_verify(ssl, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
362                    skip_verify);
363   }
364   if (config->false_start) {
365     SSL_set_mode(ssl, SSL_MODE_HANDSHAKE_CUTTHROUGH);
366   }
367   if (config->cbc_record_splitting) {
368     SSL_set_mode(ssl, SSL_MODE_CBC_RECORD_SPLITTING);
369   }
370   if (config->partial_write) {
371     SSL_set_mode(ssl, SSL_MODE_ENABLE_PARTIAL_WRITE);
372   }
373   if (config->no_tls12) {
374     SSL_set_options(ssl, SSL_OP_NO_TLSv1_2);
375   }
376   if (config->no_tls11) {
377     SSL_set_options(ssl, SSL_OP_NO_TLSv1_1);
378   }
379   if (config->no_tls1) {
380     SSL_set_options(ssl, SSL_OP_NO_TLSv1);
381   }
382   if (config->no_ssl3) {
383     SSL_set_options(ssl, SSL_OP_NO_SSLv3);
384   }
385   if (config->cookie_exchange) {
386     SSL_set_options(ssl, SSL_OP_COOKIE_EXCHANGE);
387   }
388   if (config->tls_d5_bug) {
389     SSL_set_options(ssl, SSL_OP_TLS_D5_BUG);
390   }
391   if (!config->expected_channel_id.empty()) {
392     SSL_enable_tls_channel_id(ssl);
393   }
394   if (!config->send_channel_id.empty()) {
395     EVP_PKEY *pkey = LoadPrivateKey(config->send_channel_id);
396     if (pkey == NULL) {
397       BIO_print_errors_fp(stdout);
398       return 1;
399     }
400     SSL_enable_tls_channel_id(ssl);
401     if (!SSL_set1_tls_channel_id(ssl, pkey)) {
402       EVP_PKEY_free(pkey);
403       BIO_print_errors_fp(stdout);
404       return 1;
405     }
406     EVP_PKEY_free(pkey);
407   }
408   if (!config->host_name.empty()) {
409     SSL_set_tlsext_host_name(ssl, config->host_name.c_str());
410   }
411   if (!config->advertise_alpn.empty()) {
412     SSL_set_alpn_protos(ssl, (const uint8_t *)config->advertise_alpn.data(),
413                         config->advertise_alpn.size());
414   }
415   if (!config->psk.empty()) {
416     SSL_set_psk_client_callback(ssl, psk_client_callback);
417     SSL_set_psk_server_callback(ssl, psk_server_callback);
418   }
419   if (!config->psk_identity.empty()) {
420     if (!SSL_use_psk_identity_hint(ssl, config->psk_identity.c_str())) {
421       BIO_print_errors_fp(stdout);
422       return 1;
423     }
424   }
425
426   BIO *bio = BIO_new_fd(fd, 1 /* take ownership */);
427   if (bio == NULL) {
428     BIO_print_errors_fp(stdout);
429     return 1;
430   }
431   if (config->is_dtls) {
432     BIO *packeted = packeted_bio_create();
433     BIO_push(packeted, bio);
434     bio = packeted;
435   }
436   if (config->async) {
437     BIO *async =
438         config->is_dtls ? async_bio_create_datagram() : async_bio_create();
439     BIO_push(async, bio);
440     bio = async;
441   }
442   SSL_set_bio(ssl, bio, bio);
443
444   if (session != NULL) {
445     if (SSL_set_session(ssl, session) != 1) {
446       fprintf(stderr, "failed to set session\n");
447       return 2;
448     }
449   }
450
451   int ret;
452   do {
453     if (config->is_server) {
454       ret = SSL_accept(ssl);
455     } else {
456       ret = SSL_connect(ssl);
457     }
458   } while (config->async && retry_async(ssl, ret, bio));
459   if (ret != 1) {
460     SSL_free(ssl);
461     BIO_print_errors_fp(stdout);
462     return 2;
463   }
464
465   if (is_resume && (SSL_session_reused(ssl) == config->expect_session_miss)) {
466     fprintf(stderr, "session was%s reused\n",
467             SSL_session_reused(ssl) ? "" : " not");
468     return 2;
469   }
470
471   if (!config->expected_server_name.empty()) {
472     const char *server_name =
473         SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
474     if (server_name != config->expected_server_name) {
475       fprintf(stderr, "servername mismatch (got %s; want %s)\n",
476               server_name, config->expected_server_name.c_str());
477       return 2;
478     }
479
480     if (!early_callback_called) {
481       fprintf(stderr, "early callback not called\n");
482       return 2;
483     }
484   }
485
486   if (!config->expected_certificate_types.empty()) {
487     uint8_t *certificate_types;
488     int num_certificate_types =
489         SSL_get0_certificate_types(ssl, &certificate_types);
490     if (num_certificate_types !=
491         (int)config->expected_certificate_types.size() ||
492         memcmp(certificate_types,
493                config->expected_certificate_types.data(),
494                num_certificate_types) != 0) {
495       fprintf(stderr, "certificate types mismatch\n");
496       return 2;
497     }
498   }
499
500   if (!config->expected_next_proto.empty()) {
501     const uint8_t *next_proto;
502     unsigned next_proto_len;
503     SSL_get0_next_proto_negotiated(ssl, &next_proto, &next_proto_len);
504     if (next_proto_len != config->expected_next_proto.size() ||
505         memcmp(next_proto, config->expected_next_proto.data(),
506                next_proto_len) != 0) {
507       fprintf(stderr, "negotiated next proto mismatch\n");
508       return 2;
509     }
510   }
511
512   if (!config->expected_alpn.empty()) {
513     const uint8_t *alpn_proto;
514     unsigned alpn_proto_len;
515     SSL_get0_alpn_selected(ssl, &alpn_proto, &alpn_proto_len);
516     if (alpn_proto_len != config->expected_alpn.size() ||
517         memcmp(alpn_proto, config->expected_alpn.data(),
518                alpn_proto_len) != 0) {
519       fprintf(stderr, "negotiated alpn proto mismatch\n");
520       return 2;
521     }
522   }
523
524   if (!config->expected_channel_id.empty()) {
525     uint8_t channel_id[64];
526     if (!SSL_get_tls_channel_id(ssl, channel_id, sizeof(channel_id))) {
527       fprintf(stderr, "no channel id negotiated\n");
528       return 2;
529     }
530     if (config->expected_channel_id.size() != 64 ||
531         memcmp(config->expected_channel_id.data(),
532                channel_id, 64) != 0) {
533       fprintf(stderr, "channel id mismatch\n");
534       return 2;
535     }
536   }
537
538   if (config->expect_extended_master_secret) {
539     if (!ssl->session->extended_master_secret) {
540       fprintf(stderr, "No EMS for session when expected");
541       return 2;
542     }
543   }
544
545   if (config->renegotiate) {
546     if (config->async) {
547       fprintf(stderr, "--renegotiate is not supported with --async.\n");
548       return 2;
549     }
550
551     SSL_renegotiate(ssl);
552
553     ret = SSL_do_handshake(ssl);
554     if (ret != 1) {
555       SSL_free(ssl);
556       BIO_print_errors_fp(stdout);
557       return 2;
558     }
559
560     SSL_set_state(ssl, SSL_ST_ACCEPT);
561     ret = SSL_do_handshake(ssl);
562     if (ret != 1) {
563       SSL_free(ssl);
564       BIO_print_errors_fp(stdout);
565       return 2;
566     }
567   }
568
569   if (config->write_different_record_sizes) {
570     if (config->is_dtls) {
571       fprintf(stderr, "write_different_record_sizes not supported for DTLS\n");
572       return 6;
573     }
574     // This mode writes a number of different record sizes in an attempt to
575     // trip up the CBC record splitting code.
576     uint8_t buf[32769];
577     memset(buf, 0x42, sizeof(buf));
578     static const size_t kRecordSizes[] = {
579         0, 1, 255, 256, 257, 16383, 16384, 16385, 32767, 32768, 32769};
580     for (size_t i = 0; i < sizeof(kRecordSizes) / sizeof(kRecordSizes[0]);
581          i++) {
582       int w;
583       const size_t len = kRecordSizes[i];
584       size_t off = 0;
585
586       if (len > sizeof(buf)) {
587         fprintf(stderr, "Bad kRecordSizes value.\n");
588         return 5;
589       }
590
591       do {
592         w = SSL_write(ssl, buf + off, len - off);
593         if (w > 0) {
594           off += (size_t) w;
595         }
596       } while ((config->async && retry_async(ssl, w, bio)) ||
597                (w > 0 && off < len));
598
599       if (w < 0 || off != len) {
600         SSL_free(ssl);
601         BIO_print_errors_fp(stdout);
602         return 4;
603       }
604     }
605   } else {
606     if (config->shim_writes_first) {
607       int w;
608       do {
609         w = SSL_write(ssl, "hello", 5);
610       } while (config->async && retry_async(ssl, w, bio));
611     }
612     for (;;) {
613       uint8_t buf[512];
614       int n;
615       do {
616         n = SSL_read(ssl, buf, sizeof(buf));
617       } while (config->async && retry_async(ssl, n, bio));
618       if (n < 0) {
619         SSL_free(ssl);
620         BIO_print_errors_fp(stdout);
621         return 3;
622       } else if (n == 0) {
623         break;
624       } else {
625         for (int i = 0; i < n; i++) {
626           buf[i] ^= 0xff;
627         }
628         int w;
629         do {
630           w = SSL_write(ssl, buf, n);
631         } while (config->async && retry_async(ssl, w, bio));
632         if (w != n) {
633           SSL_free(ssl);
634           BIO_print_errors_fp(stdout);
635           return 4;
636         }
637       }
638     }
639   }
640
641   if (out_session) {
642     *out_session = SSL_get1_session(ssl);
643   }
644
645   SSL_shutdown(ssl);
646   SSL_free(ssl);
647   return 0;
648 }
649
650 int main(int argc, char **argv) {
651 #if !defined(OPENSSL_WINDOWS)
652   signal(SIGPIPE, SIG_IGN);
653 #endif
654
655   if (!SSL_library_init()) {
656     return 1;
657   }
658   g_ex_data_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
659
660   TestConfig config;
661   if (!ParseConfig(argc - 1, argv + 1, &config)) {
662     return usage(argv[0]);
663   }
664
665   SSL_CTX *ssl_ctx = setup_ctx(&config);
666   if (ssl_ctx == NULL) {
667     BIO_print_errors_fp(stdout);
668     return 1;
669   }
670
671   SSL_SESSION *session = NULL;
672   int ret = do_exchange(&session,
673                         ssl_ctx, &config,
674                         false /* is_resume */,
675                         3 /* fd */, NULL /* session */);
676   if (ret != 0) {
677     goto out;
678   }
679
680   if (config.resume) {
681     ret = do_exchange(NULL,
682                       ssl_ctx, &config,
683                       true /* is_resume */,
684                       4 /* fd */,
685                       config.is_server ? NULL : session);
686     if (ret != 0) {
687       goto out;
688     }
689   }
690
691   ret = 0;
692
693 out:
694   SSL_SESSION_free(session);
695   SSL_CTX_free(ssl_ctx);
696   return ret;
697 }