vcl session: switch to generic cert key apis

Remove the deprecated tls apis.

Type: improvement

Signed-off-by: Florin Coras <fcoras@cisco.com>
Change-Id: Ia1e12bd813671146f0aca22e83d04c23ac13e595
diff --git a/src/plugins/hs_apps/echo_client.c b/src/plugins/hs_apps/echo_client.c
index 50d8157..c263294 100644
--- a/src/plugins/hs_apps/echo_client.c
+++ b/src/plugins/hs_apps/echo_client.c
@@ -620,8 +620,7 @@
 static clib_error_t *
 echo_clients_attach (u8 * appns_id, u64 appns_flags, u64 appns_secret)
 {
-  vnet_app_add_tls_cert_args_t _a_cert, *a_cert = &_a_cert;
-  vnet_app_add_tls_key_args_t _a_key, *a_key = &_a_key;
+  vnet_app_add_cert_key_pair_args_t _ck_pair, *ck_pair = &_ck_pair;
   u32 prealloc_fifos, segment_size = 256 << 20;
   echo_client_main_t *ecm = &echo_client_main;
   vnet_app_attach_args_t _a, *a = &_a;
@@ -667,17 +666,14 @@
   ecm->app_index = a->app_index;
   vec_free (a->name);
 
-  clib_memset (a_cert, 0, sizeof (*a_cert));
-  a_cert->app_index = a->app_index;
-  vec_validate (a_cert->cert, test_srv_crt_rsa_len);
-  clib_memcpy_fast (a_cert->cert, test_srv_crt_rsa, test_srv_crt_rsa_len);
-  vnet_app_add_tls_cert (a_cert);
+  clib_memset (ck_pair, 0, sizeof (*ck_pair));
+  ck_pair->cert = (u8 *) test_srv_crt_rsa;
+  ck_pair->key = (u8 *) test_srv_key_rsa;
+  ck_pair->cert_len = test_srv_crt_rsa_len;
+  ck_pair->key_len = test_srv_key_rsa_len;
+  vnet_app_add_cert_key_pair (ck_pair);
+  ecm->ckpair_index = ck_pair->index;
 
-  clib_memset (a_key, 0, sizeof (*a_key));
-  a_key->app_index = a->app_index;
-  vec_validate (a_key->key, test_srv_key_rsa_len);
-  clib_memcpy_fast (a_key->key, test_srv_key_rsa, test_srv_key_rsa_len);
-  vnet_app_add_tls_key (a_key);
   return 0;
 }
 
@@ -693,6 +689,8 @@
   rv = vnet_application_detach (da);
   ecm->test_client_attached = 0;
   ecm->app_index = ~0;
+  vnet_app_del_cert_key_pair (ecm->ckpair_index);
+
   return rv;
 }
 
