aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPing Yu <ping.yu@intel.com>2019-08-19 07:01:17 -0400
committerPing Yu <ping.yu@intel.com>2019-08-20 13:36:17 +0000
commitbe4d1aa2c58efa8287bca8795bc4a83cb448993a (patch)
treec726b2c3ce5ee0e98f88aa8db1d16ce1d6b9ee32
parente71748291171e53158e2d36d8f413fed1a137013 (diff)
tls: Add C API for TLS openssl to set engine
Type: feature Parameters of the engine can be set by C API. After this patch, it is easier to integrate TLS into CSIT test. Change-Id: I063cabf613aabbfad831727551579328705afb41 Signed-off-by: Ping Yu <ping.yu@intel.com>
-rw-r--r--src/plugins/tlsopenssl/CMakeLists.txt11
-rw-r--r--src/plugins/tlsopenssl/tls_async.c10
-rw-r--r--src/plugins/tlsopenssl/tls_openssl.api31
-rw-r--r--src/plugins/tlsopenssl/tls_openssl.c13
-rw-r--r--src/plugins/tlsopenssl/tls_openssl.h5
-rw-r--r--src/plugins/tlsopenssl/tls_openssl_all_api_h.h18
-rw-r--r--src/plugins/tlsopenssl/tls_openssl_api.c128
-rw-r--r--src/plugins/tlsopenssl/tls_openssl_msg_enum.h30
-rw-r--r--src/plugins/tlsopenssl/tls_openssl_test.c200
9 files changed, 436 insertions, 10 deletions
diff --git a/src/plugins/tlsopenssl/CMakeLists.txt b/src/plugins/tlsopenssl/CMakeLists.txt
index ad34cfaa90d..07b587b4ca3 100644
--- a/src/plugins/tlsopenssl/CMakeLists.txt
+++ b/src/plugins/tlsopenssl/CMakeLists.txt
@@ -17,8 +17,19 @@ if(OPENSSL_FOUND)
add_vpp_plugin(tlsopenssl
SOURCES
tls_openssl.c
+ tls_openssl_api.c
tls_async.c
+ API_FILES
+ tls_openssl.api
+
+ INSTALL_HEADERS
+ tls_openssl_all_api_h.h
+ tls_openssl_msg_enum.h
+
+ API_TEST_SOURCES
+ tls_openssl_test.c
+
LINK_LIBRARIES
${OPENSSL_LIBRARIES}
)
diff --git a/src/plugins/tlsopenssl/tls_async.c b/src/plugins/tlsopenssl/tls_async.c
index ade073c66bc..e577f34eacf 100644
--- a/src/plugins/tlsopenssl/tls_async.c
+++ b/src/plugins/tlsopenssl/tls_async.c
@@ -143,7 +143,7 @@ openssl_engine_register (char *engine_name, char *algorithm)
if (registered < 0)
{
clib_error ("engine %s is not regisered in VPP", engine_name);
- return 0;
+ return -1;
}
ENGINE_load_builtin_engines ();
@@ -153,7 +153,7 @@ openssl_engine_register (char *engine_name, char *algorithm)
if (engine == NULL)
{
clib_warning ("Failed to find engine ENGINE_by_id %s", engine_name);
- return 0;
+ return -1;
}
om->engine = engine;
@@ -168,7 +168,7 @@ openssl_engine_register (char *engine_name, char *algorithm)
{
clib_warning ("Failed to set engine %s algorithm %s\n",
engine_name, algorithm);
- return 0;
+ return -1;
}
}
else
@@ -177,13 +177,13 @@ openssl_engine_register (char *engine_name, char *algorithm)
{
clib_warning ("Failed to set engine %s to all algorithm",
engine_name);
- return 0;
+ return -1;
}
}
om->start_polling = 1;
- return 1;
+ return 0;
}
diff --git a/src/plugins/tlsopenssl/tls_openssl.api b/src/plugins/tlsopenssl/tls_openssl.api
new file mode 100644
index 00000000000..7de77522c9c
--- /dev/null
+++ b/src/plugins/tlsopenssl/tls_openssl.api
@@ -0,0 +1,31 @@
+/* Define TLS OpenSSL binary API to control the feature */
+
+option version = "2.0.0";
+
+define tls_openssl_set_engine {
+ /* Client identifier, set from api_main.my_client_index */
+ u32 client_index;
+
+ /* Arbitrary context, so client can match reply to request */
+ u32 context;
+
+ /* if async is enabled */
+ u32 async;
+
+ /* engine name */
+ u8 engine[64];
+
+ /* algorithm */
+ u8 algorithm[64];
+
+ /* cipher */
+ u8 ciphers[64];
+};
+
+define tls_openssl_set_engine_reply {
+ /* From the request */
+ u32 context;
+
+ /* Return value, zero means all OK */
+ i32 retval;
+};
diff --git a/src/plugins/tlsopenssl/tls_openssl.c b/src/plugins/tlsopenssl/tls_openssl.c
index 8d0fd36a04f..589d76de860 100644
--- a/src/plugins/tlsopenssl/tls_openssl.c
+++ b/src/plugins/tlsopenssl/tls_openssl.c
@@ -16,6 +16,7 @@
#include <openssl/ssl.h>
#include <openssl/conf.h>
#include <openssl/err.h>
+
#ifdef HAVE_OPENSSL_ASYNC
#include <openssl/async.h>
#endif
@@ -26,9 +27,9 @@
#include <ctype.h>
#include <tlsopenssl/tls_openssl.h>
-#define MAX_CRYPTO_LEN 16
+#define MAX_CRYPTO_LEN 64
-static openssl_main_t openssl_main;
+openssl_main_t openssl_main;
static u32
openssl_ctx_alloc (void)
{
@@ -850,7 +851,7 @@ tls_init_ca_chain (void)
return (rv < 0 ? -1 : 0);
}
-static int
+int
tls_openssl_set_ciphers (char *ciphers)
{
openssl_main_t *om = &openssl_main;
@@ -876,8 +877,10 @@ tls_openssl_init (vlib_main_t * vm)
{
vlib_thread_main_t *vtm = vlib_get_thread_main ();
openssl_main_t *om = &openssl_main;
+ clib_error_t *error = 0;
u32 num_threads;
+ error = tls_openssl_api_init (vm);
num_threads = 1 /* main thread */ + vtm->n_threads;
SSL_library_init ();
@@ -899,7 +902,7 @@ tls_openssl_init (vlib_main_t * vm)
tls_openssl_set_ciphers
("ALL:!ADH:!LOW:!EXP:!MD5:!RC4-SHA:!DES-CBC3-SHA:@STRENGTH");
- return 0;
+ return error;
}
/* *INDENT-OFF* */
VLIB_INIT_FUNCTION (tls_openssl_init) =
@@ -961,7 +964,7 @@ tls_openssl_set_command_fn (vlib_main_t * vm, unformat_input_t * input,
}
else
{
- if (!openssl_engine_register (engine_name, engine_alg))
+ if (openssl_engine_register (engine_name, engine_alg) < 0)
{
return clib_error_return (0, "failed to register %s polling",
engine_name);
diff --git a/src/plugins/tlsopenssl/tls_openssl.h b/src/plugins/tlsopenssl/tls_openssl.h
index 66e0b364cba..e392b9ae4f2 100644
--- a/src/plugins/tlsopenssl/tls_openssl.h
+++ b/src/plugins/tlsopenssl/tls_openssl.h
@@ -45,6 +45,9 @@ typedef struct openssl_main_
openssl_ctx_t ***ctx_pool;
openssl_listen_ctx_t *lctx_pool;
+ /* API message ID base */
+ u16 msg_id_base;
+
X509_STORE *cert_store;
u8 *ciphers;
int engine_init;
@@ -69,6 +72,8 @@ int tls_async_openssl_callback (SSL * s, void *evt);
void openssl_polling_start (ENGINE * engine);
int openssl_engine_register (char *engine, char *alg);
void openssl_async_node_enable_disable (u8 is_en);
+clib_error_t *tls_openssl_api_init (vlib_main_t * vm);
+int tls_openssl_set_ciphers (char *ciphers);
/*
* fd.io coding-style-patch-verification: ON
diff --git a/src/plugins/tlsopenssl/tls_openssl_all_api_h.h b/src/plugins/tlsopenssl/tls_openssl_all_api_h.h
new file mode 100644
index 00000000000..96b63f2e1a4
--- /dev/null
+++ b/src/plugins/tlsopenssl/tls_openssl_all_api_h.h
@@ -0,0 +1,18 @@
+/*
+ * tls_openssl_all_api_h.h - skeleton vpp engine plug-in api #include file
+ *
+ * Copyright (c) 2019 Intel Corporation
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/* Include the generated file, see BUILT_SOURCES in Makefile.am */
+#include <tlsopenssl/tls_openssl.api.h>
diff --git a/src/plugins/tlsopenssl/tls_openssl_api.c b/src/plugins/tlsopenssl/tls_openssl_api.c
new file mode 100644
index 00000000000..9474aae2faf
--- /dev/null
+++ b/src/plugins/tlsopenssl/tls_openssl_api.c
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2018 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <vnet/vnet.h>
+#include <vlibapi/api.h>
+#include <vlibmemory/api.h>
+#include <vpp/app/version.h>
+#include <tlsopenssl/tls_openssl.h>
+
+/* define message IDs */
+#include <tlsopenssl/tls_openssl_msg_enum.h>
+
+/* define message structures */
+#define vl_typedefs
+#include <tlsopenssl/tls_openssl_all_api_h.h>
+#undef vl_typedefs
+
+/* define generated endian-swappers */
+#define vl_endianfun
+#include <tlsopenssl/tls_openssl_all_api_h.h>
+#undef vl_endianfun
+
+/* instantiate all the print functions we know about */
+#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
+#define vl_printfun
+#include <tlsopenssl/tls_openssl_all_api_h.h>
+#undef vl_printfun
+
+/* Get the API version number */
+#define vl_api_version(n, v) static u32 api_version = (v);
+#include <tlsopenssl/tls_openssl_all_api_h.h>
+#undef vl_api_version
+
+#define REPLY_MSG_ID_BASE om->msg_id_base
+#include <vlibapi/api_helper_macros.h>
+
+/* List of message types that this plugin understands */
+
+#define foreach_tls_openssl_plugin_api_msg \
+ _ (TLS_OPENSSL_SET_ENGINE, tls_openssl_set_engine)
+
+extern openssl_main_t openssl_main;
+
+/* API message handler */
+static void
+vl_api_tls_openssl_set_engine_t_handler (vl_api_tls_openssl_set_engine_t *mp)
+{
+ vl_api_tls_openssl_set_engine_reply_t *rmp;
+ openssl_main_t *om = &openssl_main;
+ char *engine, *alg, *ciphers;
+ int rv;
+
+ engine = (char *)&mp->engine;
+ alg = (char *)&mp->algorithm;
+ ciphers = (char *)&mp->ciphers;
+
+ if (mp->async)
+ {
+ om->async = 1;
+ openssl_async_node_enable_disable (1);
+ }
+
+ if (ciphers[0])
+ tls_openssl_set_ciphers (ciphers);
+ rv = openssl_engine_register (engine, alg);
+
+ REPLY_MACRO (VL_API_TLS_OPENSSL_SET_ENGINE_REPLY);
+}
+
+/* Set up the API message handling tables */
+static clib_error_t *tls_openssl_plugin_api_hookup (vlib_main_t *vm)
+{
+ openssl_main_t *om = &openssl_main;
+#define _(N, n) \
+ vl_msg_api_set_handlers ((VL_API_##N + om->msg_id_base), #n, \
+ vl_api_##n##_t_handler, vl_noop_handler, \
+ vl_api_##n##_t_endian, vl_api_##n##_t_print, \
+ sizeof (vl_api_##n##_t), 1);
+ foreach_tls_openssl_plugin_api_msg;
+#undef _
+
+ return 0;
+}
+
+#define vl_msg_name_crc_list
+#include <tlsopenssl/tls_openssl_all_api_h.h>
+#undef vl_msg_name_crc_list
+
+static void setup_message_id_table (openssl_main_t *om, api_main_t *am)
+{
+#define _(id, n, crc) \
+ vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id + om->msg_id_base);
+ foreach_vl_msg_name_crc_tls_openssl;
+#undef _
+}
+
+clib_error_t *tls_openssl_api_init (vlib_main_t *vm)
+{
+ openssl_main_t *om = &openssl_main;
+ clib_error_t *error = 0;
+ u8 *name;
+
+ name = format (0, "tls_openssl_%08x%c", api_version, 0);
+
+ /* Ask for a correctly-sized block of API message decode slots */
+ om->msg_id_base =
+ vl_msg_api_get_msg_ids ((char *)name, VL_MSG_FIRST_AVAILABLE);
+
+ error = tls_openssl_plugin_api_hookup (vm);
+
+ /* Add our API messages to the global name_crc hash table */
+ setup_message_id_table (om, &api_main);
+ vec_free (name);
+
+ return error;
+}
diff --git a/src/plugins/tlsopenssl/tls_openssl_msg_enum.h b/src/plugins/tlsopenssl/tls_openssl_msg_enum.h
new file mode 100644
index 00000000000..d1f74d0b4dd
--- /dev/null
+++ b/src/plugins/tlsopenssl/tls_openssl_msg_enum.h
@@ -0,0 +1,30 @@
+/*
+ * tlsopenssl_msg_enum.h - skeleton vpp engine plug-in message enumeration
+ *
+ * Copyright (c) 2019 Intel Corportation
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef included_tlsopenssl_msg_enum_h
+#define included_tlsopenssl_msg_enum_h
+
+#include <vppinfra/byte_order.h>
+
+#define vl_msg_id(n,h) n,
+typedef enum {
+#include <tlsopenssl/tls_openssl_all_api_h.h>
+ /* We'll want to know how many messages IDs we need... */
+ VL_MSG_FIRST_AVAILABLE,
+} vl_msg_id_t;
+#undef vl_msg_id
+
+#endif /* included_tlsopenssl_msg_enum_h*/
diff --git a/src/plugins/tlsopenssl/tls_openssl_test.c b/src/plugins/tlsopenssl/tls_openssl_test.c
new file mode 100644
index 00000000000..1c810c9a7f8
--- /dev/null
+++ b/src/plugins/tlsopenssl/tls_openssl_test.c
@@ -0,0 +1,200 @@
+/*
+ * tls_openssl_test.c - skeleton vpp-api-test plug-in
+ *
+ * Copyright (c) 2019 Intel Corporation
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <vat/vat.h>
+#include <vlibapi/api.h>
+#include <vlibmemory/api.h>
+#include <vppinfra/error.h>
+#include <ctype.h>
+
+uword unformat_sw_if_index (unformat_input_t * input, va_list * args);
+
+/* Declare message IDs */
+#include <tlsopenssl/tls_openssl_msg_enum.h>
+
+/* define message structures */
+#define vl_typedefs
+#include <tlsopenssl/tls_openssl_all_api_h.h>
+#undef vl_typedefs
+
+/* declare message handlers for each api */
+
+#define vl_endianfun /* define message structures */
+#include <tlsopenssl/tls_openssl_all_api_h.h>
+#undef vl_endianfun
+
+/* instantiate all the print functions we know about */
+#define vl_print(handle, ...)
+#define vl_printfun
+#include <tlsopenssl/tls_openssl_all_api_h.h>
+#undef vl_printfun
+
+/* Get the API version number. */
+#define vl_api_version(n,v) static u32 api_version=(v);
+#include <tlsopenssl/tls_openssl_all_api_h.h>
+#undef vl_api_version
+
+typedef struct
+{
+ /* API message ID base */
+ u16 msg_id_base;
+ vat_main_t *vat_main;
+} tls_openssl_test_main_t;
+
+tls_openssl_test_main_t tls_openssl_test_main;
+
+#define __plugin_msg_base tls_openssl_test_main.msg_id_base
+#include <vlibapi/vat_helper_macros.h>
+
+#define foreach_standard_reply_retval_handler \
+_(tls_openssl_set_engine_reply)
+
+#define _(n) \
+ static void vl_api_##n##_t_handler \
+ (vl_api_##n##_t * mp) \
+ { \
+ vat_main_t * vam = tls_openssl_test_main.vat_main; \
+ i32 retval = ntohl(mp->retval); \
+ if (vam->async_mode) { \
+ vam->async_errors += (retval < 0); \
+ } else { \
+ vam->retval = retval; \
+ vam->result_ready = 1; \
+ } \
+ }
+foreach_standard_reply_retval_handler;
+#undef _
+
+/*
+ * Table of message reply handlers, must include boilerplate handlers
+ * we just generated
+ */
+#define foreach_vpe_api_reply_msg \
+_(TLS_OPENSSL_SET_ENGINE_REPLY, tls_openssl_set_engine_reply)
+
+
+static int
+api_tls_openssl_set_engine (vat_main_t * vam)
+{
+ unformat_input_t *line_input = vam->input;
+ vl_api_tls_openssl_set_engine_t *mp;
+ u8 *engine_name = 0;
+ u8 *engine_alg = 0;
+ u8 *ciphers = 0;
+ u32 async = 0;
+ int ret;
+
+ /* Parse args required to build the message */
+ while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (line_input, "engine %s", &engine_name))
+ ;
+ else if (unformat (line_input, "async"))
+ {
+ async = 1;
+ }
+ else if (unformat (line_input, "alg %s", &engine_alg))
+ ;
+ else if (unformat (line_input, "ciphers %s", &ciphers))
+ ;
+ else
+ {
+ errmsg ("unknown input `%U'", format_unformat_error, line_input);
+ return -99;
+ }
+ }
+
+ if (engine_name == 0)
+ {
+ errmsg ("Must specify engine name");
+ return -99;
+ }
+
+ if (engine_alg == 0)
+ engine_alg = format (0, "ALL");
+ else
+ {
+ for (int i = 0; i < strnlen ((char *) engine_alg, 64); i++)
+ engine_alg[i] = toupper (engine_alg[i]);
+ }
+
+
+ /* Construct the API message */
+ M (TLS_OPENSSL_SET_ENGINE, mp);
+ mp->async = async;
+
+ clib_memcpy_fast (mp->engine, engine_name,
+ strnlen ((const char *) engine_name, 64));
+
+ clib_memcpy_fast (mp->algorithm, engine_alg,
+ strnlen ((const char *) engine_alg, 64));
+
+ if (ciphers)
+ clib_memcpy_fast (mp->ciphers, ciphers,
+ strnlen ((const char *) ciphers, 64));
+
+ /* send it... */
+ S (mp);
+
+ /* Wait for a reply... */
+ W (ret);
+ return ret;
+}
+
+/*
+ * List of messages that the api test plugin sends,
+ * and that the data plane plugin processes
+ */
+#define foreach_vpe_api_msg \
+_(tls_openssl_set_engine, "tls openssl set [engine <engine name>]" \
+"[alg [algorithm] [async]\n")
+
+static void
+tls_openssl_api_hookup (vat_main_t * vam)
+{
+ tls_openssl_test_main_t *htmp = &tls_openssl_test_main;
+ /* Hook up handlers for replies from the data plane plug-in */
+#define _(N,n) \
+ vl_msg_api_set_handlers((VL_API_##N + htmp->msg_id_base), \
+ #n, \
+ vl_api_##n##_t_handler, \
+ vl_noop_handler, \
+ vl_api_##n##_t_endian, \
+ vl_api_##n##_t_print, \
+ sizeof(vl_api_##n##_t), 1);
+ foreach_vpe_api_reply_msg;
+#undef _
+
+ /* API messages we can send */
+#define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
+ foreach_vpe_api_msg;
+#undef _
+
+ /* Help strings */
+#define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
+ foreach_vpe_api_msg;
+#undef _
+}
+
+VAT_PLUGIN_REGISTER (tls_openssl);
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */