Add TLS support for VCL 06/16306/7
authorPing Yu <ping.yu@intel.com>
Sat, 1 Dec 2018 00:16:17 +0000 (19:16 -0500)
committerFlorin Coras <florin.coras@gmail.com>
Fri, 4 Jan 2019 19:55:47 +0000 (19:55 +0000)
Ater this patch, vcl_test_client and vcl_test_server can work happily with
TLS connection.
"-S" is to indicate TLS connection.

Change-Id: I761894b0b5929912691625f0fe63604725b55978
Signed-off-by: Ping Yu <ping.yu@intel.com>
src/vcl/vcl_bapi.c
src/vcl/vcl_private.h
src/vcl/vcl_test.h
src/vcl/vcl_test_client.c
src/vcl/vcl_test_server.c
src/vcl/vppcom.c
src/vcl/vppcom.h

index b513bd7..de5e80a 100644 (file)
@@ -367,6 +367,31 @@ vl_api_connect_session_reply_t_handler (vl_api_connect_sock_reply_t * mp)
                  ntohl (mp->retval));
 }
 
+static void
+  vl_api_application_tls_cert_add_reply_t_handler
+  (vl_api_application_tls_cert_add_reply_t * mp)
+{
+  if (mp->retval)
+    {
+      clib_warning ("VCL<%d>: add cert failed: %U", getpid (),
+                   format_api_error, ntohl (mp->retval));
+      return;
+    }
+}
+
+static void
+  vl_api_application_tls_key_add_reply_t_handler
+  (vl_api_application_tls_key_add_reply_t * mp)
+{
+  if (mp->retval)
+    {
+      clib_warning ("VCL<%d>: add key failed: %U", getpid (),
+                   format_api_error, ntohl (mp->retval));
+      return;
+    }
+
+}
+
 #define foreach_sock_msg                                               \
 _(SESSION_ENABLE_DISABLE_REPLY, session_enable_disable_reply)          \
 _(BIND_SOCK_REPLY, bind_sock_reply)                                    \
@@ -375,6 +400,8 @@ _(CONNECT_SESSION_REPLY, connect_session_reply)                             \
 _(DISCONNECT_SESSION_REPLY, disconnect_session_reply)                  \
 _(APPLICATION_ATTACH_REPLY, application_attach_reply)                  \
 _(APPLICATION_DETACH_REPLY, application_detach_reply)                  \
+_(APPLICATION_TLS_CERT_ADD_REPLY, application_tls_cert_add_reply)      \
+_(APPLICATION_TLS_KEY_ADD_REPLY, application_tls_key_add_reply)        \
 _(MAP_ANOTHER_SEGMENT, map_another_segment)                            \
 _(UNMAP_SEGMENT, unmap_segment)                                                \
 _(APP_CUT_THROUGH_REGISTRATION_ADD, app_cut_through_registration_add)  \
@@ -444,6 +471,7 @@ vppcom_app_send_attach (void)
   bmp->options[APP_OPTIONS_PREALLOC_FIFO_PAIRS] =
     vcm->cfg.preallocated_fifo_pairs;
   bmp->options[APP_OPTIONS_EVT_QUEUE_SIZE] = vcm->cfg.event_queue_size;
+  bmp->options[APP_OPTIONS_TLS_ENGINE] = TLS_ENGINE_OPENSSL;
   if (nsid_len)
     {
       bmp->namespace_id_len = nsid_len;
@@ -596,6 +624,42 @@ vppcom_send_accept_session_reply (u64 handle, u32 context, int retval)
   vl_msg_api_send_shmem (wrk->vl_input_queue, (u8 *) & rmp);
 }
 
