tls: Make tls CPS test run for a quite long time
[vpp.git] / src / plugins / tlsopenssl / tls_openssl.c
1 /*
2  * Copyright (c) 2018 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 #include <openssl/ssl.h>
17 #include <openssl/conf.h>
18 #include <openssl/err.h>
19
20 #ifdef HAVE_OPENSSL_ASYNC
21 #include <openssl/async.h>
22 #endif
23 #include <dlfcn.h>
24 #include <vnet/plugin/plugin.h>
25 #include <vpp/app/version.h>
26 #include <vnet/tls/tls.h>
27 #include <ctype.h>
28 #include <tlsopenssl/tls_openssl.h>
29
30 #define MAX_CRYPTO_LEN 64
31
32 openssl_main_t openssl_main;
33 static u32
34 openssl_ctx_alloc (void)
35 {
36   u8 thread_index = vlib_get_thread_index ();
37   openssl_main_t *tm = &openssl_main;
38   openssl_ctx_t **ctx;
39
40   pool_get (tm->ctx_pool[thread_index], ctx);
41   if (!(*ctx))
42     *ctx = clib_mem_alloc (sizeof (openssl_ctx_t));
43
44   clib_memset (*ctx, 0, sizeof (openssl_ctx_t));
45   (*ctx)->ctx.c_thread_index = thread_index;
46   (*ctx)->ctx.tls_ctx_engine = CRYPTO_ENGINE_OPENSSL;
47   (*ctx)->ctx.app_session_handle = SESSION_INVALID_HANDLE;
48   (*ctx)->openssl_ctx_index = ctx - tm->ctx_pool[thread_index];
49   return ((*ctx)->openssl_ctx_index);
50 }
51
52 static void
53 openssl_ctx_free (tls_ctx_t * ctx)
54 {
55   openssl_ctx_t *oc = (openssl_ctx_t *) ctx;
56
57   if (SSL_is_init_finished (oc->ssl) && !ctx->is_passive_close)
58     SSL_shutdown (oc->ssl);
59
60   SSL_free (oc->ssl);
61
62   vec_free (ctx->srv_hostname);
63   pool_put_index (openssl_main.ctx_pool[ctx->c_thread_index],
64                   oc->openssl_ctx_index);
65 }
66
67 tls_ctx_t *
68 openssl_ctx_get (u32 ctx_index)
69 {
70   openssl_ctx_t **ctx;
71   ctx = pool_elt_at_index (openssl_main.ctx_pool[vlib_get_thread_index ()],
72                            ctx_index);
73   return &(*ctx)->ctx;
74 }
75
76 tls_ctx_t *
77 openssl_ctx_get_w_thread (u32 ctx_index, u8 thread_index)
78 {
79   openssl_ctx_t **ctx;
80   ctx = pool_elt_at_index (openssl_main.ctx_pool[thread_index], ctx_index);
81   return &(*ctx)->ctx;
82 }
83
84 static u32
85 openssl_listen_ctx_alloc (void)
86 {
87   openssl_main_t *om = &openssl_main;
88   openssl_listen_ctx_t *lctx;
89
90   pool_get (om->lctx_pool, lctx);
91
92   clib_memset (lctx, 0, sizeof (openssl_listen_ctx_t));
93   lctx->openssl_lctx_index = lctx - om->lctx_pool;
94   return lctx->openssl_lctx_index;
95 }
96
97 static void
98 openssl_listen_ctx_free (openssl_listen_ctx_t * lctx)
99 {
100   pool_put_index (openssl_main.lctx_pool, lctx->openssl_lctx_index);
101 }
102
103 openssl_listen_ctx_t *
104 openssl_lctx_get (u32 lctx_index)
105 {
106   return pool_elt_at_index (openssl_main.lctx_pool, lctx_index);
107 }
108
109 static int
110 openssl_try_handshake_read (openssl_ctx_t * oc, session_t * tls_session)
111 {
112   u32 deq_max, deq_now;
113   svm_fifo_t *f;
114   int wrote, rv;
115
116   f = tls_session->rx_fifo;
117   deq_max = svm_fifo_max_dequeue_cons (f);
118   if (!deq_max)
119     return 0;
120
121   deq_now = clib_min (svm_fifo_max_read_chunk (f), deq_max);
122   wrote = BIO_write (oc->wbio, svm_fifo_head (f), deq_now);
123   if (wrote <= 0)
124     return 0;
125
126   svm_fifo_dequeue_drop (f, wrote);
127   if (wrote < deq_max)
128     {
129       deq_now = clib_min (svm_fifo_max_read_chunk (f), deq_max - wrote);
130       rv = BIO_write (oc->wbio, svm_fifo_head (f), deq_now);
131       if (rv > 0)
132         {
133           svm_fifo_dequeue_drop (f, rv);
134           wrote += rv;
135         }
136     }
137   return wrote;
138 }
139
140 static int
141 openssl_try_handshake_write (openssl_ctx_t * oc, session_t * tls_session)
142 {
143   u32 enq_max, deq_now;
144   svm_fifo_t *f;
145   int read, rv;
146
147   if (BIO_ctrl_pending (oc->rbio) <= 0)
148     return 0;
149
150   f = tls_session->tx_fifo;
151   enq_max = svm_fifo_max_enqueue_prod (f);
152   if (!enq_max)
153     return 0;
154
155   deq_now = clib_min (svm_fifo_max_write_chunk (f), enq_max);
156   read = BIO_read (oc->rbio, svm_fifo_tail (f), deq_now);
157   if (read <= 0)
158     return 0;
159
160   svm_fifo_enqueue_nocopy (f, read);
161   tls_add_vpp_q_tx_evt (tls_session);
162
163   if (read < enq_max)
164     {
165       deq_now = clib_min (svm_fifo_max_write_chunk (f), enq_max - read);
166       rv = BIO_read (oc->rbio, svm_fifo_tail (f), deq_now);
167       if (rv > 0)
168         {
169           svm_fifo_enqueue_nocopy (f, rv);
170           read += rv;
171         }
172     }
173
174   return read;
175 }
176
177 #ifdef HAVE_OPENSSL_ASYNC
178 static int
179 vpp_ssl_async_process_event (tls_ctx_t * ctx,
180                              openssl_resume_handler * handler)
181 {
182   openssl_ctx_t *oc = (openssl_ctx_t *) ctx;
183   openssl_tls_callback_t *engine_cb;
184
185   engine_cb = vpp_add_async_pending_event (ctx, handler);
186   if (engine_cb)
187     {
188       SSL_set_async_callback_arg (oc->ssl, (void *) engine_cb->arg);
189       TLS_DBG (2, "set callback to engine %p\n", engine_cb->callback);
190     }
191   return 0;
192
193 }
194
195 /* Due to engine busy stat, VPP need to retry later */
196 static int
197 vpp_ssl_async_retry_func (tls_ctx_t * ctx, openssl_resume_handler * handler)
198 {
199
200   if (vpp_add_async_run_event (ctx, handler))
201     return 1;
202
203   return 0;
204
205 }
206
207 #endif
208
209 static void
210 openssl_handle_handshake_failure (tls_ctx_t * ctx)
211 {
212   if (SSL_is_server (((openssl_ctx_t *) ctx)->ssl))
213     {
214       /*
215        * Cleanup pre-allocated app session and close transport
216        */
217       session_free (session_get (ctx->c_s_index, ctx->c_thread_index));
218       ctx->no_app_session = 1;
219       ctx->c_s_index = SESSION_INVALID_INDEX;
220       tls_disconnect_transport (ctx);
221     }
222   else
223     {
224       /*
225        * Also handles cleanup of the pre-allocated session
226        */
227       tls_notify_app_connected (ctx, /* is failed */ 1);
228     }
229 }
230
231 int
232 openssl_ctx_handshake_rx (tls_ctx_t * ctx, session_t * tls_session)
233 {
234   openssl_ctx_t *oc = (openssl_ctx_t *) ctx;
235   int rv = 0, err;
236 #ifdef HAVE_OPENSSL_ASYNC
237   int estatus;
238   openssl_resume_handler *myself;
239 #endif
240
241   while (SSL_in_init (oc->ssl))
242     {
243       if (ctx->resume)
244         {
245           ctx->resume = 0;
246         }
247       else if (!openssl_try_handshake_read (oc, tls_session))
248         {
249           break;
250         }
251
252 #ifdef HAVE_OPENSSL_ASYNC
253       myself = openssl_ctx_handshake_rx;
254       vpp_ssl_async_process_event (ctx, myself);
255 #endif
256
257       rv = SSL_do_handshake (oc->ssl);
258       err = SSL_get_error (oc->ssl, rv);
259
260       if (err == SSL_ERROR_SSL)
261         {
262           char buf[512];
263           ERR_error_string (ERR_get_error (), buf);
264           clib_warning ("Err: %s", buf);
265
266           openssl_handle_handshake_failure (ctx);
267           return -1;
268         }
269
270       openssl_try_handshake_write (oc, tls_session);
271 #ifdef HAVE_OPENSSL_ASYNC
272       if (err == SSL_ERROR_WANT_ASYNC)
273         {
274           SSL_get_async_status (oc->ssl, &estatus);
275
276           if (estatus == ASYNC_STATUS_EAGAIN)
277             {
278               vpp_ssl_async_retry_func (ctx, myself);
279             }
280         }
281 #endif
282
283       if (err != SSL_ERROR_WANT_WRITE)
284         break;
285     }
286   TLS_DBG (2, "tls state for %u is %s", oc->openssl_ctx_index,
287            SSL_state_string_long (oc->ssl));
288
289   if (SSL_in_init (oc->ssl))
290     return 0;
291
292   /*
293    * Handshake complete
294    */
295   if (!SSL_is_server (oc->ssl))
296     {
297       /*
298        * Verify server certificate
299        */
300       if ((rv = SSL_get_verify_result (oc->ssl)) != X509_V_OK)
301         {
302           TLS_DBG (1, " failed verify: %s\n",
303                    X509_verify_cert_error_string (rv));
304
305           /*
306            * Presence of hostname enforces strict certificate verification
307            */
308           if (ctx->srv_hostname)
309             {
310               tls_notify_app_connected (ctx, /* is failed */ 0);
311               return -1;
312             }
313         }
314       tls_notify_app_connected (ctx, /* is failed */ 0);
315     }
316   else
317     {
318       tls_notify_app_accept (ctx);
319     }
320
321   TLS_DBG (1, "Handshake for %u complete. TLS cipher is %s",
322            oc->openssl_ctx_index, SSL_get_cipher (oc->ssl));
323   return rv;
324 }
325
326 static void
327 openssl_confirm_app_close (tls_ctx_t * ctx)
328 {
329   tls_disconnect_transport (ctx);
330   session_transport_closed_notify (&ctx->connection);
331 }
332
333 static inline int
334 openssl_ctx_write (tls_ctx_t * ctx, session_t * app_session)
335 {
336   openssl_ctx_t *oc = (openssl_ctx_t *) ctx;
337   int wrote = 0, rv, read, max_buf = 100 * TLS_CHUNK_SIZE, max_space;
338   u32 enq_max, deq_max, deq_now, to_write;
339   session_t *tls_session;
340   svm_fifo_t *f;
341
342   f = app_session->tx_fifo;
343   deq_max = svm_fifo_max_dequeue_cons (f);
344   if (!deq_max)
345     goto check_tls_fifo;
346
347   max_space = max_buf - BIO_ctrl_pending (oc->rbio);
348   max_space = (max_space < 0) ? 0 : max_space;
349   deq_now = clib_min (deq_max, (u32) max_space);
350   to_write = clib_min (svm_fifo_max_read_chunk (f), deq_now);
351   wrote = SSL_write (oc->ssl, svm_fifo_head (f), to_write);
352   if (wrote <= 0)
353     {
354       tls_add_vpp_q_builtin_tx_evt (app_session);
355       goto check_tls_fifo;
356     }
357   svm_fifo_dequeue_drop (app_session->tx_fifo, wrote);
358   if (wrote < deq_now)
359     {
360       to_write = clib_min (svm_fifo_max_read_chunk (f), deq_now - wrote);
361       rv = SSL_write (oc->ssl, svm_fifo_head (f), to_write);
362       if (rv > 0)
363         {
364           svm_fifo_dequeue_drop (app_session->tx_fifo, rv);
365           wrote += rv;
366         }
367     }
368
369   if (svm_fifo_needs_deq_ntf (app_session->tx_fifo, wrote))
370     session_dequeue_notify (app_session);
371
372   if (wrote < deq_max)
373     tls_add_vpp_q_builtin_tx_evt (app_session);
374
375 check_tls_fifo:
376
377   if (BIO_ctrl_pending (oc->rbio) <= 0)
378     return wrote;
379
380   tls_session = session_get_from_handle (ctx->tls_session_handle);
381   f = tls_session->tx_fifo;
382   enq_max = svm_fifo_max_enqueue_prod (f);
383   if (!enq_max)
384     {
385       tls_add_vpp_q_builtin_tx_evt (app_session);
386       return wrote;
387     }
388
389   deq_now = clib_min (svm_fifo_max_write_chunk (f), enq_max);
390   read = BIO_read (oc->rbio, svm_fifo_tail (f), deq_now);
391   if (read <= 0)
392     {
393       tls_add_vpp_q_builtin_tx_evt (app_session);
394       return wrote;
395     }
396
397   svm_fifo_enqueue_nocopy (f, read);
398   tls_add_vpp_q_tx_evt (tls_session);
399
400   if (read < enq_max && BIO_ctrl_pending (oc->rbio) > 0)
401     {
402       deq_now = clib_min (svm_fifo_max_write_chunk (f), enq_max - read);
403       read = BIO_read (oc->rbio, svm_fifo_tail (f), deq_now);
404       if (read > 0)
405         svm_fifo_enqueue_nocopy (f, read);
406     }
407
408   if (BIO_ctrl_pending (oc->rbio) > 0)
409     tls_add_vpp_q_builtin_tx_evt (app_session);
410   else if (ctx->app_closed)
411     openssl_confirm_app_close (ctx);
412
413   return wrote;
414 }
415
416 static inline int
417 openssl_ctx_read (tls_ctx_t * ctx, session_t * tls_session)
418 {
419   int read, wrote = 0, max_space, max_buf = 100 * TLS_CHUNK_SIZE, rv;
420   openssl_ctx_t *oc = (openssl_ctx_t *) ctx;
421   u32 deq_max, enq_max, deq_now, to_read;
422   session_t *app_session;
423   svm_fifo_t *f;
424
425   if (PREDICT_FALSE (SSL_in_init (oc->ssl)))
426     {
427       if (openssl_ctx_handshake_rx (ctx, tls_session) < 0)
428         return 0;
429       else
430         goto check_app_fifo;
431     }
432
433   f = tls_session->rx_fifo;
434   deq_max = svm_fifo_max_dequeue_cons (f);
435   max_space = max_buf - BIO_ctrl_pending (oc->wbio);
436   max_space = max_space < 0 ? 0 : max_space;
437   deq_now = clib_min (deq_max, max_space);
438   if (!deq_now)
439     goto check_app_fifo;
440
441   to_read = clib_min (svm_fifo_max_read_chunk (f), deq_now);
442   wrote = BIO_write (oc->wbio, svm_fifo_head (f), to_read);
443   if (wrote <= 0)
444     {
445       tls_add_vpp_q_builtin_rx_evt (tls_session);
446       goto check_app_fifo;
447     }
448   svm_fifo_dequeue_drop (f, wrote);
449   if (wrote < deq_now)
450     {
451       to_read = clib_min (svm_fifo_max_read_chunk (f), deq_now - wrote);
452       rv = BIO_write (oc->wbio, svm_fifo_head (f), to_read);
453       if (rv > 0)
454         {
455           svm_fifo_dequeue_drop (f, rv);
456           wrote += rv;
457         }
458     }
459   if (svm_fifo_max_dequeue_cons (f))
460     tls_add_vpp_q_builtin_rx_evt (tls_session);
461
462 check_app_fifo:
463
464   if (BIO_ctrl_pending (oc->wbio) <= 0)
465     return wrote;
466
467   app_session = session_get_from_handle (ctx->app_session_handle);
468   f = app_session->rx_fifo;
469   enq_max = svm_fifo_max_enqueue_prod (f);
470   if (!enq_max)
471     {
472       tls_add_vpp_q_builtin_rx_evt (tls_session);
473       return wrote;
474     }
475
476   deq_now = clib_min (svm_fifo_max_write_chunk (f), enq_max);
477   read = SSL_read (oc->ssl, svm_fifo_tail (f), deq_now);
478   if (read <= 0)
479     {
480       tls_add_vpp_q_builtin_rx_evt (tls_session);
481       return wrote;
482     }
483   svm_fifo_enqueue_nocopy (f, read);
484   if (read < enq_max && SSL_pending (oc->ssl) > 0)
485     {
486       deq_now = clib_min (svm_fifo_max_write_chunk (f), enq_max - read);
487       read = SSL_read (oc->ssl, svm_fifo_tail (f), deq_now);
488       if (read > 0)
489         svm_fifo_enqueue_nocopy (f, read);
490     }
491
492   /* If handshake just completed, session may still be in accepting state */
493   if (app_session->session_state >= SESSION_STATE_READY)
494     tls_notify_app_enqueue (ctx, app_session);
495   if (SSL_pending (oc->ssl) > 0)
496     tls_add_vpp_q_builtin_rx_evt (tls_session);
497
498   return wrote;
499 }
500
501 static int
502 openssl_ctx_init_client (tls_ctx_t * ctx)
503 {
504   long flags = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION;
505   openssl_ctx_t *oc = (openssl_ctx_t *) ctx;
506   openssl_main_t *om = &openssl_main;
507   session_t *tls_session;
508   const SSL_METHOD *method;
509   int rv, err;
510 #ifdef HAVE_OPENSSL_ASYNC
511   openssl_resume_handler *handler;
512 #endif
513
514   method = SSLv23_client_method ();
515   if (method == NULL)
516     {
517       TLS_DBG (1, "SSLv23_method returned null");
518       return -1;
519     }
520
521   oc->ssl_ctx = SSL_CTX_new (method);
522   if (oc->ssl_ctx == NULL)
523     {
524       TLS_DBG (1, "SSL_CTX_new returned null");
525       return -1;
526     }
527
528   SSL_CTX_set_ecdh_auto (oc->ssl_ctx, 1);
529   SSL_CTX_set_mode (oc->ssl_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE);
530 #ifdef HAVE_OPENSSL_ASYNC
531   if (om->async)
532     SSL_CTX_set_mode (oc->ssl_ctx, SSL_MODE_ASYNC);
533 #endif
534   rv = SSL_CTX_set_cipher_list (oc->ssl_ctx, (const char *) om->ciphers);
535   if (rv != 1)
536     {
537       TLS_DBG (1, "Couldn't set cipher");
538       return -1;
539     }
540
541   SSL_CTX_set_options (oc->ssl_ctx, flags);
542   SSL_CTX_set_cert_store (oc->ssl_ctx, om->cert_store);
543
544   oc->ssl = SSL_new (oc->ssl_ctx);
545   if (oc->ssl == NULL)
546     {
547       TLS_DBG (1, "Couldn't initialize ssl struct");
548       return -1;
549     }
550
551   oc->rbio = BIO_new (BIO_s_mem ());
552   oc->wbio = BIO_new (BIO_s_mem ());
553
554   BIO_set_mem_eof_return (oc->rbio, -1);
555   BIO_set_mem_eof_return (oc->wbio, -1);
556
557   SSL_set_bio (oc->ssl, oc->wbio, oc->rbio);
558   SSL_set_connect_state (oc->ssl);
559
560   rv = SSL_set_tlsext_host_name (oc->ssl, ctx->srv_hostname);
561   if (rv != 1)
562     {
563       TLS_DBG (1, "Couldn't set hostname");
564       return -1;
565     }
566
567   /*
568    * 2. Do the first steps in the handshake.
569    */
570   TLS_DBG (1, "Initiating handshake for [%u]%u", ctx->c_thread_index,
571            oc->openssl_ctx_index);
572
573   tls_session = session_get_from_handle (ctx->tls_session_handle);
574   while (1)
575     {
576       rv = SSL_do_handshake (oc->ssl);
577       err = SSL_get_error (oc->ssl, rv);
578       openssl_try_handshake_write (oc, tls_session);
579 #ifdef HAVE_OPENSSL_ASYNC
580       if (err == SSL_ERROR_WANT_ASYNC)
581         {
582           handler = (openssl_resume_handler *) openssl_ctx_handshake_rx;
583           vpp_ssl_async_process_event (ctx, handler);
584           break;
585         }
586 #endif
587       if (err != SSL_ERROR_WANT_WRITE)
588         break;
589     }
590
591   TLS_DBG (2, "tls state for [%u]%u is su", ctx->c_thread_index,
592            oc->openssl_ctx_index, SSL_state_string_long (oc->ssl));
593   return 0;
594 }
595
596 static int
597 openssl_start_listen (tls_ctx_t * lctx)
598 {
599   const SSL_METHOD *method;
600   SSL_CTX *ssl_ctx;
601   int rv;
602   BIO *cert_bio;
603   X509 *srvcert;
604   EVP_PKEY *pkey;
605   u32 olc_index;
606   openssl_listen_ctx_t *olc;
607   app_cert_key_pair_t *ckpair;
608
609   long flags = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION;
610   openssl_main_t *om = &openssl_main;
611
612   ckpair = app_cert_key_pair_get_if_valid (lctx->ckpair_index);
613   if (!ckpair)
614     return -1;
615
616   if (!ckpair->cert || !ckpair->key)
617     {
618       TLS_DBG (1, "tls cert and/or key not configured %d",
619                lctx->parent_app_wrk_index);
620       return -1;
621     }
622
623   method = SSLv23_method ();
624   ssl_ctx = SSL_CTX_new (method);
625   if (!ssl_ctx)
626     {
627       clib_warning ("Unable to create SSL context");
628       return -1;
629     }
630
631   SSL_CTX_set_mode (ssl_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE);
632 #ifdef HAVE_OPENSSL_ASYNC
633   if (om->async)
634     SSL_CTX_set_mode (ssl_ctx, SSL_MODE_ASYNC);
635   SSL_CTX_set_async_callback (ssl_ctx, tls_async_openssl_callback);
636 #endif
637   SSL_CTX_set_options (ssl_ctx, flags);
638   SSL_CTX_set_ecdh_auto (ssl_ctx, 1);
639
640   rv = SSL_CTX_set_cipher_list (ssl_ctx, (const char *) om->ciphers);
641   if (rv != 1)
642     {
643       TLS_DBG (1, "Couldn't set cipher");
644       return -1;
645     }
646
647   /*
648    * Set the key and cert
649    */
650   cert_bio = BIO_new (BIO_s_mem ());
651   BIO_write (cert_bio, ckpair->cert, vec_len (ckpair->cert));
652   srvcert = PEM_read_bio_X509 (cert_bio, NULL, NULL, NULL);
653   if (!srvcert)
654     {
655       clib_warning ("unable to parse certificate");
656       return -1;
657     }
658   SSL_CTX_use_certificate (ssl_ctx, srvcert);
659   BIO_free (cert_bio);
660
661   cert_bio = BIO_new (BIO_s_mem ());
662   BIO_write (cert_bio, ckpair->key, vec_len (ckpair->key));
663   pkey = PEM_read_bio_PrivateKey (cert_bio, NULL, NULL, NULL);
664   if (!pkey)
665     {
666       clib_warning ("unable to parse pkey");
667       return -1;
668     }
669   SSL_CTX_use_PrivateKey (ssl_ctx, pkey);
670   BIO_free (cert_bio);
671
672   olc_index = openssl_listen_ctx_alloc ();
673   olc = openssl_lctx_get (olc_index);
674   olc->ssl_ctx = ssl_ctx;
675   olc->srvcert = srvcert;
676   olc->pkey = pkey;
677
678   /* store SSL_CTX into TLS level structure */
679   lctx->tls_ssl_ctx = olc_index;
680
681   return 0;
682
683 }
684
685 static int
686 openssl_stop_listen (tls_ctx_t * lctx)
687 {
688   u32 olc_index;
689   openssl_listen_ctx_t *olc;
690
691   olc_index = lctx->tls_ssl_ctx;
692   olc = openssl_lctx_get (olc_index);
693
694   X509_free (olc->srvcert);
695   EVP_PKEY_free (olc->pkey);
696
697   SSL_CTX_free (olc->ssl_ctx);
698   openssl_listen_ctx_free (olc);
699
700   return 0;
701 }
702
703 static int
704 openssl_ctx_init_server (tls_ctx_t * ctx)
705 {
706   openssl_ctx_t *oc = (openssl_ctx_t *) ctx;
707   u32 olc_index = ctx->tls_ssl_ctx;
708   openssl_listen_ctx_t *olc;
709   session_t *tls_session;
710   int rv, err;
711 #ifdef HAVE_OPENSSL_ASYNC
712   openssl_resume_handler *handler;
713 #endif
714
715   /* Start a new connection */
716
717   olc = openssl_lctx_get (olc_index);
718   oc->ssl = SSL_new (olc->ssl_ctx);
719   if (oc->ssl == NULL)
720     {
721       TLS_DBG (1, "Couldn't initialize ssl struct");
722       return -1;
723     }
724
725   oc->rbio = BIO_new (BIO_s_mem ());
726   oc->wbio = BIO_new (BIO_s_mem ());
727
728   BIO_set_mem_eof_return (oc->rbio, -1);
729   BIO_set_mem_eof_return (oc->wbio, -1);
730
731   SSL_set_bio (oc->ssl, oc->wbio, oc->rbio);
732   SSL_set_accept_state (oc->ssl);
733
734   TLS_DBG (1, "Initiating handshake for [%u]%u", ctx->c_thread_index,
735            oc->openssl_ctx_index);
736
737   tls_session = session_get_from_handle (ctx->tls_session_handle);
738   while (1)
739     {
740       rv = SSL_do_handshake (oc->ssl);
741       err = SSL_get_error (oc->ssl, rv);
742       openssl_try_handshake_write (oc, tls_session);
743 #ifdef HAVE_OPENSSL_ASYNC
744       if (err == SSL_ERROR_WANT_ASYNC)
745         {
746           handler = (openssl_resume_handler *) openssl_ctx_handshake_rx;
747           vpp_ssl_async_process_event (ctx, handler);
748           break;
749         }
750 #endif
751       if (err != SSL_ERROR_WANT_WRITE)
752         break;
753     }
754
755   TLS_DBG (2, "tls state for [%u]%u is su", ctx->c_thread_index,
756            oc->openssl_ctx_index, SSL_state_string_long (oc->ssl));
757   return 0;
758 }
759
760 static u8
761 openssl_handshake_is_over (tls_ctx_t * ctx)
762 {
763   openssl_ctx_t *mc = (openssl_ctx_t *) ctx;
764   if (!mc->ssl)
765     return 0;
766   return SSL_is_init_finished (mc->ssl);
767 }
768
769 static int
770 openssl_transport_close (tls_ctx_t * ctx)
771 {
772   if (!openssl_handshake_is_over (ctx))
773     {
774       openssl_handle_handshake_failure (ctx);
775       return 0;
776     }
777   session_transport_closing_notify (&ctx->connection);
778   return 0;
779 }
780
781 static int
782 openssl_app_close (tls_ctx_t * ctx)
783 {
784   openssl_ctx_t *oc = (openssl_ctx_t *) ctx;
785   session_t *app_session;
786
787   /* Wait for all data to be written to tcp */
788   app_session = session_get_from_handle (ctx->app_session_handle);
789   if (BIO_ctrl_pending (oc->rbio) <= 0
790       && !svm_fifo_max_dequeue_cons (app_session->tx_fifo))
791     openssl_confirm_app_close (ctx);
792   else
793     ctx->app_closed = 1;
794   return 0;
795 }
796
797 const static tls_engine_vft_t openssl_engine = {
798   .ctx_alloc = openssl_ctx_alloc,
799   .ctx_free = openssl_ctx_free,
800   .ctx_get = openssl_ctx_get,
801   .ctx_get_w_thread = openssl_ctx_get_w_thread,
802   .ctx_init_server = openssl_ctx_init_server,
803   .ctx_init_client = openssl_ctx_init_client,
804   .ctx_write = openssl_ctx_write,
805   .ctx_read = openssl_ctx_read,
806   .ctx_handshake_is_over = openssl_handshake_is_over,
807   .ctx_start_listen = openssl_start_listen,
808   .ctx_stop_listen = openssl_stop_listen,
809   .ctx_transport_close = openssl_transport_close,
810   .ctx_app_close = openssl_app_close,
811 };
812
813 int
814 tls_init_ca_chain (void)
815 {
816   openssl_main_t *om = &openssl_main;
817   tls_main_t *tm = vnet_tls_get_main ();
818   BIO *cert_bio;
819   X509 *testcert;
820   int rv;
821
822   if (access (tm->ca_cert_path, F_OK | R_OK) == -1)
823     {
824       clib_warning ("Could not initialize TLS CA certificates");
825       return -1;
826     }
827
828   if (!(om->cert_store = X509_STORE_new ()))
829     {
830       clib_warning ("failed to create cert store");
831       return -1;
832     }
833
834   rv = X509_STORE_load_locations (om->cert_store, tm->ca_cert_path, 0);
835   if (rv < 0)
836     {
837       clib_warning ("failed to load ca certificate");
838     }
839
840   if (tm->use_test_cert_in_ca)
841     {
842       cert_bio = BIO_new (BIO_s_mem ());
843       BIO_write (cert_bio, test_srv_crt_rsa, test_srv_crt_rsa_len);
844       testcert = PEM_read_bio_X509 (cert_bio, NULL, NULL, NULL);
845       if (!testcert)
846         {
847           clib_warning ("unable to parse certificate");
848           return -1;
849         }
850       X509_STORE_add_cert (om->cert_store, testcert);
851       rv = 0;
852     }
853   return (rv < 0 ? -1 : 0);
854 }
855
856 int
857 tls_openssl_set_ciphers (char *ciphers)
858 {
859   openssl_main_t *om = &openssl_main;
860   int i;
861
862   if (!ciphers)
863     {
864       return -1;
865     }
866
867   vec_validate (om->ciphers, strlen (ciphers) - 1);
868   for (i = 0; i < vec_len (om->ciphers); i++)
869     {
870       om->ciphers[i] = toupper (ciphers[i]);
871     }
872
873   return 0;
874
875 }
876
877 static clib_error_t *
878 tls_openssl_init (vlib_main_t * vm)
879 {
880   vlib_thread_main_t *vtm = vlib_get_thread_main ();
881   openssl_main_t *om = &openssl_main;
882   clib_error_t *error = 0;
883   u32 num_threads;
884
885   error = tls_openssl_api_init (vm);
886   num_threads = 1 /* main thread */  + vtm->n_threads;
887
888   SSL_library_init ();
889   SSL_load_error_strings ();
890
891   if (tls_init_ca_chain ())
892     {
893       clib_warning ("failed to initialize TLS CA chain");
894       return 0;
895     }
896
897   vec_validate (om->ctx_pool, num_threads - 1);
898
899   tls_register_engine (&openssl_engine, CRYPTO_ENGINE_OPENSSL);
900
901   om->engine_init = 0;
902
903   /* default ciphers */
904   tls_openssl_set_ciphers
905     ("ALL:!ADH:!LOW:!EXP:!MD5:!RC4-SHA:!DES-CBC3-SHA:@STRENGTH");
906
907   return error;
908 }
909 /* *INDENT-OFF* */
910 VLIB_INIT_FUNCTION (tls_openssl_init) =
911 {
912   .runs_after = VLIB_INITS("tls_init"),
913 };
914 /* *INDENT-ON* */
915
916 #ifdef HAVE_OPENSSL_ASYNC
917 static clib_error_t *
918 tls_openssl_set_command_fn (vlib_main_t * vm, unformat_input_t * input,
919                             vlib_cli_command_t * cmd)
920 {
921   openssl_main_t *om = &openssl_main;
922   char *engine_name = NULL;
923   char *engine_alg = NULL;
924   char *ciphers = NULL;
925   u8 engine_name_set = 0;
926   int i;
927
928   /* By present, it is not allowed to configure engine again after running */
929   if (om->engine_init)
930     {
931       clib_warning ("engine has started!\n");
932       return clib_error_return
933         (0, "engine has started, and no config is accepted");
934     }
935
936   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
937     {
938       if (unformat (input, "engine %s", &engine_name))
939         {
940           engine_name_set = 1;
941         }
942       else if (unformat (input, "async"))
943         {
944           om->async = 1;
945           openssl_async_node_enable_disable (1);
946         }
947       else if (unformat (input, "alg %s", &engine_alg))
948         {
949           for (i = 0; i < strnlen (engine_alg, MAX_CRYPTO_LEN); i++)
950             engine_alg[i] = toupper (engine_alg[i]);
951         }
952       else if (unformat (input, "ciphers %s", &ciphers))
953         {
954           tls_openssl_set_ciphers (ciphers);
955         }
956       else
957         return clib_error_return (0, "failed: unknown input `%U'",
958                                   format_unformat_error, input);
959     }
960
961   /* reset parameters if engine is not configured */
962   if (!engine_name_set)
963     {
964       clib_warning ("No engine provided! \n");
965       om->async = 0;
966     }
967   else
968     {
969       if (openssl_engine_register (engine_name, engine_alg) < 0)
970         {
971           return clib_error_return (0, "failed to register %s polling",
972                                     engine_name);
973         }
974     }
975
976   return 0;
977 }
978
979 /* *INDENT-OFF* */
980 VLIB_CLI_COMMAND (tls_openssl_set_command, static) =
981 {
982   .path = "tls openssl set",
983   .short_help = "tls openssl set [engine <engine name>] [alg [algorithm] [async]",
984   .function = tls_openssl_set_command_fn,
985 };
986 /* *INDENT-ON* */
987 #endif
988
989 /* *INDENT-OFF* */
990 VLIB_PLUGIN_REGISTER () = {
991     .version = VPP_BUILD_VER,
992     .description = "Transport Layer Security (TLS) Engine, OpenSSL Based",
993 };
994 /* *INDENT-ON* */
995
996 /*
997  * fd.io coding-style-patch-verification: ON
998  *
999  * Local Variables:
1000  * eval: (c-set-style "gnu")
1001  * End:
1002  */