From 6212597bdadd4425371db4cc6e71c03abd026634 Mon Sep 17 00:00:00 2001 From: Boris Glimcher Date: Fri, 22 Jul 2022 17:27:45 +0300 Subject: [PATCH] sock/ssl: Add psk_key and psk_identity options to spdk_sock_impl_opts Note, this change only sets defaults for the ID/KEY, more specific use cases like NVMe/TCP may set the ID and KEY on a per connection basis. Also simplify PSK identity string, that isn't NVMe focused. NVMe libraries using this will need to construct more complicated identity strings and pass them to the sock layer. Example: rpc.py sock_impl_set_options -i ssl --psk-key 4321DEADBEEF1234 rpc.py sock_impl_set_options -i ssl --psk-identity psk.spdk.io ./build/examples/perf --psk-key 4321DEADBEEF1234 --psk-identity psk.spdk.io ./build/examples/hello_sock --psk-key 4321DEADBEEF1234 --psk-identity psk.spdk.io Change-Id: I1cb5b0b706bdeafbccbc71f8320bc8e2961cbb55 Signed-off-by: Boris Glimcher Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/13759 Reviewed-by: Jim Harris Reviewed-by: Ben Walker Reviewed-by: Paul Luse Tested-by: SPDK CI Jenkins Community-CI: Mellanox Build Bot --- CHANGELOG.md | 1 + doc/jsonrpc.md | 10 ++++- examples/nvme/perf/perf.c | 59 +++++++++++++++++++++++--- examples/sock/hello_world/hello_sock.c | 20 ++++++++- include/spdk/sock.h | 10 +++++ lib/sock/sock.c | 6 +++ lib/sock/sock_rpc.c | 14 ++++++ module/sock/posix/posix.c | 41 +++++++++++------- module/sock/uring/uring.c | 6 ++- python/spdk/rpc/sock.py | 10 ++++- scripts/rpc.py | 8 +++- test/iscsi_tgt/sock/sock.sh | 28 +++++++----- test/nvmf/target/tls.sh | 32 +++++++++++++- 13 files changed, 205 insertions(+), 40 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 67193b708..fd6b4a333 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ Calculate num_md_pages from num_md_pages_per_cluster_ratio, and pass it to spdk_ ### rpc New options `enable_ktls` and `tls_version` were added to the `sock_impl_set_options` structure. +New options `psk_key` and `psk_identity` were added to the `sock_impl_set_options` structure. Added warning message for `bdev_rbd_create`, if it is used without -c. `bdev_rbd_create()` API without specifying -c is deprecated and will be removed in future release. diff --git a/doc/jsonrpc.md b/doc/jsonrpc.md index 4a02a5ec8..84ecb4ff5 100644 --- a/doc/jsonrpc.md +++ b/doc/jsonrpc.md @@ -9743,7 +9743,9 @@ Example response: "enable_zerocopy_send_client": false, "zerocopy_threshold": 0, "tls_version": 13, - "enable_ktls": false + "enable_ktls": false, + "psk_key": "1234567890ABCDEF", + "psk_identity": "psk.spdk.io" } } ~~~ @@ -9768,6 +9770,8 @@ zerocopy_threshold | Optional | number | Set zerocopy_threshold in -- | -- | -- | that fall below this threshold may be sent without zerocopy flag set tls_version | Optional | number | TLS protocol version, e.g. 13 for v1.3 (only applies when impl_name == ssl) enable_ktls | Optional | boolean | Enable or disable Kernel TLS (only applies when impl_name == ssl) +psk_key | Optional | string | Default PSK KEY in hexadecimal digits, e.g. 1234567890ABCDEF (only applies when impl_name == ssl) +psk_identity | Optional | string | Default PSK ID, e.g. psk.spdk.io (only applies when impl_name == ssl) #### Response @@ -9793,7 +9797,9 @@ Example request: "enable_zerocopy_send_client": false, "zerocopy_threshold": 10240, "tls_version": 13, - "enable_ktls": false + "enable_ktls": false, + "psk_key": "1234567890ABCDEF", + "psk_identity": "psk.spdk.io" } } ~~~ diff --git a/examples/nvme/perf/perf.c b/examples/nvme/perf/perf.c index d18ffee1e..732d2618d 100644 --- a/examples/nvme/perf/perf.c +++ b/examples/nvme/perf/perf.c @@ -291,7 +291,7 @@ static int g_file_optind; /* Index of first filename in argv */ static inline void task_complete(struct perf_task *task); static void -perf_set_sock_opts(const char *impl_name, const char *field, uint32_t val) +perf_set_sock_opts(const char *impl_name, const char *field, uint32_t val, const char *valstr) { struct spdk_sock_impl_opts sock_opts = {}; size_t opts_size = sizeof(sock_opts); @@ -323,6 +323,26 @@ perf_set_sock_opts(const char *impl_name, const char *field, uint32_t val) sock_opts.tls_version = val; } else if (strcmp(field, "ktls") == 0) { sock_opts.enable_ktls = val; + } else if (strcmp(field, "psk_key") == 0) { + if (!valstr) { + fprintf(stderr, "No socket opts value specified\n"); + return; + } + sock_opts.psk_key = strdup(valstr); + if (sock_opts.psk_key == NULL) { + fprintf(stderr, "Failed to allocate psk_key in sock_impl\n"); + return; + } + } else if (strcmp(field, "psk_identity") == 0) { + if (!valstr) { + fprintf(stderr, "No socket opts value specified\n"); + return; + } + sock_opts.psk_identity = strdup(valstr); + if (sock_opts.psk_identity == NULL) { + fprintf(stderr, "Failed to allocate psk_identity in sock_impl\n"); + return; + } } else { fprintf(stderr, "Warning: invalid or unprocessed socket opts field: %s\n", field); return; @@ -1790,6 +1810,8 @@ usage(char *program_name) printf("\t[--disable-ktls disable Kernel TLS. Only valid for ssl impl. Default for ssl impl]\n"); printf("\t[--enable-ktls enable Kernel TLS. Only valid for ssl impl]\n"); printf("\t[--tls-version TLS version to use. Only valid for ssl impl. Default: 0 (auto-negotiation)]\n"); + printf("\t[--psk-key Default PSK KEY in hexadecimal digits, e.g. 1234567890ABCDEF (only applies when sock_impl == ssl)]\n"); + printf("\t[--psk-identity Default PSK ID, e.g. psk.spdk.io (only applies when sock_impl == ssl)]\n"); } static void @@ -2288,6 +2310,10 @@ static const struct option g_perf_cmdline_opts[] = { {"enable-ktls", no_argument, NULL, PERF_ENABLE_KTLS}, #define PERF_TLS_VERSION 262 {"tls-version", required_argument, NULL, PERF_TLS_VERSION}, +#define PERF_PSK_KEY 263 + {"psk-key", required_argument, NULL, PERF_PSK_KEY}, +#define PERF_PSK_IDENTITY 264 + {"psk-identity ", required_argument, NULL, PERF_PSK_IDENTITY}, /* Should be the last element */ {0, 0, 0, 0} }; @@ -2299,6 +2325,8 @@ parse_args(int argc, char **argv, struct spdk_env_opts *env_opts) long int val; int rc; char *endptr; + bool ssl_used = false; + char *sock_impl = "posix"; while ((op = getopt_long(argc, argv, PERF_GETOPT_SHORT, g_perf_cmdline_opts, &long_idx)) != -1) { switch (op) { @@ -2469,26 +2497,38 @@ parse_args(int argc, char **argv, struct spdk_env_opts *env_opts) g_vmd = true; break; case PERF_DISABLE_KTLS: - perf_set_sock_opts(optarg, "ktls", 0); + ssl_used = true; + perf_set_sock_opts("ssl", "ktls", 0, NULL); break; case PERF_ENABLE_KTLS: - perf_set_sock_opts(optarg, "ktls", 1); + ssl_used = true; + perf_set_sock_opts("ssl", "ktls", 1, NULL); break; case PERF_TLS_VERSION: + ssl_used = true; val = spdk_strtol(optarg, 10); if (val < 0) { fprintf(stderr, "Illegal tls version value %s\n", optarg); return val; } - perf_set_sock_opts(optarg, "tls_version", val); + perf_set_sock_opts("ssl", "tls_version", val, NULL); + break; + case PERF_PSK_KEY: + ssl_used = true; + perf_set_sock_opts("ssl", "psk_key", 0, optarg); + break; + case PERF_PSK_IDENTITY: + ssl_used = true; + perf_set_sock_opts("ssl", "psk_identity", 0, optarg); break; case PERF_DISABLE_ZCOPY: - perf_set_sock_opts(optarg, "enable_zerocopy_send_client", 0); + perf_set_sock_opts(optarg, "enable_zerocopy_send_client", 0, NULL); break; case PERF_ENABLE_ZCOPY: - perf_set_sock_opts(optarg, "enable_zerocopy_send_client", 1); + perf_set_sock_opts(optarg, "enable_zerocopy_send_client", 1, NULL); break; case PERF_DEFAULT_SOCK_IMPL: + sock_impl = optarg; rc = spdk_sock_set_default_impl(optarg); if (rc) { fprintf(stderr, "Failed to set sock impl %s, err %d (%s)\n", optarg, errno, strerror(errno)); @@ -2547,6 +2587,13 @@ parse_args(int argc, char **argv, struct spdk_env_opts *env_opts) g_workload_type = &g_workload_type[4]; } + if (ssl_used && strncmp(sock_impl, "ssl", 3) != 0) { + fprintf(stderr, "sock impl is not SSL but tried to use one of the SSL only options\n"); + usage(argv[0]); + return 1; + } + + if (strcmp(g_workload_type, "read") == 0 || strcmp(g_workload_type, "write") == 0) { g_rw_percentage = strcmp(g_workload_type, "read") == 0 ? 100 : 0; if (g_mix_specified) { diff --git a/examples/sock/hello_world/hello_sock.c b/examples/sock/hello_world/hello_sock.c index 3b21ab46d..23672ca23 100644 --- a/examples/sock/hello_world/hello_sock.c +++ b/examples/sock/hello_world/hello_sock.c @@ -27,6 +27,8 @@ static int g_zcopy; static int g_ktls; static int g_tls_version; static bool g_verbose; +static char *g_psk_key; +static char *g_psk_identity; /* * We'll use this struct to gather housekeeping hello_context to pass between @@ -40,6 +42,8 @@ struct hello_context_t { int zcopy; int ktls; int tls_version; + char *psk_key; + char *psk_identity; bool verbose; int bytes_in; @@ -61,7 +65,9 @@ struct hello_context_t { static void hello_sock_usage(void) { + printf(" -E psk_key Default PSK KEY in hexadecimal digits, e.g. 1234567890ABCDEF (only applies when sock_impl == ssl)\n"); printf(" -H host_addr host address\n"); + printf(" -I psk_id Default PSK ID, e.g. psk.spdk.io (only applies when sock_impl == ssl)\n"); printf(" -P port port number\n"); printf(" -N sock_impl socket implementation, e.g., -N posix or -N uring\n"); printf(" -S start in server mode\n"); @@ -80,9 +86,15 @@ static int hello_sock_parse_arg(int ch, char *arg) { switch (ch) { + case 'E': + g_psk_key = arg; + break; case 'H': g_host = arg; break; + case 'I': + g_psk_identity = arg; + break; case 'N': g_sock_impl_name = arg; break; @@ -225,6 +237,8 @@ hello_sock_connect(struct hello_context_t *ctx) spdk_sock_impl_get_opts(ctx->sock_impl_name, &impl_opts, &impl_opts_size); impl_opts.enable_ktls = ctx->ktls; impl_opts.tls_version = ctx->tls_version; + impl_opts.psk_key = ctx->psk_key; + impl_opts.psk_identity = ctx->psk_identity; opts.opts_size = sizeof(opts); spdk_sock_get_default_opts(&opts); @@ -369,6 +383,8 @@ hello_sock_listen(struct hello_context_t *ctx) spdk_sock_impl_get_opts(ctx->sock_impl_name, &impl_opts, &impl_opts_size); impl_opts.enable_ktls = ctx->ktls; impl_opts.tls_version = ctx->tls_version; + impl_opts.psk_key = ctx->psk_key; + impl_opts.psk_identity = ctx->psk_identity; opts.opts_size = sizeof(opts); spdk_sock_get_default_opts(&opts); @@ -443,7 +459,7 @@ main(int argc, char **argv) opts.name = "hello_sock"; opts.shutdown_cb = hello_sock_shutdown_cb; - if ((rc = spdk_app_parse_args(argc, argv, &opts, "H:kKN:P:ST:VzZ", NULL, hello_sock_parse_arg, + if ((rc = spdk_app_parse_args(argc, argv, &opts, "E:H:I:kKN:P:ST:VzZ", NULL, hello_sock_parse_arg, hello_sock_usage)) != SPDK_APP_PARSE_ARGS_SUCCESS) { exit(rc); } @@ -454,6 +470,8 @@ main(int argc, char **argv) hello_context.zcopy = g_zcopy; hello_context.ktls = g_ktls; hello_context.tls_version = g_tls_version; + hello_context.psk_key = g_psk_key; + hello_context.psk_identity = g_psk_identity; hello_context.verbose = g_verbose; rc = spdk_app_start(&opts, hello_start, &hello_context); diff --git a/include/spdk/sock.h b/include/spdk/sock.h index af8b4a4eb..5ac3bf0ff 100644 --- a/include/spdk/sock.h +++ b/include/spdk/sock.h @@ -138,6 +138,16 @@ struct spdk_sock_impl_opts { * Enable or disable kernel TLS. Used by ssl socket modules. */ bool enable_ktls; + + /** + * Set default PSK key. Used by ssl socket module. + */ + char *psk_key; + + /** + * Set default PSK identity. Used by ssl socket module. + */ + char *psk_identity; }; /** diff --git a/lib/sock/sock.c b/lib/sock/sock.c index 73d4ad848..ef7479fac 100644 --- a/lib/sock/sock.c +++ b/lib/sock/sock.c @@ -867,6 +867,12 @@ spdk_sock_write_config_json(struct spdk_json_write_ctx *w) spdk_json_write_named_uint32(w, "zerocopy_threshold", opts.zerocopy_threshold); spdk_json_write_named_uint32(w, "tls_version", opts.tls_version); spdk_json_write_named_bool(w, "enable_ktls", opts.enable_ktls); + if (opts.psk_key) { + spdk_json_write_named_string(w, "psk_key", opts.psk_key); + } + if (opts.psk_identity) { + spdk_json_write_named_string(w, "psk_identity", opts.psk_identity); + } spdk_json_write_object_end(w); spdk_json_write_object_end(w); } else { diff --git a/lib/sock/sock_rpc.c b/lib/sock/sock_rpc.c index 966cf8ffa..a182074d8 100644 --- a/lib/sock/sock_rpc.c +++ b/lib/sock/sock_rpc.c @@ -54,6 +54,12 @@ rpc_sock_impl_get_options(struct spdk_jsonrpc_request *request, spdk_json_write_named_uint32(w, "zerocopy_threshold", sock_opts.zerocopy_threshold); spdk_json_write_named_uint32(w, "tls_version", sock_opts.tls_version); spdk_json_write_named_bool(w, "enable_ktls", sock_opts.enable_ktls); + if (sock_opts.psk_key) { + spdk_json_write_named_string(w, "psk_key", sock_opts.psk_key); + } + if (sock_opts.psk_identity) { + spdk_json_write_named_string(w, "psk_identity", sock_opts.psk_identity); + } spdk_json_write_object_end(w); spdk_jsonrpc_end_result(request, w); free(impl_name); @@ -110,6 +116,14 @@ static const struct spdk_json_object_decoder rpc_sock_impl_set_opts_decoders[] = { "enable_ktls", offsetof(struct spdk_rpc_sock_impl_set_opts, sock_opts.enable_ktls), spdk_json_decode_bool, true + }, + { + "psk_key", offsetof(struct spdk_rpc_sock_impl_set_opts, sock_opts.psk_key), + spdk_json_decode_string, true + }, + { + "psk_identity", offsetof(struct spdk_rpc_sock_impl_set_opts, sock_opts.psk_identity), + spdk_json_decode_string, true } }; diff --git a/module/sock/posix/posix.c b/module/sock/posix/posix.c index 1147d96da..3ae62988d 100644 --- a/module/sock/posix/posix.c +++ b/module/sock/posix/posix.c @@ -78,7 +78,9 @@ static struct spdk_sock_impl_opts g_spdk_posix_sock_impl_opts = { .enable_zerocopy_send_client = false, .zerocopy_threshold = 0, .tls_version = 0, - .enable_ktls = false + .enable_ktls = false, + .psk_key = NULL, + .psk_identity = NULL }; static struct spdk_sock_map g_map = { @@ -118,6 +120,8 @@ posix_sock_copy_impl_opts(struct spdk_sock_impl_opts *dest, const struct spdk_so SET_FIELD(zerocopy_threshold); SET_FIELD(tls_version); SET_FIELD(enable_ktls); + SET_FIELD(psk_key); + SET_FIELD(psk_identity); #undef SET_FIELD #undef FIELD_OK @@ -498,9 +502,6 @@ posix_fd_create(struct addrinfo *res, struct spdk_sock_opts *opts, return fd; } -#define PSK_ID "nqn.2014-08.org.nvmexpress:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6" -#define PSK_KEY "1234567890ABCDEF" - static unsigned int posix_sock_tls_psk_server_cb(SSL *ssl, const char *id, @@ -509,24 +510,27 @@ posix_sock_tls_psk_server_cb(SSL *ssl, { long key_len; unsigned char *default_psk; + struct spdk_sock_impl_opts *impl_opts; - if (PSK_KEY == NULL) { + impl_opts = SSL_get_app_data(ssl); + + if (impl_opts->psk_key == NULL) { SPDK_ERRLOG("PSK is not set\n"); goto err; } - SPDK_DEBUGLOG(sock_posix, "Length of Client's PSK ID %lu\n", strlen(PSK_ID)); + SPDK_DEBUGLOG(sock_posix, "Length of Client's PSK ID %lu\n", strlen(impl_opts->psk_identity)); if (id == NULL) { SPDK_ERRLOG("Received empty PSK ID\n"); goto err; } SPDK_DEBUGLOG(sock_posix, "Received PSK ID '%s'\n", id); - if (strcmp(PSK_ID, id) != 0) { + if (strcmp(impl_opts->psk_identity, id) != 0) { SPDK_ERRLOG("Unknown Client's PSK ID\n"); goto err; } SPDK_DEBUGLOG(sock_posix, "Length of Client's PSK KEY %u\n", max_psk_len); - default_psk = OPENSSL_hexstr2buf(PSK_KEY, &key_len); + default_psk = OPENSSL_hexstr2buf(impl_opts->psk_key, &key_len); if (default_psk == NULL) { SPDK_ERRLOG("Could not unhexlify PSK\n"); goto err; @@ -553,26 +557,29 @@ posix_sock_tls_psk_client_cb(SSL *ssl, const char *hint, { long key_len; unsigned char *default_psk; + struct spdk_sock_impl_opts *impl_opts; + + impl_opts = SSL_get_app_data(ssl); if (hint) { SPDK_DEBUGLOG(sock_posix, "Received PSK identity hint '%s'\n", hint); } - if (PSK_KEY == NULL) { + if (impl_opts->psk_key == NULL) { SPDK_ERRLOG("PSK is not set\n"); goto err; } - default_psk = OPENSSL_hexstr2buf(PSK_KEY, &key_len); + default_psk = OPENSSL_hexstr2buf(impl_opts->psk_key, &key_len); if (default_psk == NULL) { SPDK_ERRLOG("Could not unhexlify PSK\n"); goto err; } - if ((strlen(PSK_ID) + 1 > max_identity_len) + if ((strlen(impl_opts->psk_identity) + 1 > max_identity_len) || (key_len > max_psk_len)) { SPDK_ERRLOG("PSK ID or Key buffer is not sufficient\n"); goto err; } - spdk_strcpy_pad(identity, PSK_ID, strlen(PSK_ID), 0); + spdk_strcpy_pad(identity, impl_opts->psk_identity, strlen(impl_opts->psk_identity), 0); SPDK_DEBUGLOG(sock_posix, "Sending PSK identity '%s'\n", identity); memcpy(psk, default_psk, key_len); @@ -658,7 +665,7 @@ err: } static SSL * -ssl_sock_connect_loop(SSL_CTX *ctx, int fd) +ssl_sock_connect_loop(SSL_CTX *ctx, int fd, struct spdk_sock_impl_opts *impl_opts) { int rc; SSL *ssl; @@ -670,6 +677,7 @@ ssl_sock_connect_loop(SSL_CTX *ctx, int fd) return NULL; } SSL_set_fd(ssl, fd); + SSL_set_app_data(ssl, impl_opts); SSL_set_psk_client_callback(ssl, posix_sock_tls_psk_client_cb); SPDK_DEBUGLOG(sock_posix, "SSL object creation finished: %p\n", ssl); SPDK_DEBUGLOG(sock_posix, "%s = SSL_state_string_long(%p)\n", SSL_state_string_long(ssl), ssl); @@ -696,7 +704,7 @@ ssl_sock_connect_loop(SSL_CTX *ctx, int fd) } static SSL * -ssl_sock_accept_loop(SSL_CTX *ctx, int fd) +ssl_sock_accept_loop(SSL_CTX *ctx, int fd, struct spdk_sock_impl_opts *impl_opts) { int rc; SSL *ssl; @@ -708,6 +716,7 @@ ssl_sock_accept_loop(SSL_CTX *ctx, int fd) return NULL; } SSL_set_fd(ssl, fd); + SSL_set_app_data(ssl, impl_opts); SSL_set_psk_server_callback(ssl, posix_sock_tls_psk_server_cb); SPDK_DEBUGLOG(sock_posix, "SSL object creation finished: %p\n", ssl); SPDK_DEBUGLOG(sock_posix, "%s = SSL_state_string_long(%p)\n", SSL_state_string_long(ssl), ssl); @@ -934,7 +943,7 @@ retry: fd = -1; break; } - ssl = ssl_sock_connect_loop(ctx, fd); + ssl = ssl_sock_connect_loop(ctx, fd, &impl_opts); if (!ssl) { SPDK_ERRLOG("ssl_sock_connect_loop() failed, errno = %d\n", errno); close(fd); @@ -1037,7 +1046,7 @@ posix_sock_accept(struct spdk_sock *_sock) /* Establish SSL connection */ if (sock->ctx) { - ssl = ssl_sock_accept_loop(sock->ctx, fd); + ssl = ssl_sock_accept_loop(sock->ctx, fd, &sock->base.impl_opts); if (!ssl) { SPDK_ERRLOG("ssl_sock_accept_loop() failed, errno = %d\n", errno); close(fd); diff --git a/module/sock/uring/uring.c b/module/sock/uring/uring.c index 139c7c8c0..b59633330 100644 --- a/module/sock/uring/uring.c +++ b/module/sock/uring/uring.c @@ -97,7 +97,9 @@ static struct spdk_sock_impl_opts g_spdk_uring_sock_impl_opts = { .enable_zerocopy_send_client = false, .zerocopy_threshold = 0, .tls_version = 0, - .enable_ktls = false + .enable_ktls = false, + .psk_key = NULL, + .psk_identity = NULL }; static struct spdk_sock_map g_map = { @@ -138,6 +140,8 @@ uring_sock_copy_impl_opts(struct spdk_sock_impl_opts *dest, const struct spdk_so SET_FIELD(zerocopy_threshold); SET_FIELD(tls_version); SET_FIELD(enable_ktls); + SET_FIELD(psk_key); + SET_FIELD(psk_identity); #undef SET_FIELD #undef FIELD_OK diff --git a/python/spdk/rpc/sock.py b/python/spdk/rpc/sock.py index 4761b74df..d7ccc10b6 100644 --- a/python/spdk/rpc/sock.py +++ b/python/spdk/rpc/sock.py @@ -22,7 +22,9 @@ def sock_impl_set_options(client, enable_zerocopy_send_client=None, zerocopy_threshold=None, tls_version=None, - enable_ktls=None): + enable_ktls=None, + psk_key=None, + psk_identity=None): """Set parameters for the socket layer implementation. Args: @@ -37,6 +39,8 @@ def sock_impl_set_options(client, zerocopy_threshold: set zerocopy_threshold in bytes(optional) tls_version: set TLS protocol version (optional) enable_ktls: enable or disable Kernel TLS (optional) + psk_key: set psk_key (optional) + psk_identity: set psk_identity (optional) """ params = {} @@ -61,6 +65,10 @@ def sock_impl_set_options(client, params['tls_version'] = tls_version if enable_ktls is not None: params['enable_ktls'] = enable_ktls + if psk_key is not None: + params['psk_key'] = psk_key + if psk_identity is not None: + params['psk_identity'] = psk_identity return client.call('sock_impl_set_options', params) diff --git a/scripts/rpc.py b/scripts/rpc.py index f0ee5564e..859ab2a04 100755 --- a/scripts/rpc.py +++ b/scripts/rpc.py @@ -2846,7 +2846,9 @@ Format: 'user:u1 secret:s1 muser:mu1 msecret:ms1,user:u2 secret:s2 muser:mu2 mse enable_zerocopy_send_client=args.enable_zerocopy_send_client, zerocopy_threshold=args.zerocopy_threshold, tls_version=args.tls_version, - enable_ktls=args.enable_ktls) + enable_ktls=args.enable_ktls, + psk_key=args.psk_key, + psk_identity=args.psk_identity) p = subparsers.add_parser('sock_impl_set_options', help="""Set options of socket layer implementation""") p.add_argument('-i', '--impl', help='Socket implementation name, e.g. posix', required=True) @@ -2875,9 +2877,11 @@ Format: 'user:u1 secret:s1 muser:mu1 msecret:ms1,user:u2 secret:s2 muser:mu2 mse action='store_true', dest='enable_ktls') p.add_argument('--disable-ktls', help='Disable Kernel TLS', action='store_false', dest='enable_ktls') + p.add_argument('--psk-key', help='Set default PSK KEY', dest='psk_key') + p.add_argument('--psk-identity', help='Set default PSK ID', dest='psk_identity') p.set_defaults(func=sock_impl_set_options, enable_recv_pipe=None, enable_quickack=None, enable_placement_id=None, enable_zerocopy_send_server=None, enable_zerocopy_send_client=None, - zerocopy_threshold=None, tls_version=None, enable_ktls=None) + zerocopy_threshold=None, tls_version=None, enable_ktls=None, psk_key=None, psk_identity=None) def sock_set_default_impl(args): print_json(rpc.sock.sock_set_default_impl(args.client, diff --git a/test/iscsi_tgt/sock/sock.sh b/test/iscsi_tgt/sock/sock.sh index 9e03c21fa..86b303d36 100755 --- a/test/iscsi_tgt/sock/sock.sh +++ b/test/iscsi_tgt/sock/sock.sh @@ -67,7 +67,7 @@ iscsitestinit HELLO_SOCK_APP="${TARGET_NS_CMD[*]} $SPDK_EXAMPLE_DIR/hello_sock" SOCAT_APP="socat" OPENSSL_APP="openssl" -PSK_ID="nqn.2014-08.org.nvmexpress:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6" +PSK="-N ssl -E 1234567890ABCDEF -I psk.spdk.io" # ---------------- # Test client path @@ -119,39 +119,39 @@ timing_enter sock_ssl_server echo "Testing SSL server path" # start echo server using hello_sock echo server -$HELLO_SOCK_APP -H $TARGET_IP -P $ISCSI_PORT -S -N "ssl" & +$HELLO_SOCK_APP -H $TARGET_IP -P $ISCSI_PORT -S $PSK & server_pid=$! trap 'killprocess $server_pid; iscsitestfini; exit 1' SIGINT SIGTERM EXIT waitforlisten $server_pid # send message using hello_sock client message="**MESSAGE:This is a test message from the hello_sock client with ssl**" -response=$(echo $message | $HELLO_SOCK_APP -H $TARGET_IP -P $ISCSI_PORT -N "ssl") +response=$(echo $message | $HELLO_SOCK_APP -H $TARGET_IP -P $ISCSI_PORT $PSK) if ! echo "$response" | grep -q "$message"; then exit 1 fi # send message using hello_sock client using TLS 1.3 message="**MESSAGE:This is a test message from the hello_sock client with ssl using TLS 1.3**" -response=$(echo $message | $HELLO_SOCK_APP -H $TARGET_IP -P $ISCSI_PORT -N "ssl" -T 13) +response=$(echo $message | $HELLO_SOCK_APP -H $TARGET_IP -P $ISCSI_PORT $PSK -T 13) if ! echo "$response" | grep -q "$message"; then exit 1 fi # send message using hello_sock client using TLS 1.2 message="**MESSAGE:This is a test message from the hello_sock client with ssl using TLS 1.2**" -response=$(echo $message | $HELLO_SOCK_APP -H $TARGET_IP -P $ISCSI_PORT -N "ssl" -T 12) +response=$(echo $message | $HELLO_SOCK_APP -H $TARGET_IP -P $ISCSI_PORT $PSK -T 12) if ! echo "$response" | grep -q "$message"; then exit 1 fi # send message using hello_sock client using incorrect TLS 7 message="**MESSAGE:This is a test message from the hello_sock client with ssl using incorrect TLS 7**" -echo $message | $HELLO_SOCK_APP -H $TARGET_IP -P $ISCSI_PORT -N "ssl" -T 7 && exit 1 +echo $message | $HELLO_SOCK_APP -H $TARGET_IP -P $ISCSI_PORT $PSK -T 7 && exit 1 # send message using hello_sock client with KTLS disabled message="**MESSAGE:This is a test message from the hello_sock client with KTLS disabled**" -response=$(echo $message | $HELLO_SOCK_APP -H $TARGET_IP -P $ISCSI_PORT -N "ssl" -k) +response=$(echo $message | $HELLO_SOCK_APP -H $TARGET_IP -P $ISCSI_PORT $PSK -k) if ! echo "$response" | grep -q "$message"; then exit 1 fi @@ -159,14 +159,14 @@ fi # send message using hello_sock client with KTLS enabled message="**MESSAGE:This is a test message from the hello_sock client with KTLS enabled**" # UT infrastructure so far doesn't support new openssl-3 with this option, so expect a failure -echo $message | $HELLO_SOCK_APP -H $TARGET_IP -P $ISCSI_PORT -N "ssl" -K && exit 1 +echo $message | $HELLO_SOCK_APP -H $TARGET_IP -P $ISCSI_PORT $PSK -K && exit 1 # send message using openssl client using TLS 1.3 message="**MESSAGE:This is a test message from the openssl client using TLS 1.3**" response=$( ( echo -ne $message sleep 2 -) | $OPENSSL_APP s_client -debug -state -tlsextdebug -tls1_3 -psk_identity $PSK_ID -psk "1234567890ABCDEF" -connect $TARGET_IP:$ISCSI_PORT) +) | $OPENSSL_APP s_client -debug -state -tlsextdebug -tls1_3 -psk_identity psk.spdk.io -psk "1234567890ABCDEF" -connect $TARGET_IP:$ISCSI_PORT) if ! echo "$response" | grep -q "$message"; then exit 1 fi @@ -176,11 +176,19 @@ message="**MESSAGE:This is a test message from the openssl client using TLS 1.2* response=$( ( echo -ne $message sleep 2 -) | $OPENSSL_APP s_client -debug -state -tlsextdebug -tls1_2 -psk_identity $PSK_ID -psk "1234567890ABCDEF" -connect $TARGET_IP:$ISCSI_PORT) +) | $OPENSSL_APP s_client -debug -state -tlsextdebug -tls1_2 -psk_identity psk.spdk.io -psk "1234567890ABCDEF" -connect $TARGET_IP:$ISCSI_PORT) if ! echo "$response" | grep -q "$message"; then exit 1 fi +# send message using hello_sock client with unmatching PSK KEY, expect a failure +message="**MESSAGE:This is a test message from the hello_sock client with unmatching psk_key**" +echo $message | $HELLO_SOCK_APP -H $TARGET_IP -P $ISCSI_PORT $PSK -E 4321DEADBEEF1234 && exit 1 + +# send message using hello_sock client with unmatching PSK IDENTITY, expect a failure +message="**MESSAGE:This is a test message from the hello_sock client with unmatching psk_key**" +echo $message | $HELLO_SOCK_APP -H $TARGET_IP -P $ISCSI_PORT $PSK -I WRONG_PSK_ID && exit 1 + trap '-' SIGINT SIGTERM EXIT # NOTE: socat returns code 143 on SIGINT killprocess $server_pid || true diff --git a/test/nvmf/target/tls.sh b/test/nvmf/target/tls.sh index 036dd388f..dcdec1ebb 100755 --- a/test/nvmf/target/tls.sh +++ b/test/nvmf/target/tls.sh @@ -72,6 +72,36 @@ if [[ "$ktls" != "false" ]]; then exit 1 fi +# Check default PSK key +key=$($rpc_py sock_impl_get_options -i ssl | jq -r .psk_key) +if [[ "$key" != "null" ]]; then + echo "TLS default key should be empty and not $key" + exit 1 +fi + +# Check default PSK key set +$rpc_py sock_impl_set_options -i ssl --psk-key 1234567890ABCDEF +key=$($rpc_py sock_impl_get_options -i ssl | jq -r .psk_key) +if [[ "$key" != "1234567890ABCDEF" ]]; then + echo "TLS key was not set correctly $key != 1234567890ABCDEF" + exit 1 +fi + +# Check default PSK identity +identity=$($rpc_py sock_impl_get_options -i ssl | jq -r .psk_identity) +if [[ "$identity" != "null" ]]; then + echo "TLS default identity should be empty and not $identity" + exit 1 +fi + +# Check default PSK identity set +$rpc_py sock_impl_set_options -i ssl --psk-identity psk.spdk.io +identity=$($rpc_py sock_impl_get_options -i ssl | jq -r .psk_identity) +if [[ "$identity" != "psk.spdk.io" ]]; then + echo "PSK ID was not set correctly $identity != psk.spdk.io" + exit 1 +fi + $rpc_py sock_impl_set_options -i ssl --tls-version 13 $rpc_py framework_start_init $rpc_py nvmf_create_transport $NVMF_TRANSPORT_OPTS @@ -84,7 +114,7 @@ $rpc_py nvmf_subsystem_add_ns nqn.2016-06.io.spdk:cnode1 malloc0 -n 1 # Send IO "${NVMF_TARGET_NS_CMD[@]}" $SPDK_EXAMPLE_DIR/perf -S ssl -q 64 -o 4096 -w randrw -M 30 -t 10 \ -r "trtype:${TEST_TRANSPORT} adrfam:IPv4 traddr:${NVMF_FIRST_TARGET_IP} trsvcid:${NVMF_PORT} \ -subnqn:nqn.2016-06.io.spdk:cnode1" +subnqn:nqn.2016-06.io.spdk:cnode1" --psk-key 1234567890ABCDEF --psk-identity psk.spdk.io trap - SIGINT SIGTERM EXIT nvmftestfini