@@ -723,20 +721,25 @@
 clib_error_t *
 echo_clients_connect (vlib_main_t * vm, u32 n_clients)
 {
+  session_endpoint_cfg_t sep = SESSION_ENDPOINT_CFG_NULL;
   echo_client_main_t *ecm = &echo_client_main;
   vnet_connect_args_t _a, *a = &_a;
   int i, rv;
 
   clib_memset (a, 0, sizeof (*a));
 
+  if (parse_uri ((char *) ecm->connect_uri, &sep))
+    return clib_error_return (0, "invalid uri");
+
   for (i = 0; i < n_clients; i++)
     {
-      a->uri = (char *) ecm->connect_uri;
+      clib_memcpy (&a->sep_ext, &sep, sizeof (sep));
       a->api_context = i;
       a->app_index = ecm->app_index;
+      a->sep_ext.ckpair_index = ecm->ckpair_index;
 
       vlib_worker_thread_barrier_sync (vm);
-      if ((rv = vnet_connect_uri (a)))
+      if ((rv = vnet_connect (a)))
 	{
 	  vlib_worker_thread_barrier_release (vm);
 	  return clib_error_return (0, "connect returned: %d", rv);
diff --git a/src/plugins/hs_apps/echo_client.h b/src/plugins/hs_apps/echo_client.h
index 34cf0bd..c4983ca 100644
--- a/src/plugins/hs_apps/echo_client.h
+++ b/src/plugins/hs_apps/echo_client.h
@@ -66,6 +66,7 @@
   u8 is_dgram;
   u32 no_copy;				/**< Don't memcpy data to tx fifo */
   u32 quic_streams;			/**< QUIC streams per connection */
+  u32 ckpair_index;			/**< Cert key pair for tls/quic */
 
   /*
    * Test state variables
diff --git a/src/plugins/hs_apps/echo_server.c b/src/plugins/hs_apps/echo_server.c
index a5335bb..1c40225 100644
--- a/src/plugins/hs_apps/echo_server.c
+++ b/src/plugins/hs_apps/echo_server.c
@@ -47,7 +47,9 @@
   u32 private_segment_size;	/**< Size of private segments  */
   char *server_uri;		/**< Server URI */
   u32 tls_engine;		/**< TLS engine: mbedtls/openssl */
+  u32 ckpair_index;		/**< Cert and key for tls/quic */
   u8 is_dgram;			/**< set if transport is dgram */
+
   /*
    * Test state
    */
@@ -304,8 +306,7 @@
 static int
 echo_server_attach (u8 * appns_id, u64 appns_flags, u64 appns_secret)
 {
-  vnet_app_add_tls_cert_args_t _a_cert, *a_cert = &_a_cert;
-  vnet_app_add_tls_key_args_t _a_key, *a_key = &_a_key;
+  vnet_app_add_cert_key_pair_args_t _ck_pair, *ck_pair = &_ck_pair;
   echo_server_main_t *esm = &echo_server_main;
   vnet_app_attach_args_t _a, *a = &_a;
   u64 options[APP_OPTIONS_N_OPTIONS];
@@ -357,17 +358,14 @@
   esm->app_index = a->app_index;
   vec_free (a->name);
 
-  clib_memset (a_cert, 0, sizeof (*a_cert));
-  a_cert->app_index = a->app_index;
-  vec_validate (a_cert->cert, test_srv_crt_rsa_len);
-  clib_memcpy_fast (a_cert->cert, test_srv_crt_rsa, test_srv_crt_rsa_len);
-  vnet_app_add_tls_cert (a_cert);
+  clib_memset (ck_pair, 0, sizeof (*ck_pair));
+  ck_pair->cert = (u8 *) test_srv_crt_rsa;
+  ck_pair->key = (u8 *) test_srv_key_rsa;
+  ck_pair->cert_len = test_srv_crt_rsa_len;
+  ck_pair->key_len = test_srv_key_rsa_len;
+  vnet_app_add_cert_key_pair (ck_pair);
+  esm->ckpair_index = ck_pair->index;
 
-  clib_memset (a_key, 0, sizeof (*a_key));
-  a_key->app_index = a->app_index;
-  vec_validate (a_key->key, test_srv_key_rsa_len);
-  clib_memcpy_fast (a_key->key, test_srv_key_rsa, test_srv_key_rsa_len);
-  vnet_app_add_tls_key (a_key);
   return 0;
 }
 
@@ -381,6 +379,7 @@
   da->app_index = esm->app_index;
   rv = vnet_application_detach (da);
   esm->app_index = ~0;
+  vnet_app_del_cert_key_pair (esm->ckpair_index);
   return rv;
 }
 
@@ -389,17 +388,16 @@
 {
   i32 rv;
   echo_server_main_t *esm = &echo_server_main;
-  vnet_listen_args_t _args = {
-    .app_index = esm->app_index,
-    .sep_ext = {
-		.app_wrk_index = 0,
-		}
-  }, *args = &_args;
+  vnet_listen_args_t _args = { 0 }, *args = &_args;
+
+  args->sep_ext.app_wrk_index = 0;
 
   if ((rv = parse_uri (esm->server_uri, &args->sep_ext)))
     {
       return -1;
     }
+  args->app_index = esm->app_index;
+  args->sep_ext.ckpair_index = esm->ckpair_index;
 
   if (args->sep_ext.transport_proto == TRANSPORT_PROTO_UDP)
     {
diff --git a/src/plugins/hs_apps/http_server.c b/src/plugins/hs_apps/http_server.c
index ce4e09a..e1674d5 100644
--- a/src/plugins/hs_apps/http_server.c
+++ b/src/plugins/hs_apps/http_server.c
@@ -73,6 +73,9 @@
   /* process node index for evnt scheduling */
   u32 node_index;
 
+  /* Cert key pair for tls */
+  u32 ckpair_index;
+
   tw_timer_wheel_2t_1w_2048sl_t tw;
   clib_spinlock_t tw_lock;
 
@@ -712,8 +715,7 @@
 static int
 http_server_attach ()
 {
-  vnet_app_add_tls_cert_args_t _a_cert, *a_cert = &_a_cert;
-  vnet_app_add_tls_key_args_t _a_key, *a_key = &_a_key;
+  vnet_app_add_cert_key_pair_args_t _ck_pair, *ck_pair = &_ck_pair;
   http_server_main_t *hsm = &http_server_main;
   u64 options[APP_OPTIONS_N_OPTIONS];
   vnet_app_attach_args_t _a, *a = &_a;
@@ -746,17 +748,13 @@
   vec_free (a->name);
   hsm->app_index = a->app_index;
 
-  clib_memset (a_cert, 0, sizeof (*a_cert));
-  a_cert->app_index = a->app_index;
-  vec_validate (a_cert->cert, test_srv_crt_rsa_len);
-  clib_memcpy_fast (a_cert->cert, test_srv_crt_rsa, test_srv_crt_rsa_len);
-  vnet_app_add_tls_cert (a_cert);
-
-  clib_memset (a_key, 0, sizeof (*a_key));
-  a_key->app_index = a->app_index;
-  vec_validate (a_key->key, test_srv_key_rsa_len);
-  clib_memcpy_fast (a_key->key, test_srv_key_rsa, test_srv_key_rsa_len);
-  vnet_app_add_tls_key (a_key);
+  clib_memset (ck_pair, 0, sizeof (*ck_pair));
+  ck_pair->cert = (u8 *) test_srv_crt_rsa;
+  ck_pair->key = (u8 *) test_srv_key_rsa;
+  ck_pair->cert_len = test_srv_crt_rsa_len;
+  ck_pair->key_len = test_srv_key_rsa_len;
+  vnet_app_add_cert_key_pair (ck_pair);
+  hsm->ckpair_index = ck_pair->index;
 
   return 0;
 }
@@ -764,14 +762,24 @@
 static int
 http_server_listen ()
 {
+  session_endpoint_cfg_t sep = SESSION_ENDPOINT_CFG_NULL;
   http_server_main_t *hsm = &http_server_main;
   vnet_listen_args_t _a, *a = &_a;
+  char *uri = "tcp://0.0.0.0/80";
+
   clib_memset (a, 0, sizeof (*a));
   a->app_index = hsm->app_index;
-  a->uri = "tcp://0.0.0.0/80";
+
   if (hsm->uri)
-    a->uri = (char *) hsm->uri;
-  return vnet_bind_uri (a);
+    uri = (char *) hsm->uri;
+
+  if (parse_uri (uri, &sep))
+    return -1;
+
+  clib_memcpy (&a->sep_ext, &sep, sizeof (sep));
+  a->sep_ext.ckpair_index = hsm->ckpair_index;
+
+  return vnet_listen (a);
 }
 
 static void
diff --git a/src/plugins/hs_apps/vcl/vcl_test_client.c b/src/plugins/hs_apps/vcl/vcl_test_client.c
index 51544a7..0aff98e 100644
--- a/src/plugins/hs_apps/vcl/vcl_test_client.c
+++ b/src/plugins/hs_apps/vcl/vcl_test_client.c
@@ -51,6 +51,7 @@
   vcl_test_t post_test;
   uint8_t proto;
   uint32_t n_workers;
+  uint32_t ckpair_index;
   volatile int active_workers;
   struct sockaddr_storage server_addr;
 } vcl_test_client_main_t;
@@ -265,6 +266,13 @@
 	  return ts->fd;
 	}
 
+      if (vcm->proto == VPPCOM_PROTO_TLS)
+	{
+	  uint32_t ckp_len = sizeof (vcm->ckpair_index);
+	  vppcom_session_attr (ts->fd, VPPCOM_ATTR_SET_CKPAIR,
+			       &vcm->ckpair_index, &ckp_len);
+	}
+
       /* Connect is blocking */
       rv = vppcom_session_connect (ts->fd, &vcm->server_endpt);
       if (rv < 0)
@@ -1099,11 +1107,23 @@
 
   if (vcm->proto == VPPCOM_PROTO_TLS || vcm->proto == VPPCOM_PROTO_QUIC)
     {
+      vppcom_cert_key_pair_t ckpair;
+      uint32_t ckp_len;
+      int ckp_index;
+
       vtinf ("Adding tls certs ...");
-      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);
+      ckpair.cert = vcl_test_crt_rsa;
+      ckpair.key = vcl_test_key_rsa;
+      ckpair.cert_len = vcl_test_crt_rsa_len;
+      ckpair.key_len = vcl_test_key_rsa_len;
+      ckp_index = vppcom_add_cert_key_pair (&ckpair);
+      if (ckp_index < 0)
+	vtfail ("vppcom_add_cert_key_pair()", ckp_index);
+
+      vcm->ckpair_index = ckp_index;
+      ckp_len = sizeof (ckp_index);
+      vppcom_session_attr (ctrl->fd, VPPCOM_ATTR_SET_CKPAIR, &ckp_index,
+			   &ckp_len);
     }
 
   vtinf ("Connecting to server...");
diff --git a/src/plugins/hs_apps/vcl/vcl_test_server.c b/src/plugins/hs_apps/vcl/vcl_test_server.c
index 798fd72..a2a4d6a 100644
--- a/src/plugins/hs_apps/vcl/vcl_test_server.c
+++ b/src/plugins/hs_apps/vcl/vcl_test_server.c
@@ -553,10 +553,22 @@
   if (vsm->cfg.proto == VPPCOM_PROTO_TLS
       || vsm->cfg.proto == VPPCOM_PROTO_QUIC)
     {
-      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);
+      vppcom_cert_key_pair_t ckpair;
+      uint32_t ckp_len;
+      int ckp_index;
+
+      vtinf ("Adding tls certs ...");
+      ckpair.cert = vcl_test_crt_rsa;
+      ckpair.key = vcl_test_key_rsa;
+      ckpair.cert_len = vcl_test_crt_rsa_len;
+      ckpair.key_len = vcl_test_key_rsa_len;
+      ckp_index = vppcom_add_cert_key_pair (&ckpair);
+      if (ckp_index < 0)
+	vtfail ("vppcom_add_cert_key_pair()", ckp_index);
+
+      ckp_len = sizeof (ckp_index);
+      vppcom_session_attr (wrk->listen_fd, VPPCOM_ATTR_SET_CKPAIR, &ckp_index,
+			   &ckp_len);
     }
 
   rv = vppcom_session_bind (wrk->listen_fd, &vsm->cfg.endpt);
