session: Add certificate store
[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   const SSL_METHOD *method;
596   SSL_CTX *ssl_ctx;
597   int rv;
598   BIO *cert_bio;
599   X509 *srvcert;
600   EVP_PKEY *pkey;
601   u32 olc_index;
602   openssl_listen_ctx_t *olc;
603   app_cert_key_pair_t *ckpair;
604
605   long flags = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION;
606   openssl_main_t *om = &openssl_main;
607
608   ckpair = app_cert_key_pair_get_if_valid (lctx->ckpair_index);
609   if (!ckpair)
610     return -1;
611
612   if (!ckpair->cert || !ckpair->key)
613     {
614       TLS_DBG (1, "tls cert and/or key not configured %d",
615                lctx->parent_app_wrk_index);
616       return -1;
617     }
618
619   method = SSLv23_method ();
620   ssl_ctx = SSL_CTX_new (method);
621   if (!ssl_ctx)
622     {
623       clib_warning ("Unable to create SSL context");
624       return -1;
625     }
626
627   SSL_CTX_set_mode (ssl_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE);
628 #ifdef HAVE_OPENSSL_ASYNC
629   if (om->async)
630     SSL_CTX_set_mode (ssl_ctx, SSL_MODE_ASYNC);
631   SSL_CTX_set_async_callback (ssl_ctx, tls_async_openssl_callback);
632 #endif
633   SSL_CTX_set_options (ssl_ctx, flags);
634   SSL_CTX_set_ecdh_auto (ssl_ctx, 1);
635
636   rv = SSL_CTX_set_cipher_list (ssl_ctx, (const char *) om->ciphers);
637   if (rv != 1)
638     {
639       TLS_DBG (1, "Couldn't set cipher");
640       return -1;
641     }
642
643   /*
644    * Set the key and cert
645    */
646   cert_bio = BIO_new (BIO_s_mem ());
647   BIO_write (cert_bio, ckpair->cert, vec_len (ckpair->cert));
648   srvcert = PEM_read_bio_X509 (cert_bio, NULL, NULL, NULL);
649   if (!srvcert)
650     {
651       clib_warning ("unable to parse certificate");
652       return -1;
653     }
654   SSL_CTX_use_certificate (ssl_ctx, srvcert);
655   BIO_free (cert_bio);
656
657   cert_bio = BIO_new (BIO_s_mem ());
658   BIO_write (cert_bio, ckpair->key, vec_len (ckpair->key));
659   pkey = PEM_read_bio_PrivateKey (cert_bio, NULL, NULL, NULL);
660   if (!pkey)
661     {
662       clib_warning ("unable to parse pkey");
663       return -1;
664     }
665   SSL_CTX_use_PrivateKey (ssl_ctx, pkey);
666   BIO_free (cert_bio);
667
668   olc_index = openssl_listen_ctx_alloc ();
669   olc = openssl_lctx_get (olc_index);
670   olc->ssl_ctx = ssl_ctx;
671   olc->srvcert = srvcert;
672   olc->pkey = pkey;
673
674   /* store SSL_CTX into TLS level structure */
675   lctx->tls_ssl_ctx = olc_index;
676
677   return 0;
678
679 }
680
681 static int
682 openssl_stop_listen (tls_ctx_t * lctx)
683 {
684   u32 olc_index;
685   openssl_listen_ctx_t *olc;
686
687   olc_index = lctx->tls_ssl_ctx;
688   olc = openssl_lctx_get (olc_index);
689
690   X509_free (olc->srvcert);
691   EVP_PKEY_free (olc->pkey);
692
693   SSL_CTX_free (olc->ssl_ctx);
694   openssl_listen_ctx_free (olc);
695
696   return 0;
697 }
698
699 static int
700 openssl_ctx_init_server (tls_ctx_t * ctx)
701 {
702   openssl_ctx_t *oc = (openssl_ctx_t *) ctx;
703   u32 olc_index = ctx->tls_ssl_ctx;
704   openssl_listen_ctx_t *olc;
705   session_t *tls_session;
706   int rv, err;
707 #ifdef HAVE_OPENSSL_ASYNC
708   openssl_resume_handler *handler;
709 #endif
710
711   /* Start a new connection */
712
713   olc = openssl_lctx_get (olc_index);
714   oc->ssl = SSL_new (olc->ssl_ctx);
715   if (oc->ssl == NULL)
716     {
717       TLS_DBG (1, "Couldn't initialize ssl struct");
718       return -1;
719     }
720
721   oc->rbio = BIO_new (BIO_s_mem ());
722   oc->wbio = BIO_new (BIO_s_mem ());
723
724   BIO_set_mem_eof_return (oc->rbio, -1);
725   BIO_set_mem_eof_return (oc->wbio, -1);
726
727   SSL_set_bio (oc->ssl, oc->wbio, oc->rbio);
728   SSL_set_accept_state (oc->ssl);
729
730   TLS_DBG (1, "Initiating handshake for [%u]%u", ctx->c_thread_index,
731            oc->openssl_ctx_index);
732
733   tls_session = session_get_from_handle (ctx->tls_session_handle);
734   while (1)
735     {
736       rv = SSL_do_handshake (oc->ssl);
737       err = SSL_get_error (oc->ssl, rv);
738       openssl_try_handshake_write (oc, tls_session);
739 #ifdef HAVE_OPENSSL_ASYNC
740       if (err == SSL_ERROR_WANT_ASYNC)
741         {
742           handler = (openssl_resume_handler *) openssl_ctx_handshake_rx;
743           vpp_ssl_async_process_event (ctx, handler);
744           break;
745         }
746 #endif
747       if (err != SSL_ERROR_WANT_WRITE)
748         break;
749     }
750
751   TLS_DBG (2, "tls state for [%u]%u is su", ctx->c_thread_index,
752            oc->openssl_ctx_index, SSL_state_string_long (oc->ssl));
753   return 0;
754 }
755
756 static u8
757 openssl_handshake_is_over (tls_ctx_t * ctx)
758 {
759   openssl_ctx_t *mc = (openssl_ctx_t *) ctx;
760   if (!mc->ssl)
761     return 0;
762   return SSL_is_init_finished (mc->ssl);
763 }
764
765 static int
766 openssl_transport_close (tls_ctx_t * ctx)
767 {
768   if (!openssl_handshake_is_over (ctx))
769     {
770       openssl_handle_handshake_failure (ctx);
771       return 0;
772     }
773   session_transport_closing_notify (&ctx->connection);
774   return 0;
775 }
776
777 static int
778 openssl_app_close (tls_ctx_t * ctx)
779 {
780   openssl_ctx_t *oc = (openssl_ctx_t *) ctx;
781   session_t *app_session;
782
783   /* Wait for all data to be written to tcp */
784   app_session = session_get_from_handle (ctx->app_session_handle);
785   if (BIO_ctrl_pending (oc->rbio) <= 0
786       && !svm_fifo_max_dequeue_cons (app_session->tx_fifo))
787     openssl_confirm_app_close (ctx);
788   else
789     ctx->app_closed = 1;
790   return 0;
791 }
792
793 const static tls_engine_vft_t openssl_engine = {
794   .ctx_alloc = openssl_ctx_alloc,
795   .ctx_free = openssl_ctx_free,
796   .ctx_get = openssl_ctx_get,
797   .ctx_get_w_thread = openssl_ctx_get_w_thread,
798   .ctx_init_server = openssl_ctx_init_server,
799   .ctx_init_client = openssl_ctx_init_client,
800   .ctx_write = openssl_ctx_write,
801   .ctx_read = openssl_ctx_read,
802   .ctx_handshake_is_over = openssl_handshake_is_over,
803   .ctx_start_listen = openssl_start_listen,
804   .ctx_stop_listen = openssl_stop_listen,
805   .ctx_transport_close = openssl_transport_close,
806   .ctx_app_close = openssl_app_close,
807 };
808
809 int
810 tls_init_ca_chain (void)
811 {
812   openssl_main_t *om = &openssl_main;
813   tls_main_t *tm = vnet_tls_get_main ();
814   BIO *cert_bio;
815   X509 *testcert;
816   int rv;
817
818   if (access (tm->ca_cert_path, F_OK | R_OK) == -1)
819     {
820       clib_warning ("Could not initialize TLS CA certificates");
821       return -1;
822     }
823
824   if (!(om->cert_store = X509_STORE_new ()))
825     {
826       clib_warning ("failed to create cert store");
827       return -1;
828     }
829
830   rv = X509_STORE_load_locations (om->cert_store, tm->ca_cert_path, 0);
831   if (rv < 0)
832     {
833       clib_warning ("failed to load ca certificate");
834     }
835
836   if (tm->use_test_cert_in_ca)
837     {
838       cert_bio = BIO_new (BIO_s_mem ());
839       BIO_write (cert_bio, test_srv_crt_rsa, test_srv_crt_rsa_len);
840       testcert = PEM_read_bio_X509 (cert_bio, NULL, NULL, NULL);
841       if (!testcert)
842         {
843           clib_warning ("unable to parse certificate");
844           return -1;
845         }
846       X509_STORE_add_cert (om->cert_store, testcert);
847       rv = 0;
848     }
849   return (rv < 0 ? -1 : 0);
850 }
851
852 int
853 tls_openssl_set_ciphers (char *ciphers)
854 {
855   openssl_main_t *om = &openssl_main;
856   int i;
857
858   if (!ciphers)
859     {
860       return -1;
861     }
862
863   vec_validate (om->ciphers, strlen (ciphers) - 1);
864   for (i = 0; i < vec_len (om->ciphers); i++)
865     {
866       om->ciphers[i] = toupper (ciphers[i]);
867     }
868
869   return 0;
870
871 }
872
873 static clib_error_t *
874 tls_openssl_init (vlib_main_t * vm)
875 {
876   vlib_thread_main_t *vtm = vlib_get_thread_main ();
877   openssl_main_t *om = &openssl_main;
878   clib_error_t *error = 0;
879   u32 num_threads;
880
881   error = tls_openssl_api_init (vm);
882   num_threads = 1 /* main thread */  + vtm->n_threads;
883
884   SSL_library_init ();
885   SSL_load_error_strings ();
886
887   if (tls_init_ca_chain ())
888     {
889       clib_warning ("failed to initialize TLS CA chain");
890       return 0;
891     }
892
893   vec_validate (om->ctx_pool, num_threads - 1);
894
895   tls_register_engine (&openssl_engine, TLS_ENGINE_OPENSSL);
896
897   om->engine_init = 0;
898
899   /* default ciphers */
900   tls_openssl_set_ciphers
901     ("ALL:!ADH:!LOW:!EXP:!MD5:!RC4-SHA:!DES-CBC3-SHA:@STRENGTH");
902
903   return error;
904 }
905 /* *INDENT-OFF* */
906 VLIB_INIT_FUNCTION (tls_openssl_init) =
907 {
908   .runs_after = VLIB_INITS("tls_init"),
909 };
910 /* *INDENT-ON* */
911
912 #ifdef HAVE_OPENSSL_ASYNC
913 static clib_error_t *
914 tls_openssl_set_command_fn (vlib_main_t * vm, unformat_input_t * input,
915                             vlib_cli_command_t * cmd)
916 {
917   openssl_main_t *om = &openssl_main;
918   char *engine_name = NULL;
919   char *engine_alg = NULL;
920   char *ciphers = NULL;
921   u8 engine_name_set = 0;
922   int i;
923
924   /* By present, it is not allowed to configure engine again after running */
925   if (om->engine_init)
926     {
927       clib_warning ("engine has started!\n");
928       return clib_error_return
929         (0, "engine has started, and no config is accepted");
930     }
931
932   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
933     {
934       if (unformat (input, "engine %s", &engine_name))
935         {
936           engine_name_set = 1;
937         }
938       else if (unformat (input, "async"))
939         {
940           om->async = 1;
941           openssl_async_node_enable_disable (1);
942         }
943       else if (unformat (input, "alg %s", &engine_alg))
944         {
945           for (i = 0; i < strnlen (engine_alg, MAX_CRYPTO_LEN); i++)
946             engine_alg[i] = toupper (engine_alg[i]);
947         }
948       else if (unformat (input, "ciphers %s", &ciphers))
949         {
950           tls_openssl_set_ciphers (ciphers);
951         }
952       else
953         return clib_error_return (0, "failed: unknown input `%U'",
954                                   format_unformat_error, input);
955     }
956
957   /* reset parameters if engine is not configured */
958   if (!engine_name_set)
959     {
960       clib_warning ("No engine provided! \n");
961       om->async = 0;
962     }
963   else
964     {
965       if (openssl_engine_register (engine_name, engine_alg) < 0)
966         {
967           return clib_error_return (0, "failed to register %s polling",
968                                     engine_name);
969         }
970     }
971
972   return 0;
973 }
974
975 /* *INDENT-OFF* */
976 VLIB_CLI_COMMAND (tls_openssl_set_command, static) =
977 {
978   .path = "tls openssl set",
979   .short_help = "tls openssl set [engine <engine name>] [alg [algorithm] [async]",
980   .function = tls_openssl_set_command_fn,
981 };
982 /* *INDENT-ON* */
983 #endif
984
985 /* *INDENT-OFF* */
986 VLIB_PLUGIN_REGISTER () = {
987     .version = VPP_BUILD_VER,
988     .description = "Transport Layer Security (TLS) Engine, OpenSSL Based",
989 };
990 /* *INDENT-ON* */
991
992 /*
993  * fd.io coding-style-patch-verification: ON
994  *
995  * Local Variables:
996  * eval: (c-set-style "gnu")
997  * End:
998  */