+void
+vppcom_send_application_tls_cert_add (vcl_session_t * session, char *cert,
+                                     u32 cert_len)
+{
+  vcl_worker_t *wrk = vcl_worker_get_current ();
+  vl_api_application_tls_cert_add_t *cert_mp;
+
+  cert_mp = vl_msg_api_alloc (sizeof (*cert_mp) + cert_len);
+  clib_memset (cert_mp, 0, sizeof (*cert_mp));
+  cert_mp->_vl_msg_id = ntohs (VL_API_APPLICATION_TLS_CERT_ADD);
+  cert_mp->client_index = wrk->my_client_index;
+  cert_mp->context = session->session_index;
+  cert_mp->cert_len = clib_host_to_net_u16 (cert_len);
+  clib_memcpy_fast (cert_mp->cert, cert, cert_len);
+  vl_msg_api_send_shmem (wrk->vl_input_queue, (u8 *) & cert_mp);
+
+}
+
+void
+vppcom_send_application_tls_key_add (vcl_session_t * session, char *key,
+                                    u32 key_len)
+{
+  vcl_worker_t *wrk = vcl_worker_get_current ();
+  vl_api_application_tls_key_add_t *key_mp;
+
+  key_mp = vl_msg_api_alloc (sizeof (*key_mp) + key_len);
+  clib_memset (key_mp, 0, sizeof (*key_mp));
+  key_mp->_vl_msg_id = ntohs (VL_API_APPLICATION_TLS_KEY_ADD);
+  key_mp->client_index = wrk->my_client_index;
+  key_mp->context = session->session_index;
+  key_mp->key_len = clib_host_to_net_u16 (key_len);
+  clib_memcpy_fast (key_mp->key, key, key_len);
+  vl_msg_api_send_shmem (wrk->vl_input_queue, (u8 *) & key_mp);
+
+}
+
 u32
 vcl_max_nsid_len (void)
 {
index 34098ac..9dce518 100644 (file)
@@ -557,6 +557,11 @@ void vppcom_send_bind_sock (vcl_session_t * session);
 void vppcom_send_unbind_sock (u64 vpp_handle);
 void vppcom_api_hookup (void);
 void vppcom_send_accept_session_reply (u64 vpp_handle, u32 context, int rv);
+void vppcom_send_application_tls_cert_add (vcl_session_t * session,
+                                          char *cert, u32 cert_len);
+void
+vppcom_send_application_tls_key_add (vcl_session_t * session, char *key,
+                                    u32 key_len);
 void vcl_send_app_worker_add_del (u8 is_add);
 void vcl_send_child_worker_del (vcl_worker_t * wrk);
 
index 9d28b26..638d519 100644 (file)
@@ -89,6 +89,7 @@ typedef struct __attribute__ ((packed))
   uint32_t verbose;
   uint32_t address_ip6;
   uint32_t transport_udp;
+  uint32_t transport_tls;
   uint64_t rxbuf_size;
   uint64_t txbuf_size;
   uint64_t num_writes;
@@ -120,6 +121,66 @@ typedef struct
   vcl_test_stats_t stats;
 } vcl_test_session_t;
 