diff --git a/src/plugins/http_static/http_static.h b/src/plugins/http_static/http_static.h
index daa2ecf..8ee0f92 100644
--- a/src/plugins/http_static/http_static.h
+++ b/src/plugins/http_static/http_static.h
@@ -181,6 +181,9 @@
   /** Process node index for event scheduling */
   u32 node_index;
 
+  /** Cert and key pair for tls */
+  u32 ckpair_index;
+
   /** Session cleanup timer wheel */
   tw_timer_wheel_2t_1w_2048sl_t tw;
   clib_spinlock_t tw_lock;
diff --git a/src/plugins/http_static/static_server.c b/src/plugins/http_static/static_server.c
index 0ae6741..b354666 100644
--- a/src/plugins/http_static/static_server.c
+++ b/src/plugins/http_static/static_server.c
@@ -1140,8 +1140,7 @@
 static int
 http_static_server_attach ()
 {
-  vnet_app_add_tls_cert_args_t _a_cert, *a_cert = &_a_cert;
-  vnet_app_add_tls_key_args_t _a_key, *a_key = &_a_key;
+  vnet_app_add_cert_key_pair_args_t _ck_pair, *ck_pair = &_ck_pair;
   http_static_server_main_t *hsm = &http_static_server_main;
   u64 options[APP_OPTIONS_N_OPTIONS];
   vnet_app_attach_args_t _a, *a = &_a;
@@ -1175,17 +1174,13 @@
   vec_free (a->name);
   hsm->app_index = a->app_index;
 
-  clib_memset (a_cert, 0, sizeof (*a_cert));
-  a_cert->app_index = a->app_index;
-  vec_validate (a_cert->cert, test_srv_crt_rsa_len);
-  clib_memcpy_fast (a_cert->cert, test_srv_crt_rsa, test_srv_crt_rsa_len);
-  vnet_app_add_tls_cert (a_cert);
-
-  clib_memset (a_key, 0, sizeof (*a_key));
-  a_key->app_index = a->app_index;
-  vec_validate (a_key->key, test_srv_key_rsa_len);
-  clib_memcpy_fast (a_key->key, test_srv_key_rsa, test_srv_key_rsa_len);
-  vnet_app_add_tls_key (a_key);
+  clib_memset (ck_pair, 0, sizeof (*ck_pair));
+  ck_pair->cert = (u8 *) test_srv_crt_rsa;
+  ck_pair->key = (u8 *) test_srv_key_rsa;
+  ck_pair->cert_len = test_srv_crt_rsa_len;
+  ck_pair->key_len = test_srv_key_rsa_len;
+  vnet_app_add_cert_key_pair (ck_pair);
+  hsm->ckpair_index = ck_pair->index;
 
   return 0;
 }
