tls: Add C API for TLS openssl to set engine
[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 = TLS_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       openssl_ctx_handshake_rx (ctx, tls_session);
428       return 0;
429     }
430
431   f = tls_session->rx_fifo;
432   deq_max = svm_fifo_max_dequeue_cons (f);
433   max_space = max_buf - BIO_ctrl_pending (oc->wbio);
434   max_space = max_space < 0 ? 0 : max_space;
435   deq_now = clib_min (deq_max, max_space);
436   if (!deq_now)
437     goto check_app_fifo;
438
439   to_read = clib_min (svm_fifo_max_read_chunk (f), deq_now);
440   wrote = BIO_write (oc->wbio, svm_fifo_head (f), to_read);
441   if (wrote <= 0)
442     {
443       tls_add_vpp_q_builtin_rx_evt (tls_session);
444       goto check_app_fifo;
445     }
446   svm_fifo_dequeue_drop (f, wrote);
447   if (wrote < deq_now)
448     {
449       to_read = clib_min (svm_fifo_max_read_chunk (f), deq_now - wrote);
450       rv = BIO_write (oc->wbio, svm_fifo_head (f), to_read);
451       if (rv > 0)
452         {
453           svm_fifo_dequeue_drop (f, rv);
454           wrote += rv;
455         }
456     }
457   if (svm_fifo_max_dequeue_cons (f))
458     tls_add_vpp_q_builtin_rx_evt (tls_session);
459
460 check_app_fifo:
461
462   if (BIO_ctrl_pending (oc->wbio) <= 0)
463     return wrote;
464
465   app_session = session_get_from_handle (ctx->app_session_handle);
466   f = app_session->rx_fifo;
467   enq_max = svm_fifo_max_enqueue_prod (f);
468   if (!enq_max)
469     {
470       tls_add_vpp_q_builtin_rx_evt (tls_session);
471       return wrote;
472     }
473
474   deq_now = clib_min (svm_fifo_max_write_chunk (f), enq_max);
475   read = SSL_read (oc->ssl, svm_fifo_tail (f), deq_now);
476   if (read <= 0)
477     {
478       tls_add_vpp_q_builtin_rx_evt (tls_session);
479       return wrote;
480     }
481   svm_fifo_enqueue_nocopy (f, read);
482   if (read < enq_max && BIO_ctrl_pending (oc->wbio) > 0)
483     {
484       deq_now = clib_min (svm_fifo_max_write_chunk (f), enq_max - read);
485       read = SSL_read (oc->ssl, svm_fifo_tail (f), deq_now);
486       if (read > 0)
487         svm_fifo_enqueue_nocopy (f, read);
488     }
489
490   tls_notify_app_enqueue (ctx, app_session);
491   if (BIO_ctrl_pending (oc->wbio) > 0)
492     tls_add_vpp_q_builtin_rx_evt (tls_session);
493
494   return wrote;
495 }
496
497 static int
498 openssl_ctx_init_client (tls_ctx_t * ctx)
499 {
500   long flags = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION;
501   openssl_ctx_t *oc = (openssl_ctx_t *) ctx;
502   openssl_main_t *om = &openssl_main;
503   session_t *tls_session;
504   const SSL_METHOD *method;
505   int rv, err;
506 #ifdef HAVE_OPENSSL_ASYNC
507   openssl_resume_handler *handler;
508 #endif
509
510   method = SSLv23_client_method ();
511   if (method == NULL)
512     {
513       TLS_DBG (1, "SSLv23_method returned null");
514       return -1;
515     }
516
517   oc->ssl_ctx = SSL_CTX_new (method);
518   if (oc->ssl_ctx == NULL)
519     {
520       TLS_DBG (1, "SSL_CTX_new returned null");
521       return -1;
522     }
523
524   SSL_CTX_set_ecdh_auto (oc->ssl_ctx, 1);
525   SSL_CTX_set_mode (oc->ssl_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE);
526 #ifdef HAVE_OPENSSL_ASYNC
527   if (om->async)
528     SSL_CTX_set_mode (oc->ssl_ctx, SSL_MODE_ASYNC);
529 #endif
530   rv = SSL_CTX_set_cipher_list (oc->ssl_ctx, (const char *) om->ciphers);
531   if (rv != 1)
532     {
533       TLS_DBG (1, "Couldn't set cipher");
534       return -1;
535     }
536
537   SSL_CTX_set_options (oc->ssl_ctx, flags);
538   SSL_CTX_set_cert_store (oc->ssl_ctx, om->cert_store);
539
540   oc->ssl = SSL_new (oc->ssl_ctx);
541   if (oc->ssl == NULL)
542     {
543       TLS_DBG (1, "Couldn't initialize ssl struct");
544       return -1;
545     }
546
547   oc->rbio = BIO_new (BIO_s_mem ());
548   oc->wbio = BIO_new (BIO_s_mem ());
549
550   BIO_set_mem_eof_return (oc->rbio, -1);
551   BIO_set_mem_eof_return (oc->wbio, -1);
552
553   SSL_set_bio (oc->ssl, oc->wbio, oc->rbio);
554   SSL_set_connect_state (oc->ssl);
555
556   rv = SSL_set_tlsext_host_name (oc->ssl, ctx->srv_hostname);
557   if (rv != 1)
558     {
559       TLS_DBG (1, "Couldn't set hostname");
560       return -1;
561     }
562
563   /*
564    * 2. Do the first steps in the handshake.
565    */
566   TLS_DBG (1, "Initiating handshake for [%u]%u", ctx->c_thread_index,
567            oc->openssl_ctx_index);
568
569   tls_session = session_get_from_handle (ctx->tls_session_handle);
570   while (1)
571     {
572       rv = SSL_do_handshake (oc->ssl);
573       err = SSL_get_error (oc->ssl, rv);
574       openssl_try_handshake_write (oc, tls_session);
575 #ifdef HAVE_OPENSSL_ASYNC
576       if (err == SSL_ERROR_WANT_ASYNC)
577         {
578           handler = (openssl_resume_handler *) openssl_ctx_handshake_rx;
579           vpp_ssl_async_process_event (ctx, handler);
580           break;
581         }
582 #endif
583       if (err != SSL_ERROR_WANT_WRITE)
584         break;
585     }
586
587   TLS_DBG (2, "tls state for [%u]%u is su", ctx->c_thread_index,
588            oc->openssl_ctx_index, SSL_state_string_long (oc->ssl));
589   return 0;
590 }
591
592 static int
593 openssl_start_listen (tls_ctx_t * lctx)
594 {
595   application_t *app;
596   const SSL_METHOD *method;
597   SSL_CTX *ssl_ctx;
598   int rv;
599   BIO *cert_bio;
600   X509 *srvcert;
601   EVP_PKEY *pkey;
602   u32 olc_index;
603   openssl_listen_ctx_t *olc;
604   app_worker_t *app_wrk;
605
606   long flags = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION;
607   openssl_main_t *om = &openssl_main;
608
609   app_wrk = app_worker_get (lctx->parent_app_wrk_index);
610   if (!app_wrk)
611     return -1;
612
613   app = application_get (app_wrk->app_index);
614   if (!app->tls_cert || !app->tls_key)
615     {
616       TLS_DBG (1, "tls cert and/or key not configured %d",
617                lctx->parent_app_wrk_index);
618       return -1;
619     }
620
621   method = SSLv23_method ();
622   ssl_ctx = SSL_CTX_new (method);
623   if (!ssl_ctx)
624     {
625       clib_warning ("Unable to create SSL context");
626       return -1;
627     }
628
629   SSL_CTX_set_mode (ssl_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE);
630 #ifdef HAVE_OPENSSL_ASYNC
631   if (om->async)
632     SSL_CTX_set_mode (ssl_ctx, SSL_MODE_ASYNC);
633   SSL_CTX_set_async_callback (ssl_ctx, tls_async_openssl_callback);
634 #endif
635   SSL_CTX_set_options (ssl_ctx, flags);
636   SSL_CTX_set_ecdh_auto (ssl_ctx, 1);
637
638   rv = SSL_CTX_set_cipher_list (ssl_ctx, (const char *) om->ciphers);
639   if (rv != 1)
640     {
641       TLS_DBG (1, "Couldn't set cipher");
642       return -1;
643     }
644
645   /*
646    * Set the key and cert
647    */
648   cert_bio = BIO_new (BIO_s_mem ());
649   BIO_write (cert_bio, app->tls_cert, vec_len (app->tls_cert));
650   srvcert = PEM_read_bio_X509 (cert_bio, NULL, NULL, NULL);
651   if (!srvcert)
652     {
653       clib_warning ("unable to parse certificate");
654       return -1;
655     }
656   SSL_CTX_use_certificate (ssl_ctx, srvcert);
657   BIO_free (cert_bio);
658
659   cert_bio = BIO_new (BIO_s_mem ());
660   BIO_write (cert_bio, app->tls_key, vec_len (app->tls_key));
661   pkey = PEM_read_bio_PrivateKey (cert_bio, NULL, NULL, NULL);
662   if (!pkey)
663     {
664       clib_warning ("unable to parse pkey");
665       return -1;
666     }
667   SSL_CTX_use_PrivateKey (ssl_ctx, pkey);
668   BIO_free (cert_bio);
669
670   olc_index = openssl_listen_ctx_alloc ();
671   olc = openssl_lctx_get (olc_index);
672   olc->ssl_ctx = ssl_ctx;
673   olc->srvcert = srvcert;
674   olc->pkey = pkey;
675
676   /* store SSL_CTX into TLS level structure */
677   lctx->tls_ssl_ctx = olc_index;
678
679   return 0;
680
681 }
682
683 static int
684 openssl_stop_listen (tls_ctx_t * lctx)
685 {
686   u32 olc_index;
687   openssl_listen_ctx_t *olc;
688
689   olc_index = lctx->tls_ssl_ctx;
690   olc = openssl_lctx_get (olc_index);
691
692   X509_free (olc->srvcert);
693   EVP_PKEY_free (olc->pkey);
694
695   SSL_CTX_free (olc->ssl_ctx);
696   openssl_listen_ctx_free (olc);
697
698   return 0;
699 }
700
701 static int
702 openssl_ctx_init_server (tls_ctx_t * ctx)
703 {
704   openssl_ctx_t *oc = (openssl_ctx_t *) ctx;
705   u32 olc_index = ctx->tls_ssl_ctx;
706   openssl_listen_ctx_t *olc;
707   session_t *tls_session;
708   int rv, err;
709 #ifdef HAVE_OPENSSL_ASYNC
710   openssl_resume_handler *handler;
711 #endif
712
713   /* Start a new connection */
714
715   olc = openssl_lctx_get (olc_index);
716   oc->ssl = SSL_new (olc->ssl_ctx);
717   if (oc->ssl == NULL)
718     {
719       TLS_DBG (1, "Couldn't initialize ssl struct");
720       return -1;
721     }
722
723   oc->rbio = BIO_new (BIO_s_mem ());
724   oc->wbio = BIO_new (BIO_s_mem ());
725
726   BIO_set_mem_eof_return (oc->rbio, -1);
727   BIO_set_mem_eof_return (oc->wbio, -1);
728
729   SSL_set_bio (oc->ssl, oc->wbio, oc->rbio);
730   SSL_set_accept_state (oc->ssl);
731
732   TLS_DBG (1, "Initiating handshake for [%u]%u", ctx->c_thread_index,
733            oc->openssl_ctx_index);
734
735   tls_session = session_get_from_handle (ctx->tls_session_handle);
736   while (1)
737     {
738       rv = SSL_do_handshake (oc->ssl);
739       err = SSL_get_error (oc->ssl, rv);
740       openssl_try_handshake_write (oc, tls_session);
741 #ifdef HAVE_OPENSSL_ASYNC
742       if (err == SSL_ERROR_WANT_ASYNC)
743         {
744           handler = (openssl_resume_handler *) openssl_ctx_handshake_rx;
745           vpp_ssl_async_process_event (ctx, handler);
746           break;
747         }
748 #endif
749       if (err != SSL_ERROR_WANT_WRITE)
750         break;
751     }
752
753   TLS_DBG (2, "tls state for [%u]%u is su", ctx->c_thread_index,
754            oc->openssl_ctx_index, SSL_state_string_long (oc->ssl));
755   return 0;
756 }
757
758 static u8
759 openssl_handshake_is_over (tls_ctx_t * ctx)
760 {
761   openssl_ctx_t *mc = (openssl_ctx_t *) ctx;
762   if (!mc->ssl)
763     return 0;
764   return SSL_is_init_finished (mc->ssl);
765 }
766
767 static int
768 openssl_transport_close (tls_ctx_t * ctx)
769 {
770   if (!openssl_handshake_is_over (ctx))
771     {
772       openssl_handle_handshake_failure (ctx);
773       return 0;
774     }
775   session_transport_closing_notify (&ctx->connection);
776   return 0;
777 }
778
779 static int
780 openssl_app_close (tls_ctx_t * ctx)
781 {
782   openssl_ctx_t *oc = (openssl_ctx_t *) ctx;
783   session_t *app_session;
784
785   /* Wait for all data to be written to tcp */
786   app_session = session_get_from_handle (ctx->app_session_handle);
787   if (BIO_ctrl_pending (oc->rbio) <= 0
788       && !svm_fifo_max_dequeue_cons (app_session->tx_fifo))
789     openssl_confirm_app_close (ctx);
790   else
791     ctx->app_closed = 1;
792   return 0;
793 }
794
795 const static tls_engine_vft_t openssl_engine = {
796   .ctx_alloc = openssl_ctx_alloc,
797   .ctx_free = openssl_ctx_free,
798   .ctx_get = openssl_ctx_get,
799   .ctx_get_w_thread = openssl_ctx_get_w_thread,
800   .ctx_init_server = openssl_ctx_init_server,
801   .ctx_init_client = openssl_ctx_init_client,
802   .ctx_write = openssl_ctx_write,
803   .ctx_read = openssl_ctx_read,
804   .ctx_handshake_is_over = openssl_handshake_is_over,
805   .ctx_start_listen = openssl_start_listen,
806   .ctx_stop_listen = openssl_stop_listen,
807   .ctx_transport_close = openssl_transport_close,
808   .ctx_app_close = openssl_app_close,
809 };
810
811 int
812 tls_init_ca_chain (void)
813 {
814   openssl_main_t *om = &openssl_main;
815   tls_main_t *tm = vnet_tls_get_main ();
816   BIO *cert_bio;
817   X509 *testcert;
818   int rv;
819
820   if (access (tm->ca_cert_path, F_OK | R_OK) == -1)
821     {
822       clib_warning ("Could not initialize TLS CA certificates");
823       return -1;
824     }
825
826   if (!(om->cert_store = X509_STORE_new ()))
827     {
828       clib_warning ("failed to create cert store");
829       return -1;
830     }
831
832   rv = X509_STORE_load_locations (om->cert_store, tm->ca_cert_path, 0);
833   if (rv < 0)
834     {
835       clib_warning ("failed to load ca certificate");
836     }
837
838   if (tm->use_test_cert_in_ca)
839     {
840       cert_bio = BIO_new (BIO_s_mem ());
841       BIO_write (cert_bio, test_srv_crt_rsa, test_srv_crt_rsa_len);
842       testcert = PEM_read_bio_X509 (cert_bio, NULL, NULL, NULL);
843       if (!testcert)
844         {
845           clib_warning ("unable to parse certificate");
846           return -1;
847         }
848       X509_STORE_add_cert (om->cert_store, testcert);
849       rv = 0;
850     }
851   return (rv < 0 ? -1 : 0);
852 }
853
854 int
855 tls_openssl_set_ciphers (char *ciphers)
856 {
857   openssl_main_t *om = &openssl_main;
858   int i;
859
860   if (!ciphers)
861     {
862       return -1;
863     }
864
865   vec_validate (om->ciphers, strlen (ciphers) - 1);
866   for (i = 0; i < vec_len (om->ciphers); i++)
867     {
868       om->ciphers[i] = toupper (ciphers[i]);
869     }
870
871   return 0;
872
873 }
874
875 static clib_error_t *
876 tls_openssl_init (vlib_main_t * vm)
877 {
878   vlib_thread_main_t *vtm = vlib_get_thread_main ();
879   openssl_main_t *om = &openssl_main;
880   clib_error_t *error = 0;
881   u32 num_threads;
882
883   error = tls_openssl_api_init (vm);
884   num_threads = 1 /* main thread */  + vtm->n_threads;
885
886   SSL_library_init ();
887   SSL_load_error_strings ();
888
889   if (tls_init_ca_chain ())
890     {
891       clib_warning ("failed to initialize TLS CA chain");
892       return 0;
893     }
894
895   vec_validate (om->ctx_pool, num_threads - 1);
896
897   tls_register_engine (&openssl_engine, TLS_ENGINE_OPENSSL);
898
899   om->engine_init = 0;
900
901   /* default ciphers */
902   tls_openssl_set_ciphers
903     ("ALL:!ADH:!LOW:!EXP:!MD5:!RC4-SHA:!DES-CBC3-SHA:@STRENGTH");
904
905   return error;
906 }
907 /* *INDENT-OFF* */
908 VLIB_INIT_FUNCTION (tls_openssl_init) =
909 {
910   .runs_after = VLIB_INITS("tls_init"),
911 };
912 /* *INDENT-ON* */
913
914 #ifdef HAVE_OPENSSL_ASYNC
915 static clib_error_t *
916 tls_openssl_set_command_fn (vlib_main_t * vm, unformat_input_t * input,
917                             vlib_cli_command_t * cmd)
918 {
919   openssl_main_t *om = &openssl_main;
920   char *engine_name = NULL;
921   char *engine_alg = NULL;
922   char *ciphers = NULL;
923   u8 engine_name_set = 0;
924   int i;
925
926   /* By present, it is not allowed to configure engine again after running */
927   if (om->engine_init)
928     {
929       clib_warning ("engine has started!\n");
930       return clib_error_return
931         (0, "engine has started, and no config is accepted");
932     }
933
934   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
935     {
936       if (unformat (input, "engine %s", &engine_name))
937         {
938           engine_name_set = 1;
939         }
940       else if (unformat (input, "async"))
941         {
942           om->async = 1;
943           openssl_async_node_enable_disable (1);
944         }
945       else if (unformat (input, "alg %s", &engine_alg))
946         {
947           for (i = 0; i < strnlen (engine_alg, MAX_CRYPTO_LEN); i++)
948             engine_alg[i] = toupper (engine_alg[i]);
949         }
950       else if (unformat (input, "ciphers %s", &ciphers))
951         {
952           tls_openssl_set_ciphers (ciphers);
953         }
954       else
955         return clib_error_return (0, "failed: unknown input `%U'",
956                                   format_unformat_error, input);
957     }
958
959   /* reset parameters if engine is not configured */
960   if (!engine_name_set)
961     {
962       clib_warning ("No engine provided! \n");
963       om->async = 0;
964     }
965   else
966     {
967       if (openssl_engine_register (engine_name, engine_alg) < 0)
968         {
969           return clib_error_return (0, "failed to register %s polling",
970                                     engine_name);
971         }
972     }
973
974   return 0;
975 }
976
977 /* *INDENT-OFF* */
978 VLIB_CLI_COMMAND (tls_openssl_set_command, static) =
979 {
980   .path = "tls openssl set",
981   .short_help = "tls openssl set [engine <engine name>] [alg [algorithm] [async]",
982   .function = tls_openssl_set_command_fn,
983 };
984 /* *INDENT-ON* */
985 #endif
986
987 /* *INDENT-OFF* */
988 VLIB_PLUGIN_REGISTER () = {
989     .version = VPP_BUILD_VER,
990     .description = "Transport Layer Security (TLS) Engine, OpenSSL Based",
991 };
992 /* *INDENT-ON* */
993
994 /*
995  * fd.io coding-style-patch-verification: ON
996  *
997  * Local Variables:
998  * eval: (c-set-style "gnu")
999  * End:
1000  */