+
+/*
+ * TLS server cert and keys to be used for testing only
+ */
+char vcl_test_crt_rsa[] =
+  "-----BEGIN CERTIFICATE-----\r\n"
+  "MIID5zCCAs+gAwIBAgIJALeMYCEHrTtJMA0GCSqGSIb3DQEBCwUAMIGJMQswCQYD\r\n"
+  "VQQGEwJVUzELMAkGA1UECAwCQ0ExETAPBgNVBAcMCFNhbiBKb3NlMQ4wDAYDVQQK\r\n"
+  "DAVDaXNjbzEOMAwGA1UECwwFZmQuaW8xFjAUBgNVBAMMDXRlc3R0bHMuZmQuaW8x\r\n"
+  "IjAgBgkqhkiG9w0BCQEWE3ZwcC1kZXZAbGlzdHMuZmQuaW8wHhcNMTgwMzA1MjEx\r\n"
+  "NTEyWhcNMjgwMzAyMjExNTEyWjCBiTELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNB\r\n"
+  "MREwDwYDVQQHDAhTYW4gSm9zZTEOMAwGA1UECgwFQ2lzY28xDjAMBgNVBAsMBWZk\r\n"
+  "LmlvMRYwFAYDVQQDDA10ZXN0dGxzLmZkLmlvMSIwIAYJKoZIhvcNAQkBFhN2cHAt\r\n"
+  "ZGV2QGxpc3RzLmZkLmlvMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA\r\n"
+  "4C1k8a1DuStgggqT4o09fP9sJ2dC54bxhS/Xk2VEfaIZ222WSo4X/syRVfVy9Yah\r\n"
+  "cpI1zJ/RDxaZSFhgA+nPZBrFMsrULkrdAOpOVj8eDEp9JuWdO2ODSoFnCvLxcYWB\r\n"
+  "Yc5kHryJpEaGJl1sFQSesnzMFty/59ta0stk0Fp8r5NhIjWvSovGzPo6Bhz+VS2c\r\n"
+  "ebIZh4x1t2hHaFcgm0qJoJ6DceReWCW8w+yOVovTolGGq+bpb2Hn7MnRSZ2K2NdL\r\n"
+  "+aLXpkZbS/AODP1FF2vTO1mYL290LO7/51vJmPXNKSDYMy5EvILr5/VqtjsFCwRL\r\n"
+  "Q4jcM/+GeHSAFWx4qIv0BwIDAQABo1AwTjAdBgNVHQ4EFgQUWa1SOB37xmT53tZQ\r\n"
+  "aXuLLhRI7U8wHwYDVR0jBBgwFoAUWa1SOB37xmT53tZQaXuLLhRI7U8wDAYDVR0T\r\n"
+  "BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAoUht13W4ya27NVzQuCMvqPWL3VM4\r\n"
+  "3xbPFk02FaGz/WupPu276zGlzJAZrbuDcQowwwU1Ni1Yygxl96s1c2M5rHDTrOKG\r\n"
+  "rK0hbkSFBo+i6I8u4HiiQ4rYmG0Hv6+sXn3of0HsbtDPGgWZoipPWDljPYEURu3e\r\n"
+  "3HRe/Dtsj9CakBoSDzs8ndWaBR+f4sM9Tk1cjD46Gq2T/qpSPXqKxEUXlzhdCAn4\r\n"
+  "twub17Bq2kykHpppCwPg5M+v30tHG/R2Go15MeFWbEJthFk3TZMjKL7UFs7fH+x2\r\n"
+  "wSonXb++jY+KmCb93C+soABBizE57g/KmiR2IxQ/LMjDik01RSUIaM0lLA==\r\n"
+  "-----END CERTIFICATE-----\r\n";
+uint32_t vcl_test_crt_rsa_len = sizeof (vcl_test_crt_rsa);
+
+char vcl_test_key_rsa[] =
+  "-----BEGIN PRIVATE KEY-----\r\n"
+  "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDgLWTxrUO5K2CC\r\n"
+  "CpPijT18/2wnZ0LnhvGFL9eTZUR9ohnbbZZKjhf+zJFV9XL1hqFykjXMn9EPFplI\r\n"
+  "WGAD6c9kGsUyytQuSt0A6k5WPx4MSn0m5Z07Y4NKgWcK8vFxhYFhzmQevImkRoYm\r\n"
+  "XWwVBJ6yfMwW3L/n21rSy2TQWnyvk2EiNa9Ki8bM+joGHP5VLZx5shmHjHW3aEdo\r\n"
+  "VyCbSomgnoNx5F5YJbzD7I5Wi9OiUYar5ulvYefsydFJnYrY10v5otemRltL8A4M\r\n"
+  "/UUXa9M7WZgvb3Qs7v/nW8mY9c0pINgzLkS8guvn9Wq2OwULBEtDiNwz/4Z4dIAV\r\n"
+  "bHioi/QHAgMBAAECggEBAMzGipP8+oT166U+NlJXRFifFVN1DvdhG9PWnOxGL+c3\r\n"
+  "ILmBBC08WQzmHshPemBvR6DZkA1H23cV5JTiLWrFtC00CvhXsLRMrE5+uWotI6yE\r\n"
+  "iofybMroHvD6/X5R510UX9hQ6MHu5ShLR5VZ9zXHz5MpTmB/60jG5dLx+jgcwBK8\r\n"
+  "LuGv2YB/WCUwT9QJ3YU2eaingnXtz/MrFbkbltrqlnBdlD+kTtw6Yac9y1XuuQXc\r\n"
+  "BPeulLNDuPolJVWbUvDBZrpt2dXTgz8ws1sv+wCNE0xwQJsqW4Nx3QkpibUL9RUr\r\n"
+  "CVbKlNfa9lopT6nGKlgX69R/uH35yh9AOsfasro6w0ECgYEA82UJ8u/+ORah+0sF\r\n"
+  "Q0FfW5MTdi7OAUHOz16pUsGlaEv0ERrjZxmAkHA/VRwpvDBpx4alCv0Hc39PFLIk\r\n"
+  "nhSsM2BEuBkTAs6/GaoNAiBtQVE/hN7awNRWVmlieS0go3Y3dzaE9IUMyj8sPOFT\r\n"
+  "5JdJ6BM69PHKCkY3dKdnnfpFEuECgYEA68mRpteunF1mdZgXs+WrN+uLlRrQR20F\r\n"
+  "ZyMYiUCH2Dtn26EzA2moy7FipIIrQcX/j+KhYNGM3e7MU4LymIO29E18mn8JODnH\r\n"
+  "sQOXzBTsf8A4yIVMkcuQD3bfb0JiUGYUPOidTp2N7IJA7+6Yc3vQOyb74lnKnJoO\r\n"
+  "gougPT2wS+cCgYAn7muzb6xFsXDhyW0Tm6YJYBfRS9yAWEuVufINobeBZPSl2cN1\r\n"
+  "Jrnw+HlrfTNbrJWuJmjtZJXUXQ6cVp2rUbjutNyRV4vG6iRwEXYQ40EJdkr1gZpi\r\n"
+  "CHQhuShuuPih2MNAy7EEbM+sXrDjTBR3bFqzuHPzu7dp+BshCFX3lRfAAQKBgGQt\r\n"
+  "K5i7IhCFDjb/+3IPLgOAK7mZvsvZ4eXD33TQ2eZgtut1PXtBtNl17/b85uv293Fm\r\n"
+  "VDISVcsk3eLNS8zIiT6afUoWlxAwXEs0v5WRfjl4radkGvgGiJpJYvyeM67877RB\r\n"
+  "EDSKc/X8ESLfOB44iGvZUEMG6zJFscx9DgN25iQZAoGAbyd+JEWwdVH9/K3IH1t2\r\n"
+  "PBkZX17kNWv+iVM1WyFjbe++vfKZCrOJiyiqhDeEqgrP3AuNMlaaduC3VRC3G5oV\r\n"
+  "Mj1tlhDWQ/qhvKdCKNdIVQYDE75nw+FRWV8yYkHAnXYW3tNoweDIwixE0hkPR1bc\r\n"
+  "oEjPLVNtx8SOj/M4rhaPT3I=\r\n" "-----END PRIVATE KEY-----\r\n";
+uint32_t vcl_test_key_rsa_len = sizeof (vcl_test_key_rsa);
+
 static inline void
 vcl_test_stats_accumulate (vcl_test_stats_t * accum, vcl_test_stats_t * incr)
 {
index e1d7b3b..70fe75d 100644 (file)
@@ -711,10 +711,11 @@ print_usage_and_exit (void)
           "  OPTIONS\n"
           "  -h               Print this message and exit.\n"
           "  -6               Use IPv6\n"
-          "  -u               Use UDP transport layer\n"
           "  -c               Print test config before test.\n"
           "  -w <dir>         Write test results to <dir>.\n"
           "  -X               Exit after running test.\n"
+          "  -D               Use UDP transport layer\n"
+          "  -S               Use TLS transport layer\n"
           "  -E               Run Echo test.\n"
           "  -N <num-writes>  Test Cfg: number of writes.\n"
           "  -R <rxbuf-size>  Test Cfg: rx buffer size.\n"
@@ -732,7 +733,7 @@ vtc_process_opts (vcl_test_client_main_t * vcm, int argc, char **argv)
   int c, v;
 
   opterr = 0;
-  while ((c = getopt (argc, argv, "chn:w:XE:I:N:R:T:UBV6D")) != -1)
+  while ((c = getopt (argc, argv, "chn:w:XE:I:N:R:T:UBV6DS")) != -1)
     switch (c)
       {
       case 'c':
@@ -873,6 +874,10 @@ vtc_process_opts (vcl_test_client_main_t * vcm, int argc, char **argv)
        ctrl->cfg.transport_udp = 1;
        break;
 
+      case 'S':
+       ctrl->cfg.transport_tls = 1;
+       break;
+
       case '?':
        switch (optopt)
          {
@@ -902,7 +907,19 @@ vtc_process_opts (vcl_test_client_main_t * vcm, int argc, char **argv)
       vtwrn ("Insufficient number of arguments!");
       print_usage_and_exit ();
     }
-  vcm->proto = ctrl->cfg.transport_udp ? VPPCOM_PROTO_UDP : VPPCOM_PROTO_TCP;
+
+  if (ctrl->cfg.transport_udp)
+    {
+      vcm->proto = VPPCOM_PROTO_UDP;
+    }
+  else if (ctrl->cfg.transport_tls)
+    {
+      vcm->proto = VPPCOM_PROTO_TLS;
+    }
+  else
+    {
+      vcm->proto = VPPCOM_PROTO_TCP;
+    }
 
   memset (&vcm->server_addr, 0, sizeof (vcm->server_addr));
   if (ctrl->cfg.address_ip6)
@@ -988,6 +1005,15 @@ main (int argc, char **argv)
   if (ctrl->fd < 0)
     vtfail ("vppcom_session_create()", ctrl->fd);
 
+  if (vcm->proto == VPPCOM_PROTO_TLS)
+    {
+      vppcom_session_tls_add_cert (ctrl->fd, vcl_test_crt_rsa,
+                                  vcl_test_crt_rsa_len);
+      vppcom_session_tls_add_key (ctrl->fd, vcl_test_key_rsa,
+                                 vcl_test_key_rsa_len);
+    }
+
+
   vtinf ("Connecting to server...");
   rv = vppcom_session_connect (ctrl->fd, &vcm->server_endpt);
   if (rv)
index 54f164e..2809441 100644 (file)
@@ -320,7 +320,8 @@ print_usage_and_exit (void)
           "  -h               Print this message and exit.\n"
           "  -6               Use IPv6\n"
           "  -w <num>         Number of workers\n"
-          "  -u               Use UDP transport layer\n");
+          "  -D               Use UDP transport layer\n"
+          "  -S               Use TLS transport layer\n");
   exit (1);
 }
 
