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