@@ -1194,13 +1189,23 @@
 http_static_server_listen ()
 {
   http_static_server_main_t *hsm = &http_static_server_main;
+  session_endpoint_cfg_t sep = SESSION_ENDPOINT_CFG_NULL;
   vnet_listen_args_t _a, *a = &_a;
+  char *uri = "tcp://0.0.0.0/80";
+
   clib_memset (a, 0, sizeof (*a));
   a->app_index = hsm->app_index;
-  a->uri = "tcp://0.0.0.0/80";
+
   if (hsm->uri)
-    a->uri = (char *) hsm->uri;
-  return vnet_bind_uri (a);
+    uri = (char *) hsm->uri;
+
+  if (parse_uri (uri, &sep))
+    return -1;
+
+  clib_memcpy (&a->sep_ext, &sep, sizeof (sep));
+  a->sep_ext.ckpair_index = hsm->ckpair_index;
+
+  return vnet_listen (a);
 }
 
 static void
diff --git a/src/vcl/ldp.c b/src/vcl/ldp.c
index 98ed4a9..b72c0c5 100644
--- a/src/vcl/ldp.c
+++ b/src/vcl/ldp.c
@@ -100,10 +100,15 @@
   u32 vlsh_bit_val;
   u32 vlsh_bit_mask;
   u32 debug;
-  u8 transparent_tls;
 
   /** vcl needs next epoll_create to go to libc_epoll */
   u8 vcl_needs_real_epoll;
+
+  /**
+   * crypto state used only for testing
+   */
+  u8 transparent_tls;
+  u32 ckpair_index;
 } ldp_main_t;
 
 #define LDP_DEBUG ldp->debug
@@ -121,6 +126,7 @@
   .vlsh_bit_mask = (1 << LDP_SID_BIT_MIN) - 1,
   .debug = LDP_DEBUG_INIT,
   .transparent_tls = 0,
+  .ckpair_index = ~0,
 };
 
 static ldp_main_t *ldp = &ldp_main;
@@ -902,66 +908,69 @@
 /* If transparent TLS mode is turned on, then ldp will load key and cert.
  */
 static int
-load_tls_cert (vls_handle_t vlsh)
+load_cert_key_pair (void)
 {
-  char *env_var_str = getenv (LDP_ENV_TLS_CERT);
-  char inbuf[4096];
-  char *tls_cert;
-  int cert_size;
+  char *cert_str = getenv (LDP_ENV_TLS_CERT);
+  char *key_str = getenv (LDP_ENV_TLS_KEY);
+  char cert_buf[4096], key_buf[4096];
+  int cert_size, key_size;
+  vppcom_cert_key_pair_t crypto;
+  int ckp_index;
   FILE *fp;
 
-  if (env_var_str)
-    {
-      fp = fopen (env_var_str, "r");
-      if (fp == NULL)
-	{
-	  LDBG (0, "ERROR: failed to open cert file %s \n", env_var_str);
-	  return -1;
-	}
-      cert_size = fread (inbuf, sizeof (char), sizeof (inbuf), fp);
-      tls_cert = inbuf;
-      vppcom_session_tls_add_cert (vlsh_to_session_index (vlsh), tls_cert,
-				   cert_size);
-      fclose (fp);
-    }
-  else
+  if (!cert_str || !key_str)
     {
       LDBG (0, "ERROR: failed to read LDP environment %s\n",
 	    LDP_ENV_TLS_CERT);
       return -1;
     }
+
+  fp = fopen (cert_str, "r");
+  if (fp == NULL)
+    {
+      LDBG (0, "ERROR: failed to open cert file %s \n", cert_str);
+      return -1;
+    }
+  cert_size = fread (cert_buf, sizeof (char), sizeof (cert_buf), fp);
+  fclose (fp);
+
+  fp = fopen (key_str, "r");
+  if (fp == NULL)
+    {
+      LDBG (0, "ERROR: failed to open key file %s \n", key_str);
+      return -1;
+    }
+  key_size = fread (key_buf, sizeof (char), sizeof (key_buf), fp);
+  fclose (fp);
+
+  crypto.cert = cert_buf;
+  crypto.key = key_buf;
+  crypto.cert_len = cert_size;
+  crypto.key_len = key_size;
+  ckp_index = vppcom_add_cert_key_pair (&crypto);
+  if (ckp_index < 0)
+    {
+      LDBG (0, "ERROR: failed to add cert key pair\n");
+      return -1;
+    }
+
+  ldp->ckpair_index = ckp_index;
+
   return 0;
 }
 
 static int
-load_tls_key (vls_handle_t vlsh)
+assign_cert_key_pair (vls_handle_t vlsh)
 {
-  char *env_var_str = getenv (LDP_ENV_TLS_KEY);
-  char inbuf[4096];
-  char *tls_key;
-  int key_size;
-  FILE *fp;
+  uint32_t ckp_len;
 
-  if (env_var_str)
-    {
-      fp = fopen (env_var_str, "r");
-      if (fp == NULL)
-	{
-	  LDBG (0, "ERROR: failed to open key file %s \n", env_var_str);
-	  return -1;
-	}
-      key_size = fread (inbuf, sizeof (char), sizeof (inbuf), fp);
-      tls_key = inbuf;
-      vppcom_session_tls_add_key (vlsh_to_session_index (vlsh), tls_key,
-				  key_size);
-      fclose (fp);
-    }
-  else
-    {
-      LDBG (0, "ERROR: failed to read LDP environment %s\n", LDP_ENV_TLS_KEY);
-      return -1;
-    }
-  return 0;
+  if (ldp->ckpair_index == ~0 && load_cert_key_pair () < 0)
+    return -1;
+
+  ckp_len = sizeof (ldp->ckpair_index);
+  return vppcom_session_attr (vlsh_to_session_index (vlsh),
+			      VPPCOM_ATTR_SET_CKPAIR, &ldp->ckpair_index,
+			      &ckp_len);
 }
 
 int