@@ -370,7 +371,7 @@ vcl_test_server_process_opts (vcl_test_server_main_t * vsm, int argc,
   vsm->cfg.proto = VPPCOM_PROTO_TCP;
 
   opterr = 0;
-  while ((c = getopt (argc, argv, "6Dsw:")) != -1)
+  while ((c = getopt (argc, argv, "6DSsw:")) != -1)
     switch (c)
       {
       case '6':
@@ -381,6 +382,10 @@ vcl_test_server_process_opts (vcl_test_server_main_t * vsm, int argc,
        vsm->cfg.proto = VPPCOM_PROTO_UDP;
        break;
 
+      case 'S':
+       vsm->cfg.proto = VPPCOM_PROTO_TLS;
+       break;
+
       case 'w':
        v = atoi (optarg);
        if (v > 1)
@@ -499,6 +504,15 @@ vts_worker_init (vcl_test_server_worker_t * wrk)
   if (wrk->listen_fd < 0)
     vtfail ("vppcom_session_create()", wrk->listen_fd);
 
+
+  if (vsm->cfg.proto == VPPCOM_PROTO_TLS)
+    {
+      vppcom_session_tls_add_cert (wrk->listen_fd, vcl_test_crt_rsa,
+                                  vcl_test_crt_rsa_len);
+      vppcom_session_tls_add_key (wrk->listen_fd, vcl_test_key_rsa,
+                                 vcl_test_key_rsa_len);
+    }
+
   rv = vppcom_session_bind (wrk->listen_fd, &vsm->cfg.endpt);
   if (rv < 0)
     vtfail ("vppcom_session_bind()", rv);
index be72936..70afdce 100644 (file)
@@ -1191,7 +1191,7 @@ vppcom_session_bind (uint32_t session_handle, vppcom_endpt_t * ep)
        format_ip46_address, &session->transport.lcl_ip,
        session->transport.is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
        clib_net_to_host_u16 (session->transport.lcl_port),
-       session->session_type ? "UDP" : "TCP");
+       vppcom_proto_str (session->session_type));
   vcl_evt (VCL_EVT_BIND, session);
 
   if (session->session_type == VPPCOM_PROTO_UDP)
@@ -1246,6 +1246,55 @@ vppcom_session_listen (uint32_t listen_sh, uint32_t q_len)
   return VPPCOM_OK;
 }
 
