FD.io VPP  v20.09-64-g4f7b92f0a
Vector Packet Processing
tls_openssl.c
Go to the documentation of this file.
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 
33 static u32
35 {
36  u8 thread_index = vlib_get_thread_index ();
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
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 #ifdef HAVE_OPENSSL_ASYNC
63  openssl_evt_free (ctx->evt_index, ctx->c_thread_index);
64 #endif
65  vec_free (ctx->srv_hostname);
66  pool_put_index (openssl_main.ctx_pool[ctx->c_thread_index],
67  oc->openssl_ctx_index);
68 }
69 
70 tls_ctx_t *
71 openssl_ctx_get (u32 ctx_index)
72 {
74  ctx = pool_elt_at_index (openssl_main.ctx_pool[vlib_get_thread_index ()],
75  ctx_index);
76  return &(*ctx)->ctx;
77 }
78 
79 tls_ctx_t *
80 openssl_ctx_get_w_thread (u32 ctx_index, u8 thread_index)
81 {
83  ctx = pool_elt_at_index (openssl_main.ctx_pool[thread_index], ctx_index);
84  return &(*ctx)->ctx;
85 }
86 
87 static u32
89 {
92 
93  pool_get (om->lctx_pool, lctx);
94 
95  clib_memset (lctx, 0, sizeof (openssl_listen_ctx_t));
96  lctx->openssl_lctx_index = lctx - om->lctx_pool;
97  return lctx->openssl_lctx_index;
98 }
99 
100 static void
102 {
103  pool_put_index (openssl_main.lctx_pool, lctx->openssl_lctx_index);
104 }
105 
107 openssl_lctx_get (u32 lctx_index)
108 {
109  return pool_elt_at_index (openssl_main.lctx_pool, lctx_index);
110 }
111 
112 static int
114 {
116  int read, rv;
117  u32 enq_now;
118 
120 
121  enq_now = clib_min (svm_fifo_max_write_chunk (f), enq_max);
122  if (!enq_now)
123  return 0;
124 
125  read = BIO_read (bio, svm_fifo_tail (f), enq_now);
126  if (read <= 0)
127  return 0;
128 
129  c = svm_fifo_tail_chunk (f);
130  while ((c = c->next) && read < enq_max)
131  {
132  enq_now = clib_min (c->length, enq_max - read);
133  rv = BIO_read (bio, c->data, enq_now);
134  read += rv > 0 ? rv : 0;
135 
136  if (rv < enq_now)
137  break;
138  }
139 
140  svm_fifo_enqueue_nocopy (f, read);
141 
142  return read;
143 }
144 
145 static int
147 {
148  u32 enq_now, enq_max;
150  int read, rv;
151 
152  enq_max = svm_fifo_max_enqueue_prod (f);
153  if (!enq_max)
154  return 0;
155 
157 
158  enq_now = clib_min (svm_fifo_max_write_chunk (f), enq_max);
159  if (!enq_now)
160  return 0;
161 
162  read = SSL_read (ssl, svm_fifo_tail (f), enq_now);
163  if (read <= 0)
164  return 0;
165 
166  c = svm_fifo_tail_chunk (f);
167  while ((c = c->next) && read < enq_max)
168  {
169  enq_now = clib_min (c->length, enq_max - read);
170  rv = SSL_read (ssl, c->data, enq_now);
171  read += rv > 0 ? rv : 0;
172 
173  if (rv < enq_now)
174  break;
175  }
176 
177  svm_fifo_enqueue_nocopy (f, read);
178 
179  return read;
180 }
181 
182 static int
184 {
186  int wrote, rv;
187  u32 deq_now;
188 
189  deq_now = clib_min (svm_fifo_max_read_chunk (f), len);
190  wrote = BIO_write (bio, svm_fifo_head (f), deq_now);
191  if (wrote <= 0)
192  return 0;
193 
194  c = svm_fifo_head_chunk (f);
195  while ((c = c->next) && wrote < len)
196  {
197  deq_now = clib_min (c->length, len - wrote);
198  rv = BIO_write (bio, c->data, deq_now);
199  wrote += rv > 0 ? rv : 0;
200 
201  if (rv < deq_now)
202  break;
203  }
204 
205  svm_fifo_dequeue_drop (f, wrote);
206 
207  return wrote;
208 }
209 
210 static int
212 {
214  int wrote = 0, rv;
215  u32 deq_now;
216 
217  deq_now = clib_min (svm_fifo_max_read_chunk (f), len);
218  wrote = SSL_write (ssl, svm_fifo_head (f), deq_now);
219  if (wrote <= 0)
220  return 0;
221 
222  c = svm_fifo_head_chunk (f);
223  while ((c = c->next) && wrote < len)
224  {
225  deq_now = clib_min (c->length, len - wrote);
226  rv = SSL_write (ssl, c->data, deq_now);
227  wrote += rv > 0 ? rv : 0;
228 
229  if (rv < deq_now)
230  break;
231  }
232 
233  svm_fifo_dequeue_drop (f, wrote);
234 
235  return wrote;
236 }
237 
238 static int
240 {
241  svm_fifo_t *f;
242  u32 deq_max;
243 
244  f = tls_session->rx_fifo;
245  deq_max = svm_fifo_max_dequeue_cons (f);
246  if (!deq_max)
247  return 0;
248 
249  return openssl_write_from_fifo_into_bio (f, oc->wbio, deq_max);
250 }
251 
252 static int
254 {
255  u32 read, enq_max;
256 
257  if (BIO_ctrl_pending (oc->rbio) <= 0)
258  return 0;
259 
260  enq_max = svm_fifo_max_enqueue_prod (tls_session->tx_fifo);
261  if (!enq_max)
262  return 0;
263 
264  read = openssl_read_from_bio_into_fifo (tls_session->tx_fifo, oc->rbio,
265  enq_max);
266  if (read)
267  tls_add_vpp_q_tx_evt (tls_session);
268 
269  return read;
270 }
271 
272 #ifdef HAVE_OPENSSL_ASYNC
273 static int
274 openssl_check_async_status (tls_ctx_t * ctx, openssl_resume_handler * handler,
275  session_t * session)
276 {
277  openssl_ctx_t *oc = (openssl_ctx_t *) ctx;
278  int estatus;
279 
280  SSL_get_async_status (oc->ssl, &estatus);
281  if (estatus == ASYNC_STATUS_EAGAIN)
282  {
284  }
285  else
286  {
288  }
289 
290  return 1;
291 
292 }
293 
294 #endif
295 
296 static void
298 {
299  session_t *app_session;
300 
301  if (SSL_is_server (((openssl_ctx_t *) ctx)->ssl))
302  {
303  /*
304  * Cleanup pre-allocated app session and close transport
305  */
306  app_session =
307  session_get_if_valid (ctx->c_s_index, ctx->c_thread_index);
308  if (app_session)
309  {
310  session_free (app_session);
311  ctx->no_app_session = 1;
312  ctx->c_s_index = SESSION_INVALID_INDEX;
314  }
315  }
316  else
317  {
318  /*
319  * Also handles cleanup of the pre-allocated session
320  */
321  tls_notify_app_connected (ctx, SESSION_E_TLS_HANDSHAKE);
322  }
323 }
324 
325 int
327 {
328  openssl_ctx_t *oc = (openssl_ctx_t *) ctx;
329  int rv = 0, err;
330 
331  while (SSL_in_init (oc->ssl))
332  {
333  if (ctx->resume)
334  {
335  ctx->resume = 0;
336  }
337  else if (!openssl_try_handshake_read (oc, tls_session))
338  break;
339 
340  rv = SSL_do_handshake (oc->ssl);
341  err = SSL_get_error (oc->ssl, rv);
342 
343 #ifdef HAVE_OPENSSL_ASYNC
344  if (err == SSL_ERROR_WANT_ASYNC)
345  {
346  openssl_check_async_status (ctx, openssl_ctx_handshake_rx,
347  tls_session);
348  }
349 #endif
350  if (err == SSL_ERROR_SSL)
351  {
352  char buf[512];
353  ERR_error_string (ERR_get_error (), buf);
354  clib_warning ("Err: %s", buf);
355 
357  return -1;
358  }
359 
360  openssl_try_handshake_write (oc, tls_session);
361 
362  if (err != SSL_ERROR_WANT_WRITE)
363  break;
364  }
365  TLS_DBG (2, "tls state for %u is %s", oc->openssl_ctx_index,
366  SSL_state_string_long (oc->ssl));
367 
368  if (SSL_in_init (oc->ssl))
369  return -1;
370 
371  /*
372  * Handshake complete
373  */
374  if (!SSL_is_server (oc->ssl))
375  {
376  /*
377  * Verify server certificate
378  */
379  if ((rv = SSL_get_verify_result (oc->ssl)) != X509_V_OK)
380  {
381  TLS_DBG (1, " failed verify: %s\n",
382  X509_verify_cert_error_string (rv));
383 
384  /*
385  * Presence of hostname enforces strict certificate verification
386  */
387  if (ctx->srv_hostname)
388  {
389  tls_notify_app_connected (ctx, SESSION_E_TLS_HANDSHAKE);
390  return -1;
391  }
392  }
393  tls_notify_app_connected (ctx, SESSION_E_NONE);
394  }
395  else
396  {
397  /* Need to check transport status */
398  if (ctx->is_passive_close)
400  else
401  tls_notify_app_accept (ctx);
402  }
403 
404  TLS_DBG (1, "Handshake for %u complete. TLS cipher is %s",
405  oc->openssl_ctx_index, SSL_get_cipher (oc->ssl));
406  return rv;
407 }
408 
409 static void
411 {
414 }
415 
416 static inline int
417 openssl_ctx_write (tls_ctx_t * ctx, session_t * app_session,
419 {
420  openssl_ctx_t *oc = (openssl_ctx_t *) ctx;
421  int wrote = 0, read, max_buf = 4 * TLS_CHUNK_SIZE, max_space, n_pending;
422  u32 deq_max, to_write, enq_max;
423  session_t *tls_session;
424  svm_fifo_t *f;
425 
426  f = app_session->tx_fifo;
427 
428  deq_max = svm_fifo_max_dequeue_cons (f);
429  if (!deq_max)
430  goto check_tls_fifo;
431 
432  deq_max = clib_min (deq_max, sp->max_burst_size);
433 
434  /* Figure out how much data to write */
435  max_space = max_buf - BIO_ctrl_pending (oc->rbio);
436  max_space = (max_space < 0) ? 0 : max_space;
437  to_write = clib_min (deq_max, (u32) max_space);
438 
439  wrote = openssl_write_from_fifo_into_ssl (f, oc->ssl, to_write);
440  if (!wrote)
441  goto check_tls_fifo;
442 
443  if (svm_fifo_needs_deq_ntf (f, wrote))
444  session_dequeue_notify (app_session);
445 
446 check_tls_fifo:
447 
448  if ((n_pending = BIO_ctrl_pending (oc->rbio)) <= 0)
449  return wrote;
450 
451  tls_session = session_get_from_handle (ctx->tls_session_handle);
452 
453  enq_max = svm_fifo_max_enqueue_prod (tls_session->tx_fifo);
454  if (!enq_max)
455  goto maybe_reschedule;
456 
457  read = openssl_read_from_bio_into_fifo (tls_session->tx_fifo, oc->rbio,
458  enq_max);
459  if (!read)
460  goto maybe_reschedule;
461 
462  tls_add_vpp_q_tx_evt (tls_session);
463 
464  if (PREDICT_FALSE (ctx->app_closed && !BIO_ctrl_pending (oc->rbio)))
466 
467 maybe_reschedule:
468 
469  if (!svm_fifo_max_enqueue_prod (tls_session->tx_fifo))
470  {
471  svm_fifo_add_want_deq_ntf (tls_session->tx_fifo,
475  }
476  else
477  /* Request tx reschedule of the app session */
478  app_session->flags |= SESSION_F_CUSTOM_TX;
479 
480  return wrote;
481 }
482 
483 static inline int
484 openssl_ctx_read (tls_ctx_t * ctx, session_t * tls_session)
485 {
486  int read, wrote = 0, max_space, max_buf = 4 * TLS_CHUNK_SIZE;
487  openssl_ctx_t *oc = (openssl_ctx_t *) ctx;
488  u32 deq_max, to_write;
489  session_t *app_session;
490  svm_fifo_t *f;
491 
492  if (PREDICT_FALSE (SSL_in_init (oc->ssl)))
493  {
494  if (openssl_ctx_handshake_rx (ctx, tls_session) < 0)
495  return 0;
496  else
497  goto check_app_fifo;
498  }
499 
500  f = tls_session->rx_fifo;
501 
502  deq_max = svm_fifo_max_dequeue_cons (f);
503  max_space = max_buf - BIO_ctrl_pending (oc->wbio);
504  max_space = max_space < 0 ? 0 : max_space;
505  to_write = clib_min (deq_max, max_space);
506  if (!to_write)
507  goto check_app_fifo;
508 
509  wrote = openssl_write_from_fifo_into_bio (f, oc->wbio, to_write);
510  if (!wrote)
511  {
512  tls_add_vpp_q_builtin_rx_evt (tls_session);
513  goto check_app_fifo;
514  }
515 
517  tls_add_vpp_q_builtin_rx_evt (tls_session);
518 
519 check_app_fifo:
520 
521  if (BIO_ctrl_pending (oc->wbio) <= 0)
522  return wrote;
523 
524  app_session = session_get_from_handle (ctx->app_session_handle);
525  f = app_session->rx_fifo;
526 
527  read = openssl_read_from_ssl_into_fifo (f, oc->ssl);
528  if (!read)
529  {
530  tls_add_vpp_q_builtin_rx_evt (tls_session);
531  return wrote;
532  }
533 
534  /* If handshake just completed, session may still be in accepting state */
535  if (app_session->session_state >= SESSION_STATE_READY)
536  tls_notify_app_enqueue (ctx, app_session);
537  if (SSL_pending (oc->ssl) > 0)
538  tls_add_vpp_q_builtin_rx_evt (tls_session);
539 
540  return wrote;
541 }
542 
543 static int
545 {
546  long flags = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION;
547  openssl_ctx_t *oc = (openssl_ctx_t *) ctx;
549  session_t *tls_session;
550  const SSL_METHOD *method;
551  int rv, err;
552 
553  method = SSLv23_client_method ();
554  if (method == NULL)
555  {
556  TLS_DBG (1, "SSLv23_method returned null");
557  return -1;
558  }
559 
560  oc->ssl_ctx = SSL_CTX_new (method);
561  if (oc->ssl_ctx == NULL)
562  {
563  TLS_DBG (1, "SSL_CTX_new returned null");
564  return -1;
565  }
566 
567  SSL_CTX_set_ecdh_auto (oc->ssl_ctx, 1);
568  SSL_CTX_set_mode (oc->ssl_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE);
569 #ifdef HAVE_OPENSSL_ASYNC
570  if (om->async)
571  SSL_CTX_set_mode (oc->ssl_ctx, SSL_MODE_ASYNC);
572 #endif
573  rv = SSL_CTX_set_cipher_list (oc->ssl_ctx, (const char *) om->ciphers);
574  if (rv != 1)
575  {
576  TLS_DBG (1, "Couldn't set cipher");
577  return -1;
578  }
579 
580  SSL_CTX_set_options (oc->ssl_ctx, flags);
581  SSL_CTX_set_cert_store (oc->ssl_ctx, om->cert_store);
582 
583  oc->ssl = SSL_new (oc->ssl_ctx);
584  if (oc->ssl == NULL)
585  {
586  TLS_DBG (1, "Couldn't initialize ssl struct");
587  return -1;
588  }
589 
590  oc->rbio = BIO_new (BIO_s_mem ());
591  oc->wbio = BIO_new (BIO_s_mem ());
592 
593  BIO_set_mem_eof_return (oc->rbio, -1);
594  BIO_set_mem_eof_return (oc->wbio, -1);
595 
596  SSL_set_bio (oc->ssl, oc->wbio, oc->rbio);
597  SSL_set_connect_state (oc->ssl);
598 
599  rv = SSL_set_tlsext_host_name (oc->ssl, ctx->srv_hostname);
600  if (rv != 1)
601  {
602  TLS_DBG (1, "Couldn't set hostname");
603  return -1;
604  }
605 
606  /*
607  * 2. Do the first steps in the handshake.
608  */
609  TLS_DBG (1, "Initiating handshake for [%u]%u", ctx->c_thread_index,
610  oc->openssl_ctx_index);
611 
612  tls_session = session_get_from_handle (ctx->tls_session_handle);
613 
614 #ifdef HAVE_OPENSSL_ASYNC
616 #endif
617  while (1)
618  {
619  rv = SSL_do_handshake (oc->ssl);
620  err = SSL_get_error (oc->ssl, rv);
621  openssl_try_handshake_write (oc, tls_session);
622 #ifdef HAVE_OPENSSL_ASYNC
623  if (err == SSL_ERROR_WANT_ASYNC)
624  {
625  openssl_check_async_status (ctx, openssl_ctx_handshake_rx,
626  tls_session);
627  break;
628  }
629 #endif
630  if (err != SSL_ERROR_WANT_WRITE)
631  break;
632  }
633 
634  TLS_DBG (2, "tls state for [%u]%u is su", ctx->c_thread_index,
635  oc->openssl_ctx_index, SSL_state_string_long (oc->ssl));
636  return 0;
637 }
638 
639 static int
641 {
642  const SSL_METHOD *method;
643  SSL_CTX *ssl_ctx;
644  int rv;
645  BIO *cert_bio;
646  X509 *srvcert;
647  EVP_PKEY *pkey;
648  u32 olc_index;
650  app_cert_key_pair_t *ckpair;
651 
652  long flags = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION;
654 
656  if (!ckpair)
657  return -1;
658 
659  if (!ckpair->cert || !ckpair->key)
660  {
661  TLS_DBG (1, "tls cert and/or key not configured %d",
662  lctx->parent_app_wrk_index);
663  return -1;
664  }
665 
666  method = SSLv23_method ();
667  ssl_ctx = SSL_CTX_new (method);
668  if (!ssl_ctx)
669  {
670  clib_warning ("Unable to create SSL context");
671  return -1;
672  }
673 
674  SSL_CTX_set_mode (ssl_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE);
675 #ifdef HAVE_OPENSSL_ASYNC
676  if (om->async)
677  {
678  SSL_CTX_set_mode (ssl_ctx, SSL_MODE_ASYNC);
679  SSL_CTX_set_async_callback (ssl_ctx, tls_async_openssl_callback);
680  }
681 #endif
682  SSL_CTX_set_options (ssl_ctx, flags);
683  SSL_CTX_set_ecdh_auto (ssl_ctx, 1);
684 
685  rv = SSL_CTX_set_cipher_list (ssl_ctx, (const char *) om->ciphers);
686  if (rv != 1)
687  {
688  TLS_DBG (1, "Couldn't set cipher");
689  return -1;
690  }
691 
692  /*
693  * Set the key and cert
694  */
695  cert_bio = BIO_new (BIO_s_mem ());
696  BIO_write (cert_bio, ckpair->cert, vec_len (ckpair->cert));
697  srvcert = PEM_read_bio_X509 (cert_bio, NULL, NULL, NULL);
698  if (!srvcert)
699  {
700  clib_warning ("unable to parse certificate");
701  return -1;
702  }
703  SSL_CTX_use_certificate (ssl_ctx, srvcert);
704  BIO_free (cert_bio);
705 
706  cert_bio = BIO_new (BIO_s_mem ());
707  BIO_write (cert_bio, ckpair->key, vec_len (ckpair->key));
708  pkey = PEM_read_bio_PrivateKey (cert_bio, NULL, NULL, NULL);
709  if (!pkey)
710  {
711  clib_warning ("unable to parse pkey");
712  return -1;
713  }
714  SSL_CTX_use_PrivateKey (ssl_ctx, pkey);
715  BIO_free (cert_bio);
716 
717  olc_index = openssl_listen_ctx_alloc ();
718  olc = openssl_lctx_get (olc_index);
719  olc->ssl_ctx = ssl_ctx;
720  olc->srvcert = srvcert;
721  olc->pkey = pkey;
722 
723  /* store SSL_CTX into TLS level structure */
724  lctx->tls_ssl_ctx = olc_index;
725 
726  return 0;
727 
728 }
729 
730 static int
732 {
733  u32 olc_index;
735 
736  olc_index = lctx->tls_ssl_ctx;
737  olc = openssl_lctx_get (olc_index);
738 
739  X509_free (olc->srvcert);
740  EVP_PKEY_free (olc->pkey);
741 
742  SSL_CTX_free (olc->ssl_ctx);
744 
745  return 0;
746 }
747 
748 static int
750 {
751  openssl_ctx_t *oc = (openssl_ctx_t *) ctx;
752  u32 olc_index = ctx->tls_ssl_ctx;
754  session_t *tls_session;
755  int rv, err;
756 
757  /* Start a new connection */
758 
759  olc = openssl_lctx_get (olc_index);
760  oc->ssl = SSL_new (olc->ssl_ctx);
761  if (oc->ssl == NULL)
762  {
763  TLS_DBG (1, "Couldn't initialize ssl struct");
764  return -1;
765  }
766 
767  oc->rbio = BIO_new (BIO_s_mem ());
768  oc->wbio = BIO_new (BIO_s_mem ());
769 
770  BIO_set_mem_eof_return (oc->rbio, -1);
771  BIO_set_mem_eof_return (oc->wbio, -1);
772 
773  SSL_set_bio (oc->ssl, oc->wbio, oc->rbio);
774  SSL_set_accept_state (oc->ssl);
775 
776  TLS_DBG (1, "Initiating handshake for [%u]%u", ctx->c_thread_index,
777  oc->openssl_ctx_index);
778 
779  tls_session = session_get_from_handle (ctx->tls_session_handle);
780 #ifdef HAVE_OPENSSL_ASYNC
782 #endif
783  while (1)
784  {
785  rv = SSL_do_handshake (oc->ssl);
786  err = SSL_get_error (oc->ssl, rv);
787  openssl_try_handshake_write (oc, tls_session);
788 #ifdef HAVE_OPENSSL_ASYNC
789  if (err == SSL_ERROR_WANT_ASYNC)
790  {
791  openssl_check_async_status (ctx, openssl_ctx_handshake_rx,
792  tls_session);
793  break;
794  }
795 #endif
796  if (err != SSL_ERROR_WANT_WRITE)
797  break;
798  }
799 
800  TLS_DBG (2, "tls state for [%u]%u is su", ctx->c_thread_index,
801  oc->openssl_ctx_index, SSL_state_string_long (oc->ssl));
802  return 0;
803 }
804 
805 static u8
807 {
808  openssl_ctx_t *mc = (openssl_ctx_t *) ctx;
809  if (!mc->ssl)
810  return 0;
811  return SSL_is_init_finished (mc->ssl);
812 }
813 
814 static int
816 {
817 #ifdef HAVE_OPENSSL_ASYNC
818  if (vpp_openssl_is_inflight (ctx))
819  return 0;
820 #endif
821 
822  if (!openssl_handshake_is_over (ctx))
823  {
825  return 0;
826  }
828  return 0;
829 }
830 
831 static int
833 {
834  openssl_ctx_t *oc = (openssl_ctx_t *) ctx;
835  session_t *app_session;
836 
837  /* Wait for all data to be written to tcp */
838  app_session = session_get_from_handle (ctx->app_session_handle);
839  if (BIO_ctrl_pending (oc->rbio) <= 0
840  && !svm_fifo_max_dequeue_cons (app_session->tx_fifo))
842  else
843  ctx->app_closed = 1;
844  return 0;
845 }
846 
847 const static tls_engine_vft_t openssl_engine = {
849  .ctx_free = openssl_ctx_free,
850  .ctx_get = openssl_ctx_get,
851  .ctx_get_w_thread = openssl_ctx_get_w_thread,
852  .ctx_init_server = openssl_ctx_init_server,
853  .ctx_init_client = openssl_ctx_init_client,
854  .ctx_write = openssl_ctx_write,
855  .ctx_read = openssl_ctx_read,
856  .ctx_handshake_is_over = openssl_handshake_is_over,
857  .ctx_start_listen = openssl_start_listen,
858  .ctx_stop_listen = openssl_stop_listen,
859  .ctx_transport_close = openssl_transport_close,
860  .ctx_app_close = openssl_app_close,
861 };
862 
863 int
865 {
867  tls_main_t *tm = vnet_tls_get_main ();
868  BIO *cert_bio;
869  X509 *testcert;
870  int rv;
871 
872  if (access (tm->ca_cert_path, F_OK | R_OK) == -1)
873  {
874  clib_warning ("Could not initialize TLS CA certificates");
875  return -1;
876  }
877 
878  if (!(om->cert_store = X509_STORE_new ()))
879  {
880  clib_warning ("failed to create cert store");
881  return -1;
882  }
883 
884 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
885  rv = X509_STORE_load_file (om->cert_store, tm->ca_cert_path);
886 #else
887  rv = X509_STORE_load_locations (om->cert_store, tm->ca_cert_path, 0);
888 #endif
889 
890  if (rv < 0)
891  {
892  clib_warning ("failed to load ca certificate");
893  }
894 
895  if (tm->use_test_cert_in_ca)
896  {
897  cert_bio = BIO_new (BIO_s_mem ());
898  BIO_write (cert_bio, test_srv_crt_rsa, test_srv_crt_rsa_len);
899  testcert = PEM_read_bio_X509 (cert_bio, NULL, NULL, NULL);
900  if (!testcert)
901  {
902  clib_warning ("unable to parse certificate");
903  return -1;
904  }
905  X509_STORE_add_cert (om->cert_store, testcert);
906  rv = 0;
907  }
908  return (rv < 0 ? -1 : 0);
909 }
910 
911 int
912 tls_openssl_set_ciphers (char *ciphers)
913 {
915  int i;
916 
917  if (!ciphers)
918  {
919  return -1;
920  }
921 
922  vec_validate (om->ciphers, strlen (ciphers) - 1);
923  for (i = 0; i < vec_len (om->ciphers); i++)
924  {
925  om->ciphers[i] = toupper (ciphers[i]);
926  }
927 
928  return 0;
929 
930 }
931 
932 static clib_error_t *
934 {
937  clib_error_t *error = 0;
938  u32 num_threads;
939 
940  error = tls_openssl_api_init (vm);
941  num_threads = 1 /* main thread */ + vtm->n_threads;
942 
943  SSL_library_init ();
944  SSL_load_error_strings ();
945 
946  if (tls_init_ca_chain ())
947  {
948  clib_warning ("failed to initialize TLS CA chain");
949  return 0;
950  }
951 
952  vec_validate (om->ctx_pool, num_threads - 1);
953 
954  tls_register_engine (&openssl_engine, CRYPTO_ENGINE_OPENSSL);
955 
956  om->engine_init = 0;
957 
958  /* default ciphers */
960  ("ALL:!ADH:!LOW:!EXP:!MD5:!RC4-SHA:!DES-CBC3-SHA:@STRENGTH");
961 
962  return error;
963 }
964 /* *INDENT-OFF* */
966 {
967  .runs_after = VLIB_INITS("tls_init"),
968 };
969 /* *INDENT-ON* */
970 
971 #ifdef HAVE_OPENSSL_ASYNC
972 static clib_error_t *
973 tls_openssl_set_command_fn (vlib_main_t * vm, unformat_input_t * input,
974  vlib_cli_command_t * cmd)
975 {
977  char *engine_name = NULL;
978  char *engine_alg = NULL;
979  char *ciphers = NULL;
980  u8 engine_name_set = 0;
981  int i, async = 0;
982 
983  /* By present, it is not allowed to configure engine again after running */
984  if (om->engine_init)
985  {
986  clib_warning ("engine has started!\n");
987  return clib_error_return
988  (0, "engine has started, and no config is accepted");
989  }
990 
992  {
993  if (unformat (input, "engine %s", &engine_name))
994  {
995  engine_name_set = 1;
996  }
997  else if (unformat (input, "async"))
998  {
999  async = 1;
1000  }
1001  else if (unformat (input, "alg %s", &engine_alg))
1002  {
1003  for (i = 0; i < strnlen (engine_alg, MAX_CRYPTO_LEN); i++)
1004  engine_alg[i] = toupper (engine_alg[i]);
1005  }
1006  else if (unformat (input, "ciphers %s", &ciphers))
1007  {
1008  tls_openssl_set_ciphers (ciphers);
1009  }
1010  else
1011  return clib_error_return (0, "failed: unknown input `%U'",
1012  format_unformat_error, input);
1013  }
1014 
1015  /* reset parameters if engine is not configured */
1016  if (!engine_name_set)
1017  {
1018  clib_warning ("No engine provided! \n");
1019  async = 0;
1020  }
1021  else
1022  {
1024  if (openssl_engine_register (engine_name, engine_alg, async) < 0)
1025  {
1026  return clib_error_return (0, "Failed to register %s polling",
1027  engine_name);
1028  }
1029  else
1030  {
1031  vlib_cli_output (vm, "Successfully register engine %s\n",
1032  engine_name);
1033  }
1034  }
1035  om->async = async;
1036 
1037  return 0;
1038 }
1039 
1040 /* *INDENT-OFF* */
1041 VLIB_CLI_COMMAND (tls_openssl_set_command, static) =
1042 {
1043  .path = "tls openssl set",
1044  .short_help = "tls openssl set [engine <engine name>] [alg [algorithm] [async]",
1045  .function = tls_openssl_set_command_fn,
1046 };
1047 /* *INDENT-ON* */
1048 #endif
1049 
1050 /* *INDENT-OFF* */
1051 VLIB_PLUGIN_REGISTER () = {
1052  .version = VPP_BUILD_VER,
1053  .description = "Transport Layer Security (TLS) Engine, OpenSSL Based",
1054 };
1055 /* *INDENT-ON* */
1056 
1057 /*
1058  * fd.io coding-style-patch-verification: ON
1059  *
1060  * Local Variables:
1061  * eval: (c-set-style "gnu")
1062  * End:
1063  */
u32 length
length of chunk in bytes
Definition: fifo_types.h:32
tls_main_t * vnet_tls_get_main(void)
Definition: tls.c:996
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:509
openssl_listen_ctx_t * lctx_pool
Definition: tls_openssl.h:46
int tls_notify_app_connected(tls_ctx_t *ctx, session_error_t err)
Definition: tls.c:211
static int openssl_transport_close(tls_ctx_t *ctx)
Definition: tls_openssl.c:815
#define clib_min(x, y)
Definition: clib.h:327
static u8 openssl_handshake_is_over(tls_ctx_t *ctx)
Definition: tls_openssl.c:806
X509_STORE * cert_store
Definition: tls_openssl.h:51
static u32 svm_fifo_max_enqueue_prod(svm_fifo_t *f)
Maximum number of bytes that can be enqueued into fifo.
Definition: svm_fifo.h:524
vl_api_wireguard_peer_flags_t flags
Definition: wireguard.api:103
void tls_disconnect_transport(tls_ctx_t *ctx)
Definition: tls.c:30
svm_fifo_t * tx_fifo
Notify on dequeue.
Definition: svm_fifo.h:35
static void openssl_handle_handshake_failure(tls_ctx_t *ctx)
Definition: tls_openssl.c:297
char * ca_cert_path
Definition: tls.h:99
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
svm_fifo_t * rx_fifo
Pointers to rx/tx buffers.
int tls_add_vpp_q_builtin_rx_evt(session_t *s)
Definition: tls.c:62
static session_t * session_get_if_valid(u64 si, u32 thread_index)
Definition: session.h:308
static u32 openssl_ctx_alloc(void)
Definition: tls_openssl.c:34
int tls_openssl_set_ciphers(char *ciphers)
Definition: tls_openssl.c:912
static void openssl_listen_ctx_free(openssl_listen_ctx_t *lctx)
Definition: tls_openssl.c:101
void svm_fifo_enqueue_nocopy(svm_fifo_t *f, u32 len)
Advance tail.
Definition: svm_fifo.c:933
static void openssl_ctx_free(tls_ctx_t *ctx)
Definition: tls_openssl.c:53
u8 use_test_cert_in_ca
Definition: tls.h:98
u32 flags
Session flags.
clib_error_t * tls_openssl_api_init(vlib_main_t *vm)
static int openssl_write_from_fifo_into_ssl(svm_fifo_t *f, SSL *ssl, u32 len)
Definition: tls_openssl.c:211
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:252
void tls_register_engine(const tls_engine_vft_t *vft, crypto_engine_type_t type)
Definition: tls.c:903
static u8 * svm_fifo_tail(svm_fifo_t *f)
Fifo tail pointer getter.
Definition: svm_fifo.h:605
unsigned char u8
Definition: types.h:56
void session_transport_closing_notify(transport_connection_t *tc)
Notification from transport that connection is being closed.
Definition: session.c:948
SSL_CTX * ssl_ctx
Definition: tls_openssl.h:28
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:173
static svm_fifo_chunk_t * svm_fifo_head_chunk(svm_fifo_t *f)
Fifo head chunk getter.
Definition: svm_fifo.h:566
static u32 svm_fifo_max_dequeue_cons(svm_fifo_t *f)
Fifo max bytes to dequeue optimized for consumer.
Definition: svm_fifo.h:404
u8 is_passive_close
Definition: tls.h:77
#define MAX_CRYPTO_LEN
Definition: tls_openssl.c:30
#define clib_error_return(e, args...)
Definition: error.h:99
static int openssl_stop_listen(tls_ctx_t *lctx)
Definition: tls_openssl.c:731
unsigned int u32
Definition: types.h:88
int openssl_engine_register(char *engine_name, char *algorithm, int async)
Definition: tls_async.c:116
#define SESSION_INVALID_HANDLE
Definition: session_types.h:23
static u8 * svm_fifo_head(svm_fifo_t *f)
Fifo head pointer getter.
Definition: svm_fifo.h:578
int tls_init_ca_chain(void)
Definition: tls_openssl.c:864
int session_dequeue_notify(session_t *s)
Definition: session.c:685
#define TLS_CHUNK_SIZE
Definition: tls.h:28
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:534
int vpp_tls_async_update_event(tls_ctx_t *ctx, int eagain)
Definition: tls_async.c:319
static session_t * session_get_from_handle(session_handle_t handle)
Definition: session.h:321
long ctx[MAX_CONNS]
Definition: main.c:144
struct svm_fifo_chunk_ * next
pointer to next chunk in linked-lists
Definition: fifo_types.h:33
struct _unformat_input_t unformat_input_t
Definition: tls.h:86
static int openssl_write_from_fifo_into_bio(svm_fifo_t *f, BIO *bio, u32 len)
Definition: tls_openssl.c:183
int vpp_openssl_is_inflight(tls_ctx_t *ctx)
Definition: tls_async.c:306
#define PREDICT_FALSE(x)
Definition: clib.h:120
tls_ctx_t * openssl_ctx_get(u32 ctx_index)
Definition: tls_openssl.c:71
#define SESSION_INVALID_INDEX
Definition: session_types.h:22
static const char test_srv_crt_rsa[]
Definition: tls_test.h:23
Definition: tls.h:58
clib_error_t * vnet_session_enable_disable(vlib_main_t *vm, u8 is_en)
Definition: session.c:1768
u32(* ctx_alloc)(void)
Definition: tls.h:106
u32 ckpair_index
Definition: tls.h:83
u8 len
Definition: ip_types.api:92
static int openssl_ctx_init_client(tls_ctx_t *ctx)
Definition: tls_openssl.c:544
app_cert_key_pair_t * app_cert_key_pair_get_if_valid(u32 index)
Definition: application.c:1686
static u8 svm_fifo_needs_deq_ntf(svm_fifo_t *f, u32 n_last_deq)
Check if fifo needs dequeue notification.
Definition: svm_fifo.h:792
#define UNFORMAT_END_OF_INPUT
Definition: format.h:145
static int openssl_read_from_ssl_into_fifo(svm_fifo_t *f, SSL *ssl)
Definition: tls_openssl.c:146
svmdb_client_t * c
static_always_inline uword vlib_get_thread_index(void)
Definition: threads.h:219
static int openssl_app_close(tls_ctx_t *ctx)
Definition: tls_openssl.c:832
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:317
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:380
u32 evt_index
Definition: tls.h:82
void session_free(session_t *s)
Definition: session.c:210
openssl_ctx_t *** ctx_pool
Definition: tls_openssl.h:45
#define clib_warning(format, args...)
Definition: error.h:59
static int openssl_try_handshake_write(openssl_ctx_t *oc, session_t *tls_session)
Definition: tls_openssl.c:253
static int openssl_ctx_read(tls_ctx_t *ctx, session_t *tls_session)
Definition: tls_openssl.c:484
openssl_main_t openssl_main
Definition: tls_openssl.c:32
int tls_add_vpp_q_tx_evt(session_t *s)
Definition: tls.c:70
transport_connection_t connection
Definition: tls.h:62
static int openssl_ctx_write(tls_ctx_t *ctx, session_t *app_session, transport_send_params_t *sp)
Definition: tls_openssl.c:417
transport_snd_flags_t flags
Definition: transport.h:61
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:158
#define pool_put_index(p, i)
Free pool element with given index.
Definition: pool.h:331
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:696
static void openssl_confirm_app_close(tls_ctx_t *ctx)
Definition: tls_openssl.c:410
int openssl_resume_handler(tls_ctx_t *ctx, session_t *tls_session)
Definition: tls_openssl.h:57
static clib_error_t * tls_openssl_init(vlib_main_t *vm)
Definition: tls_openssl.c:933
u8 data[0]
start of chunk data
Definition: fifo_types.h:36
static void svm_fifo_add_want_deq_ntf(svm_fifo_t *f, u8 ntf_type)
Set specific want notification flag.
Definition: svm_fifo.h:728
static void * clib_mem_alloc(uword size)
Definition: mem.h:157
int vpp_tls_async_init_event(tls_ctx_t *ctx, openssl_resume_handler *handler, session_t *session)
Definition: tls_async.c:280
tls_ctx_t * openssl_ctx_get_w_thread(u32 ctx_index, u8 thread_index)
Definition: tls_openssl.c:80
u32 svm_fifo_max_read_chunk(svm_fifo_t *f)
Max contiguous chunk of data that can be read.
Definition: svm_fifo.c:509
static int openssl_ctx_init_server(tls_ctx_t *ctx)
Definition: tls_openssl.c:749
int svm_fifo_fill_chunk_list(svm_fifo_t *f)
Ensure the whole fifo size is writeable.
Definition: svm_fifo.c:1126
int openssl_evt_free(int event_index, u8 thread_index)
Definition: tls_async.c:212
u8 app_closed
Definition: tls.h:79
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
volatile u8 session_state
State in session layer state machine.
int tls_async_openssl_callback(SSL *s, void *cb_arg)
Definition: tls_async.c:243
void session_transport_closed_notify(transport_connection_t *tc)
Notification from transport that it is closed.
Definition: session.c:1036
static int openssl_start_listen(tls_ctx_t *lctx)
Definition: tls_openssl.c:640
int openssl_ctx_handshake_rx(tls_ctx_t *ctx, session_t *tls_session)
Definition: tls_openssl.c:326
u8 * srv_hostname
Definition: tls.h:81
VLIB_PLUGIN_REGISTER()
int tls_notify_app_accept(tls_ctx_t *ctx)
Definition: tls.c:181
u8 resume
Definition: tls.h:78
void tls_notify_app_enqueue(tls_ctx_t *ctx, session_t *app_session)
Definition: tls.c:172
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
static int openssl_try_handshake_read(openssl_ctx_t *oc, session_t *tls_session)
Definition: tls_openssl.c:239
static vlib_thread_main_t * vlib_get_thread_main()
Definition: global_funcs.h:32
openssl_listen_ctx_t * openssl_lctx_get(u32 lctx_index)
Definition: tls_openssl.c:107
u32 svm_fifo_max_write_chunk(svm_fifo_t *f)
Max contiguous chunk of data that can be written.
Definition: svm_fifo.c:529
static u32 openssl_listen_ctx_alloc(void)
Definition: tls_openssl.c:88
int svm_fifo_dequeue_drop(svm_fifo_t *f, u32 len)
Dequeue and drop bytes from fifo.
Definition: svm_fifo.c:1068
struct _svm_fifo svm_fifo_t
static void transport_connection_deschedule(transport_connection_t *tc)
Definition: transport.h:208
#define VLIB_INITS(...)
Definition: init.h:357
#define TLS_DBG(_lvl, _fmt, _args...)
Definition: tls.h:36
static int openssl_read_from_bio_into_fifo(svm_fifo_t *f, BIO *bio, u32 enq_max)
Definition: tls_openssl.c:113
static svm_fifo_chunk_t * svm_fifo_tail_chunk(svm_fifo_t *f)
Fifo tail chunk getter.
Definition: svm_fifo.h:593
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
static const u32 test_srv_crt_rsa_len
Definition: tls_test.h:47
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:171