@@ -999,10 +1008,8 @@
 	{
 	  if (ldp->transparent_tls)
 	    {
-	      if (load_tls_cert (vlsh) < 0 || load_tls_key (vlsh) < 0)
-		{
-		  return -1;
-		}
+	      if (assign_cert_key_pair (vlsh) < 0)
+		return -1;
 	    }
 	  rv = ldp_vlsh_to_fd (vlsh);
 	}
diff --git a/src/vcl/vcl_bapi.c b/src/vcl/vcl_bapi.c
index 8e24bfe..7d24162 100644
--- a/src/vcl/vcl_bapi.c
+++ b/src/vcl/vcl_bapi.c
@@ -244,41 +244,39 @@
 }
 
 static void
-  vl_api_application_tls_cert_add_reply_t_handler
-  (vl_api_application_tls_cert_add_reply_t * mp)
+vl_api_app_add_cert_key_pair_reply_t_handler (
+  vl_api_app_add_cert_key_pair_reply_t *mp)
 {
   vcl_worker_t *wrk = vcl_worker_get_current ();
 
   if (mp->retval)
     {
-      VDBG (0, "add cert failed: %U", format_api_error, ntohl (mp->retval));
-      wrk->bapi_app_state = STATE_APP_FAILED;
+      VDBG (0, "Adding cert and key failed: %U", format_api_error,
+	    ntohl (mp->retval));
       return;
     }
+  wrk->bapi_return = clib_net_to_host_u32 (mp->index);
   wrk->bapi_app_state = STATE_APP_READY;
 }
 
 static void
-  vl_api_application_tls_key_add_reply_t_handler
-  (vl_api_application_tls_key_add_reply_t * mp)
+vl_api_app_del_cert_key_pair_reply_t_handler (
+  vl_api_app_del_cert_key_pair_reply_t *mp)
 {
-  vcl_worker_t *wrk = vcl_worker_get_current ();
-
   if (mp->retval)
     {
-      VDBG (0, "add key failed: %U", format_api_error, ntohl (mp->retval));
-      wrk->bapi_app_state = STATE_APP_FAILED;
+      VDBG (0, "Deleting cert and key failed: %U", format_api_error,
+	    ntohl (mp->retval));
       return;
     }
-  wrk->bapi_app_state = STATE_APP_READY;
 }
 
-#define foreach_sock_msg                                        	\
-_(SESSION_ENABLE_DISABLE_REPLY, session_enable_disable_reply)   	\
-_(APP_ATTACH_REPLY, app_attach_reply)           			\
-_(APPLICATION_TLS_CERT_ADD_REPLY, application_tls_cert_add_reply)  	\
-_(APPLICATION_TLS_KEY_ADD_REPLY, application_tls_key_add_reply)  	\
-_(APP_WORKER_ADD_DEL_REPLY, app_worker_add_del_reply)			\
+#define foreach_sock_msg                                                      \
+  _ (SESSION_ENABLE_DISABLE_REPLY, session_enable_disable_reply)              \
+  _ (APP_ATTACH_REPLY, app_attach_reply)                                      \
+  _ (APP_ADD_CERT_KEY_PAIR_REPLY, app_add_cert_key_pair_reply)                \
+  _ (APP_DEL_CERT_KEY_PAIR_REPLY, app_del_cert_key_pair_reply)                \
+  _ (APP_WORKER_ADD_DEL_REPLY, app_worker_add_del_reply)
 
 static void
 vcl_bapi_hookup (void)
@@ -408,38 +406,41 @@
   vl_msg_api_send_shmem (wrk->vl_input_queue, (u8 *) & mp);
 }
 
-void
-vcl_bapi_send_application_tls_cert_add (vcl_session_t * session, char *cert,
-					u32 cert_len)
+static void
+vcl_bapi_send_app_add_cert_key_pair (vppcom_cert_key_pair_t *ckpair)
 {
   vcl_worker_t *wrk = vcl_worker_get_current ();
-  vl_api_application_tls_cert_add_t *cert_mp;
+  u32 cert_len = test_srv_crt_rsa_len;
+  u32 key_len = test_srv_key_rsa_len;
+  vl_api_app_add_cert_key_pair_t *bmp;
 
-  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->api_client_handle;
-  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);
+  bmp = vl_msg_api_alloc (sizeof (*bmp) + cert_len + key_len);
+  clib_memset (bmp, 0, sizeof (*bmp) + cert_len + key_len);
+
+  bmp->_vl_msg_id = ntohs (VL_API_APP_ADD_CERT_KEY_PAIR);
+  bmp->client_index = wrk->api_client_handle;
+  bmp->context = wrk->wrk_index;
+  bmp->cert_len = clib_host_to_net_u16 (cert_len);
+  bmp->certkey_len = clib_host_to_net_u16 (key_len + cert_len);
+  clib_memcpy_fast (bmp->certkey, test_srv_crt_rsa, cert_len);
+  clib_memcpy_fast (bmp->certkey + cert_len, test_srv_key_rsa, key_len);
+
+  vl_msg_api_send_shmem (wrk->vl_input_queue, (u8 *) &bmp);
 }
 
-void
-vcl_bapi_send_application_tls_key_add (vcl_session_t * session, char *key,
-				       u32 key_len)
+static void
+vcl_bapi_send_app_del_cert_key_pair (u32 ckpair_index)
 {
   vcl_worker_t *wrk = vcl_worker_get_current ();
-  vl_api_application_tls_key_add_t *key_mp;
+  vl_api_app_del_cert_key_pair_t *bmp;
+  bmp = vl_msg_api_alloc (sizeof (*bmp));
+  clib_memset (bmp, 0, sizeof (*bmp));
 
-  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->api_client_handle;
-  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);
+  bmp->_vl_msg_id = ntohs (VL_API_APP_DEL_CERT_KEY_PAIR);
+  bmp->client_index = wrk->api_client_handle;
+  bmp->context = wrk->wrk_index;
+  bmp->index = clib_host_to_net_u32 (ckpair_index);
+  vl_msg_api_send_shmem (wrk->vl_input_queue, (u8 *) &bmp);
 }
 
 u32
