Commit 171345eb authored by Krzysztof Karas's avatar Krzysztof Karas Committed by Jim Harris
Browse files

sock: add optional callback to spdk_sock_impl_opts



Add a callback get_key() to retrieve PSK by the SSL sock module.

Use get_key() in posix_sock_tls_psk_server_cb() if it is
available.

Change-Id: I5a60af76eef603ccb619465df4bc86b4fe5ba60b
Signed-off-by: default avatarKrzysztof Karas <krzysztof.karas@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/15548


Reviewed-by: default avatarKonrad Sztyber <konrad.sztyber@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Mellanox Build Bot
parent 663243cb
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -64,6 +64,10 @@ authentication. Only valid for the TCP transport.
Added two optional transport module callbacks: `subsystem_add_host()` and `subsystem_remove_host()`.
These functions will notify a transport about adding/removing hosts' access.

### sock

Added a callback `get_key()` to `spdk_sock_impl_opts` structure.

### nvme

New API `spdk_nvme_ns_get_format_index` was added to calculate the exact format index, that
+19 −0
Original line number Diff line number Diff line
@@ -149,6 +149,25 @@ struct spdk_sock_impl_opts {
	 * Set default PSK identity. Used by ssl socket module.
	 */
	char *psk_identity;

	/**
	 * Optional callback to retrieve PSK based on client's identity.
	 *
	 * \param out Buffer for PSK in hexadecimal format to be filled with found key.
	 * \param out_len Length of "out" buffer.
	 * \param cipher Cipher suite to be set by this callback.
	 * \param psk_identity PSK identity for which the key needs to be found.
	 * \param get_key_ctx Context for this callback.
	 *
	 * \return key length on success, -1 on failure.
	 */
	int (*get_key)(uint8_t *out, int out_len, const char **cipher, const char *psk_identity,
		       void *get_key_ctx);

	/**
	 * Context to be passed to get_key() callback.
	 */
	void *get_key_ctx;
};

/**
+35 −19
Original line number Diff line number Diff line
@@ -80,7 +80,9 @@ static struct spdk_sock_impl_opts g_spdk_posix_sock_impl_opts = {
	.tls_version = 0,
	.enable_ktls = false,
	.psk_key = NULL,
	.psk_identity = NULL
	.psk_identity = NULL,
	.get_key = NULL,
	.get_key_ctx = NULL
};

static struct spdk_sock_map g_map = {
@@ -122,6 +124,8 @@ posix_sock_copy_impl_opts(struct spdk_sock_impl_opts *dest, const struct spdk_so
	SET_FIELD(enable_ktls);
	SET_FIELD(psk_key);
	SET_FIELD(psk_identity);
	SET_FIELD(get_key);
	SET_FIELD(get_key_ctx);

#undef SET_FIELD
#undef FIELD_OK
@@ -520,40 +524,52 @@ posix_sock_tls_psk_server_cb(SSL *ssl,
			     unsigned int max_psk_len)
{
	long key_len;
	unsigned char *default_psk;
	unsigned char *psk_k = NULL;
	const char *cipher = NULL;
	struct spdk_sock_impl_opts *impl_opts;
	uint8_t sock_psk[PSK_MAX_PSK_LEN] = {};
	int rc;

	impl_opts = SSL_get_app_data(ssl);
	SPDK_DEBUGLOG(sock_posix, "Received PSK ID '%s'\n", id);
	if (id == NULL) {
		SPDK_ERRLOG("Received empty PSK ID\n");
		goto err;
	}

	SPDK_DEBUGLOG(sock_posix, "Length of Client's PSK KEY %u\n", max_psk_len);

	if (impl_opts->get_key) {
		rc = impl_opts->get_key(sock_psk, PSK_MAX_PSK_LEN, &cipher, id, impl_opts->get_key_ctx);
		assert(cipher == NULL);
		if (rc < 0) {
			goto err;
		}
		psk_k = OPENSSL_hexstr2buf(sock_psk, &key_len);
	} else {
		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(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(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(impl_opts->psk_key, &key_len);
	if (default_psk == NULL) {
		psk_k = OPENSSL_hexstr2buf(impl_opts->psk_key, &key_len);
	}
	if (psk_k == NULL) {
		SPDK_ERRLOG("Could not unhexlify PSK\n");
		goto err;
	}
	if (key_len > max_psk_len) {
		SPDK_ERRLOG("Insufficient buffer size to copy PSK\n");
		OPENSSL_free(default_psk);
		OPENSSL_free(psk_k);
		goto err;
	}

	memcpy(psk, default_psk, key_len);
	OPENSSL_free(default_psk);
	memcpy(psk, psk_k, key_len);
	OPENSSL_free(psk_k);

	return key_len;