1*758e9fbaSOystein Eftevaag /* SPDX-License-Identifier: BSD-2-Clause */
2*758e9fbaSOystein Eftevaag /*
3*758e9fbaSOystein Eftevaag * Copyright (c) 2018, Intel Corporation
4*758e9fbaSOystein Eftevaag * All rights reserved.
5*758e9fbaSOystein Eftevaag */
6*758e9fbaSOystein Eftevaag #ifdef HAVE_CONFIG_H
7*758e9fbaSOystein Eftevaag #include <config.h>
8*758e9fbaSOystein Eftevaag #endif
9*758e9fbaSOystein Eftevaag
10*758e9fbaSOystein Eftevaag #include <inttypes.h>
11*758e9fbaSOystein Eftevaag #include <stdbool.h>
12*758e9fbaSOystein Eftevaag #include <string.h>
13*758e9fbaSOystein Eftevaag
14*758e9fbaSOystein Eftevaag #include "tss2_tpm2_types.h"
15*758e9fbaSOystein Eftevaag
16*758e9fbaSOystein Eftevaag #include "util/key-value-parse.h"
17*758e9fbaSOystein Eftevaag #define LOGMODULE tcti
18*758e9fbaSOystein Eftevaag #include "util/log.h"
19*758e9fbaSOystein Eftevaag
20*758e9fbaSOystein Eftevaag /*
21*758e9fbaSOystein Eftevaag * Parse the provided string containing a key / value pair separated by the
22*758e9fbaSOystein Eftevaag * '=' character.
23*758e9fbaSOystein Eftevaag * NOTE: The 'kv_str' parameter is not 'const' and this function will modify
24*758e9fbaSOystein Eftevaag * it as part of the parsing process. The key_value structure will be updated
25*758e9fbaSOystein Eftevaag * with references pointing to the appropriate location in the key_value_str
26*758e9fbaSOystein Eftevaag * parameter.
27*758e9fbaSOystein Eftevaag */
28*758e9fbaSOystein Eftevaag bool
parse_key_value(char * key_value_str,key_value_t * key_value)29*758e9fbaSOystein Eftevaag parse_key_value (char *key_value_str,
30*758e9fbaSOystein Eftevaag key_value_t *key_value)
31*758e9fbaSOystein Eftevaag {
32*758e9fbaSOystein Eftevaag const char *delim = "=";
33*758e9fbaSOystein Eftevaag char *tok, *state;
34*758e9fbaSOystein Eftevaag
35*758e9fbaSOystein Eftevaag LOG_TRACE ("key_value_str: \"%s\" and key_value_t: 0x%" PRIxPTR,
36*758e9fbaSOystein Eftevaag key_value_str, (uintptr_t)key_value);
37*758e9fbaSOystein Eftevaag if (key_value_str == NULL || key_value == NULL) {
38*758e9fbaSOystein Eftevaag LOG_WARNING ("received a NULL parameter, all are required");
39*758e9fbaSOystein Eftevaag return false;
40*758e9fbaSOystein Eftevaag }
41*758e9fbaSOystein Eftevaag tok = strtok_r (key_value_str, delim, &state);
42*758e9fbaSOystein Eftevaag if (tok == NULL) {
43*758e9fbaSOystein Eftevaag LOG_WARNING ("key / value string is null.");
44*758e9fbaSOystein Eftevaag return false;
45*758e9fbaSOystein Eftevaag }
46*758e9fbaSOystein Eftevaag key_value->key = tok;
47*758e9fbaSOystein Eftevaag
48*758e9fbaSOystein Eftevaag tok = strtok_r (NULL, delim, &state);
49*758e9fbaSOystein Eftevaag if (tok == NULL) {
50*758e9fbaSOystein Eftevaag LOG_WARNING ("key / value string is invalid");
51*758e9fbaSOystein Eftevaag return false;
52*758e9fbaSOystein Eftevaag }
53*758e9fbaSOystein Eftevaag key_value->value = tok;
54*758e9fbaSOystein Eftevaag
55*758e9fbaSOystein Eftevaag return true;
56*758e9fbaSOystein Eftevaag }
57*758e9fbaSOystein Eftevaag /*
58*758e9fbaSOystein Eftevaag * This function parses the provided configuration string extracting the
59*758e9fbaSOystein Eftevaag * key/value pairs. Each key/value pair extracted is stored in a key_value_t
60*758e9fbaSOystein Eftevaag * structure and then passed to the provided callback function for processing.
61*758e9fbaSOystein Eftevaag *
62*758e9fbaSOystein Eftevaag * NOTE: The 'kv_str' parameter is not 'const' and this function will modify
63*758e9fbaSOystein Eftevaag * it as part of the parsing process.
64*758e9fbaSOystein Eftevaag */
65*758e9fbaSOystein Eftevaag TSS2_RC
parse_key_value_string(char * kv_str,KeyValueFunc callback,void * user_data)66*758e9fbaSOystein Eftevaag parse_key_value_string (char *kv_str,
67*758e9fbaSOystein Eftevaag KeyValueFunc callback,
68*758e9fbaSOystein Eftevaag void *user_data)
69*758e9fbaSOystein Eftevaag {
70*758e9fbaSOystein Eftevaag const char *delim = ",";
71*758e9fbaSOystein Eftevaag char *state, *tok;
72*758e9fbaSOystein Eftevaag key_value_t key_value = KEY_VALUE_INIT;
73*758e9fbaSOystein Eftevaag TSS2_RC rc = TSS2_RC_SUCCESS;
74*758e9fbaSOystein Eftevaag
75*758e9fbaSOystein Eftevaag LOG_TRACE ("kv_str: \"%s\", callback: 0x%" PRIxPTR ", user_data: 0x%"
76*758e9fbaSOystein Eftevaag PRIxPTR, kv_str, (uintptr_t)callback,
77*758e9fbaSOystein Eftevaag (uintptr_t)user_data);
78*758e9fbaSOystein Eftevaag if (kv_str == NULL || callback == NULL || user_data == NULL) {
79*758e9fbaSOystein Eftevaag LOG_WARNING ("all parameters are required");
80*758e9fbaSOystein Eftevaag return TSS2_TCTI_RC_BAD_VALUE;
81*758e9fbaSOystein Eftevaag }
82*758e9fbaSOystein Eftevaag for (tok = strtok_r (kv_str, delim, &state);
83*758e9fbaSOystein Eftevaag tok;
84*758e9fbaSOystein Eftevaag tok = strtok_r (NULL, delim, &state)) {
85*758e9fbaSOystein Eftevaag LOG_DEBUG ("parsing key/value: %s", tok);
86*758e9fbaSOystein Eftevaag if (parse_key_value (tok, &key_value) != true) {
87*758e9fbaSOystein Eftevaag return TSS2_TCTI_RC_BAD_VALUE;
88*758e9fbaSOystein Eftevaag }
89*758e9fbaSOystein Eftevaag rc = callback (&key_value, user_data);
90*758e9fbaSOystein Eftevaag if (rc != TSS2_RC_SUCCESS) {
91*758e9fbaSOystein Eftevaag goto out;
92*758e9fbaSOystein Eftevaag }
93*758e9fbaSOystein Eftevaag }
94*758e9fbaSOystein Eftevaag out:
95*758e9fbaSOystein Eftevaag return rc;
96*758e9fbaSOystein Eftevaag }
97