@@ -706,48 +707,27 @@
 }
 
 int
-vppcom_session_tls_add_cert (uint32_t session_handle, char *cert,
-			     uint32_t cert_len)
+vcl_bapi_add_cert_key_pair (vppcom_cert_key_pair_t *ckpair)
 {
-
   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 (ckpair->key_len == 0 || ckpair->key_len == ~0)
+    return VPPCOM_EINVAL;
 
-  if (cert_len == 0 || cert_len == ~0)
-    return VPPCOM_EBADFD;
-
-  /*
-   * Send listen request to vpp and wait for reply
-   */
-  vcl_bapi_send_application_tls_cert_add (session, cert, cert_len);
+  vcl_bapi_send_app_add_cert_key_pair (ckpair);
   wrk->bapi_app_state = STATE_APP_ADDING_TLS_DATA;
   vcl_bapi_wait_for_wrk_state_change (STATE_APP_READY);
-  return VPPCOM_OK;
+  if (wrk->bapi_app_state == STATE_APP_READY)
+    return wrk->bapi_return;
+  return VPPCOM_EFAULT;
 }
 
 int
-vppcom_session_tls_add_key (uint32_t session_handle, char *key,
-			    uint32_t key_len)
+vcl_bapi_del_cert_key_pair (u32 ckpair_index)
 {
-
-  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;
-
-  vcl_bapi_send_application_tls_key_add (session, key, key_len);
-  wrk->bapi_app_state = STATE_APP_ADDING_TLS_DATA;
-  vcl_bapi_wait_for_wrk_state_change (STATE_APP_READY);
-  return VPPCOM_OK;
+  /* Don't wait for reply */
+  vcl_bapi_send_app_del_cert_key_pair (ckpair_index);
+  return 0;
 }
 
 int
diff --git a/src/vcl/vcl_private.h b/src/vcl/vcl_private.h
index 0aa2fc1..7104adc 100644
--- a/src/vcl/vcl_private.h
+++ b/src/vcl/vcl_private.h
@@ -154,12 +154,13 @@
   vcl_session_msg_t *accept_evts_fifo;
 
   u64 vpp_handle;
+  u64 parent_handle;
   u32 listener_index;		/**< index of parent listener (if any) */
   int n_accepted_sessions;	/**< sessions accepted by this listener */
-  u32 attributes;		/**< see @ref vppcom_session_attr_t */
-  u64 parent_handle;
-  int libc_epfd;
   vppcom_epoll_t vep;
+  u32 attributes;		/**< see @ref vppcom_session_attr_t */
+  int libc_epfd;
+  u32 ckpair_index;
 
   u32 sndbuf_size;		// VPP-TBD: Hack until support setsockopt(SO_SNDBUF)
   u32 rcvbuf_size;		// VPP-TBD: Hack until support setsockopt(SO_RCVBUF)
@@ -287,6 +288,7 @@
 
   /* State of the connection, shared between msg RX thread and main thread */
   volatile vcl_bapi_app_state_t bapi_app_state;
+  volatile uword bapi_return;
 
   /** vcl needs next epoll_create to go to libc_epoll */
   u8 vcl_needs_real_epoll;
@@ -536,6 +538,13 @@
 }
 
 static inline u8