+int
+vppcom_session_tls_add_cert (uint32_t session_handle, char *cert,
+                            uint32_t cert_len)
+{
+
+  vcl_worker_t *wrk = vcl_worker_get_current ();
+  vcl_session_t *session = 0;
+
+  session = vcl_session_get_w_handle (wrk, session_handle);
+  if (!session)
+    return VPPCOM_EBADFD;
+
+  if (cert_len == 0 || cert_len == ~0)
+    return VPPCOM_EBADFD;
+
+  /*
+   * Send listen request to vpp and wait for reply
+   */
+  vppcom_send_application_tls_cert_add (session, cert, cert_len);
+
+  return VPPCOM_OK;
+
+}
+
+int
+vppcom_session_tls_add_key (uint32_t session_handle, char *key,
+                           uint32_t key_len)
+{
+
+  vcl_worker_t *wrk = vcl_worker_get_current ();
+  vcl_session_t *session = 0;
+
+  session = vcl_session_get_w_handle (wrk, session_handle);
+  if (!session)
+    return VPPCOM_EBADFD;
+
+  if (key_len == 0 || key_len == ~0)
+    return VPPCOM_EBADFD;
+
+  /*
+   * Send listen request to vpp and wait for reply
+   */
+  vppcom_send_application_tls_key_add (session, key, key_len);
+
+  return VPPCOM_OK;
+
+
+}
+
 static int
 validate_args_session_accept_ (vcl_worker_t * wrk,
                               vcl_session_t * listen_session)