+vcl_session_has_crypto (vcl_session_t *s)
+{
+  return (s->session_type == VPPCOM_PROTO_TLS ||
+	  s->session_type == VPPCOM_PROTO_QUIC);
+}
+
+static inline u8
 vcl_session_is_ready (vcl_session_t * s)
 {
   return (s->session_state == VCL_STATE_READY
@@ -699,10 +708,8 @@
 void vcl_bapi_app_worker_del (vcl_worker_t * wrk);
 void vcl_bapi_disconnect_from_vpp (void);
 int vcl_bapi_recv_fds (vcl_worker_t * wrk, int *fds, int n_fds);
-void vcl_bapi_send_application_tls_cert_add (vcl_session_t * session,
-					     char *cert, u32 cert_len);
-void vcl_bapi_send_application_tls_key_add (vcl_session_t * session,
-					    char *key, u32 key_len);
+int vcl_bapi_add_cert_key_pair (vppcom_cert_key_pair_t *ckpair);
+int vcl_bapi_del_cert_key_pair (u32 ckpair_index);
 u32 vcl_bapi_max_nsid_len (void);
 int vcl_bapi_worker_set (void);
 
diff --git a/src/vcl/vppcom.c b/src/vcl/vppcom.c
index dbb2cd5..412b6a4 100644
--- a/src/vcl/vppcom.c
+++ b/src/vcl/vppcom.c
@@ -182,6 +182,7 @@
   clib_memcpy_fast (&mp->ip, &s->transport.lcl_ip, sizeof (mp->ip));
   mp->port = s->transport.lcl_port;
   mp->proto = s->session_type;
+  mp->ckpair_index = s->ckpair_index;
   if (s->flags & VCL_SESSION_F_CONNECTED)
     mp->flags = TRANSPORT_CFG_F_CONNECTED;
   app_send_ctrl_evt_to_vpp (mq, app_evt);
@@ -208,6 +209,7 @@
   mp->port = s->transport.rmt_port;
   mp->lcl_port = s->transport.lcl_port;
   mp->proto = s->session_type;
+  mp->ckpair_index = s->ckpair_index;
   if (s->flags & VCL_SESSION_F_CONNECTED)
     mp->flags |= TRANSPORT_CFG_F_CONNECTED;
   app_send_ctrl_evt_to_vpp (mq, app_evt);
@@ -1282,6 +1284,7 @@
   session->session_type = proto;
   session->session_state = VCL_STATE_CLOSED;
   session->vpp_handle = ~0;
+  session->ckpair_index = ~0;
   session->is_dgram = vcl_proto_is_dgram (proto);
 
   if (is_nonblocking)
@@ -3082,10 +3085,10 @@
 		     void *buffer, uint32_t * buflen)
 {
   vcl_worker_t *wrk = vcl_worker_get_current ();
-  vcl_session_t *session;
-  int rv = VPPCOM_OK;
   u32 *flags = buffer, tmp_flags = 0;
   vppcom_endpt_t *ep = buffer;
+  vcl_session_t *session;
+  int rv = VPPCOM_OK;
 
   session = vcl_session_get_w_handle (wrk, session_handle);
   if (!session)
@@ -3633,6 +3636,16 @@
       session->flags |= VCL_SESSION_F_CONNECTED;
       break;
 
+    case VPPCOM_ATTR_SET_CKPAIR:
+      if (!(buffer && buflen && (*buflen == sizeof (int))) ||
+	  !vcl_session_has_crypto (session))
+	{
+	  rv = VPPCOM_EINVAL;
+	  break;
+	}
+      session->ckpair_index = *(uint32_t *) buffer;
+      break;
+
     default:
       rv = VPPCOM_EINVAL;
       break;
@@ -4012,6 +4025,28 @@
   return st;
 }
 
+int
+vppcom_add_cert_key_pair (vppcom_cert_key_pair_t *ckpair)
+{
+  if (vcm->cfg.vpp_app_socket_api)
+    {
+      clib_warning ("not supported");
+      return VPPCOM_EINVAL;
+    }
+  return vcl_bapi_add_cert_key_pair (ckpair);
+}
+
+int
+vppcom_del_cert_key_pair (uint32_t ckpair_index)
+{
+  if (vcm->cfg.vpp_app_socket_api)
+    {
+      clib_warning ("not supported");
+      return VPPCOM_EINVAL;
+    }
+  return vcl_bapi_del_cert_key_pair (ckpair_index);
+}
+
 /*
  * fd.io coding-style-patch-verification: ON
  *
diff --git a/src/vcl/vppcom.h b/src/vcl/vppcom.h
index 0930300..77be806 100644
--- a/src/vcl/vppcom.h
+++ b/src/vcl/vppcom.h
@@ -71,6 +71,14 @@
 
 typedef uint32_t vcl_session_handle_t;
 
+typedef struct vppcom_cert_key_pair_
+{
+  char *cert;
+  char *key;
+  uint32_t cert_len;
+  uint32_t key_len;
+} vppcom_cert_key_pair_t;
+
 typedef enum
 {
   VPPCOM_OK = 0,
@@ -129,6 +137,7 @@
   VPPCOM_ATTR_SET_SHUT,
   VPPCOM_ATTR_GET_SHUT,
   VPPCOM_ATTR_SET_CONNECTED,
+  VPPCOM_ATTR_SET_CKPAIR,
 } vppcom_attr_op_t;
 
 typedef struct _vcl_poll
@@ -204,10 +213,8 @@
 					 uint32_t max_bytes);
 extern void vppcom_session_free_segments (uint32_t session_handle,
 					  uint32_t n_bytes);
-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_add_cert_key_pair (vppcom_cert_key_pair_t *ckpair);
+extern int vppcom_del_cert_key_pair (uint32_t ckpair_index);
 extern int vppcom_unformat_proto (uint8_t * proto, char *proto_str);
 extern int vppcom_session_is_connectable_listener (uint32_t session_handle);
 extern int vppcom_session_listener (uint32_t session_handle);
diff --git a/src/vnet/session/application.c b/src/vnet/session/application.c
index 20b0a9e..906a73e 100644
--- a/src/vnet/session/application.c
+++ b/src/vnet/session/application.c
@@ -1320,26 +1320,6 @@
   return &app->sm_properties;
 }
 
-clib_error_t *
-vnet_app_add_tls_cert (vnet_app_add_tls_cert_args_t * a)
-{
-  /* Deprected, will be remove after 20.01 */
-  app_cert_key_pair_t *ckpair;
-  ckpair = app_cert_key_pair_get_default ();
-  ckpair->cert = vec_dup (a->cert);
-  return 0;
-}
-
-clib_error_t *
-vnet_app_add_tls_key (vnet_app_add_tls_key_args_t * a)
-{
-  /* Deprected, will be remove after 20.01 */
-  app_cert_key_pair_t *ckpair;
-  ckpair = app_cert_key_pair_get_default ();
-  ckpair->key = vec_dup (a->key);
-  return 0;
-}
-
 static void
 application_format_listeners (application_t * app, int verbose)
 {
@@ -1706,8 +1686,10 @@
 vnet_app_add_cert_key_pair (vnet_app_add_cert_key_pair_args_t * a)
 {
   app_cert_key_pair_t *ckpair = app_cert_key_pair_alloc ();
-  ckpair->cert = vec_dup (a->cert);
-  ckpair->key = vec_dup (a->key);
+  vec_validate (ckpair->cert, a->cert_len - 1);
+  clib_memcpy_fast (ckpair->cert, a->cert, a->cert_len);
+  vec_validate (ckpair->key, a->key_len - 1);
+  clib_memcpy_fast (ckpair->key, a->key, a->key_len);
   a->index = ckpair->cert_key_index;
   return 0;
 }
@@ -1749,7 +1731,7 @@
 clib_error_t *
 application_init (vlib_main_t * vm)
 {
-  /* Add a certificate with index 0 to support legacy apis */
+  /* Index 0 was originally used by legacy apis, maintain as invalid */
   (void) app_cert_key_pair_alloc ();
   app_main.last_crypto_engine = CRYPTO_ENGINE_LAST;
   app_main.app_by_name = hash_create_vec (0, sizeof (u8), sizeof (uword));
diff --git a/src/vnet/session/application_interface.h b/src/vnet/session/application_interface.h
index 9614257..b2e0ef9 100644
--- a/src/vnet/session/application_interface.h
+++ b/src/vnet/session/application_interface.h
@@ -178,6 +178,8 @@
 {
   u8 *cert;
   u8 *key;
+  u32 cert_len;
+  u32 key_len;
   u32 index;
 } vnet_app_add_cert_key_pair_args_t;
 
@@ -271,8 +273,6 @@
 int vnet_unlisten (vnet_unlisten_args_t * a);
 int vnet_disconnect_session (vnet_disconnect_args_t * a);
 
-clib_error_t *vnet_app_add_tls_cert (vnet_app_add_tls_cert_args_t * a);
-clib_error_t *vnet_app_add_tls_key (vnet_app_add_tls_key_args_t * a);
 int vnet_app_add_cert_key_pair (vnet_app_add_cert_key_pair_args_t * a);
 int vnet_app_del_cert_key_pair (u32 index);
 /** Ask for app cb on pair deletion */
diff --git a/src/vnet/session/session.api b/src/vnet/session/session.api
index 091b876..53e2834 100644
--- a/src/vnet/session/session.api
+++ b/src/vnet/session/session.api
@@ -13,7 +13,7 @@
  * limitations under the License.
  */
 
-option version = "3.2.0";
+option version = "4.0.0";
 
 import "vnet/interface_types.api";
 import "vnet/ip/ip_types.api";
@@ -125,6 +125,7 @@
     @param cert - certificate as a string
 */
 autoreply define application_tls_cert_add {
+    option deprecated="to be removed post 21.06";
     u32 client_index;
     u32 context;
     u32 app_index;
@@ -140,6 +141,7 @@
     @param key - PEM encoded key as a string
 */
 autoreply define application_tls_key_add {
+    option deprecated="to be removed post 21.06";
     u32 client_index;
     u32 context;
     u32 app_index;
diff --git a/src/vnet/session/session_api.c b/src/vnet/session/session_api.c
index 2073a15..2e215f7 100644
--- a/src/vnet/session/session_api.c
+++ b/src/vnet/session/session_api.c
@@ -49,8 +49,6 @@
 _(APP_NAMESPACE_ADD_DEL, app_namespace_add_del)				\
 _(SESSION_RULE_ADD_DEL, session_rule_add_del)				\
 _(SESSION_RULES_DUMP, session_rules_dump)				\
-_(APPLICATION_TLS_CERT_ADD, application_tls_cert_add)			\
-_(APPLICATION_TLS_KEY_ADD, application_tls_key_add)			\
 _(APP_ADD_CERT_KEY_PAIR, app_add_cert_key_pair)				\
 _(APP_DEL_CERT_KEY_PAIR, app_del_cert_key_pair)				\
 _(APP_WORKER_ADD_DEL, app_worker_add_del)				\
@@ -1065,13 +1063,11 @@
     }
 
   clib_memset (a, 0, sizeof (*a));
-  vec_validate (a->cert, cert_len);
-  vec_validate (a->key, key_len);
-  clib_memcpy_fast (a->cert, mp->certkey, cert_len);
-  clib_memcpy_fast (a->key, mp->certkey + cert_len, key_len);
+  a->cert = mp->certkey;
+  a->key = mp->certkey + cert_len;
+  a->cert_len = cert_len;
+  a->key_len = key_len;
   rv = vnet_app_add_cert_key_pair (a);
-  vec_free (a->cert);
-  vec_free (a->key);
 
 done:
   /* *INDENT-OFF* */
@@ -1100,73 +1096,6 @@
   REPLY_MACRO (VL_API_APP_DEL_CERT_KEY_PAIR_REPLY);
 }
 
-/* ### WILL BE DEPRECATED POST 20.01 ### */
-static void
-vl_api_application_tls_cert_add_t_handler (vl_api_application_tls_cert_add_t *
-					   mp)
-{
-  vl_api_application_tls_cert_add_reply_t *rmp;
-  app_cert_key_pair_t *ckpair;
-  application_t *app;
-  u32 cert_len;
-  int rv = 0;
-  if (session_main_is_enabled () == 0)
-    {
-      rv = VNET_API_ERROR_FEATURE_DISABLED;
-      goto done;
-    }
-  if (!(app = application_lookup (mp->client_index)))
-    {
-      rv = VNET_API_ERROR_APPLICATION_NOT_ATTACHED;
-      goto done;
-    }
-  cert_len = clib_net_to_host_u16 (mp->cert_len);
-  if (cert_len > 10000)
-    {
-      rv = VNET_API_ERROR_INVALID_VALUE;
-      goto done;
-    }
-  ckpair = app_cert_key_pair_get_default ();
-  vec_validate (ckpair->cert, cert_len);
-  clib_memcpy_fast (ckpair->cert, mp->cert, cert_len);
-
-done:
-  REPLY_MACRO (VL_API_APPLICATION_TLS_CERT_ADD_REPLY);
-}
-
-/* ### WILL BE DEPRECATED POST 20.01 ### */
-static void
-vl_api_application_tls_key_add_t_handler (vl_api_application_tls_key_add_t *
-					  mp)
-{
-  vl_api_application_tls_key_add_reply_t *rmp;
-  app_cert_key_pair_t *ckpair;
-  application_t *app;
-  u32 key_len;
-  int rv = 0;
-  if (session_main_is_enabled () == 0)
-    {
-      rv = VNET_API_ERROR_FEATURE_DISABLED;
-      goto done;
-    }
-  if (!(app = application_lookup (mp->client_index)))
-    {
-      rv = VNET_API_ERROR_APPLICATION_NOT_ATTACHED;
-      goto done;
-    }
-  key_len = clib_net_to_host_u16 (mp->key_len);
-  if (key_len > 10000)
-    {
-      rv = VNET_API_ERROR_INVALID_VALUE;
-      goto done;
-    }
-  ckpair = app_cert_key_pair_get_default ();
-  vec_validate (ckpair->key, key_len);
-  clib_memcpy_fast (ckpair->key, mp->key, key_len);
-done:
-  REPLY_MACRO (VL_API_APPLICATION_TLS_KEY_ADD_REPLY);
-}
-
 static clib_error_t *
 application_reaper_cb (u32 client_index)
 {