@@ -1420,7 +1469,7 @@ vppcom_session_connect (uint32_t session_handle, vppcom_endpt_t * server_ep)
            &session->transport.rmt_ip, session->transport.is_ip4 ?
            IP46_TYPE_IP4 : IP46_TYPE_IP6,
            clib_net_to_host_u16 (session->transport.rmt_port),
-           session->session_type ? "UDP" : "TCP", session->session_state,
+           vppcom_proto_str (session->session_type), session->session_state,
            vppcom_session_state_str (session->session_state));
       return VPPCOM_OK;
     }
@@ -1442,7 +1491,7 @@ vppcom_session_connect (uint32_t session_handle, vppcom_endpt_t * server_ep)
        &session->transport.rmt_ip, session->transport.is_ip4 ?
        IP46_TYPE_IP4 : IP46_TYPE_IP6,
        clib_net_to_host_u16 (session->transport.rmt_port),
-       session->session_type ? "UDP" : "TCP");
+       vppcom_proto_str (session->session_type));
 
   /*
    * Send connect request and wait for reply from vpp
index 00527f4..641946b 100644 (file)
@@ -48,6 +48,10 @@ typedef enum
 {
   VPPCOM_PROTO_TCP = 0,
   VPPCOM_PROTO_UDP,
+  VPPCOM_PROTO_SCTP,
+  VPPCOM_PROTO_NONE,
+  VPPCOM_PROTO_TLS,
+  VPPCOM_PROTO_UDPC
 } vppcom_proto_t;
 
 static inline char *
@@ -58,10 +62,19 @@ vppcom_proto_str (vppcom_proto_t proto)
   switch (proto)
     {
     case VPPCOM_PROTO_TCP:
-      proto_str = "VPPCOM_PROTO_TCP";
+      proto_str = "TCP";
       break;
     case VPPCOM_PROTO_UDP:
-      proto_str = "VPPCOM_PROTO_UDP";
+      proto_str = "UDP";
+      break;
+    case VPPCOM_PROTO_SCTP:
+      proto_str = "SCTP";
+      break;
+    case VPPCOM_PROTO_TLS:
+      proto_str = "TLS";
+      break;
+    case VPPCOM_PROTO_UDPC:
+      proto_str = "UDPC";
       break;
     default:
       proto_str = "UNKNOWN";
@@ -271,6 +284,10 @@ extern int vppcom_session_read_segments (uint32_t session_handle,
                                         vppcom_data_segments_t ds);
 extern void vppcom_session_free_segments (uint32_t session_handle,
                                          vppcom_data_segments_t ds);
+extern int vppcom_session_tls_add_cert (uint32_t session_handle, char *cert,
+                                       uint32_t cert_len);
+extern int vppcom_session_tls_add_key (uint32_t session_handle, char *key,
+                                      uint32_t key_len);
 extern int vppcom_data_segment_copy (void *buf, vppcom_data_segments_t ds,
                                     uint32_t max_bytes);