]>
Commit | Line | Data |
---|---|---|
1d5e0797 SB |
1 | /* |
2 | * capabilities.c -- capabilities | |
3 | * | |
4 | * (c) Copyright IBM Corporation 2019. | |
5 | * | |
6 | * Author: Stefan Berger <stefanb@us.ibm.com> | |
7 | * | |
8 | * All rights reserved. | |
9 | * | |
10 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions are | |
12 | * met: | |
13 | * | |
14 | * Redistributions of source code must retain the above copyright notice, | |
15 | * this list of conditions and the following disclaimer. | |
16 | * | |
17 | * Redistributions in binary form must reproduce the above copyright | |
18 | * notice, this list of conditions and the following disclaimer in the | |
19 | * documentation and/or other materials provided with the distribution. | |
20 | * | |
21 | * Neither the names of the IBM Corporation nor the names of its | |
22 | * contributors may be used to endorse or promote products derived from | |
23 | * this software without specific prior written permission. | |
24 | * | |
25 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
26 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
27 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
28 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
29 | * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
30 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
31 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
32 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
33 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
34 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
35 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
36 | */ | |
37 | ||
38 | #include "config.h" | |
39 | ||
40 | #define _GNU_SOURCE | |
41 | #include <stdio.h> | |
42 | #include <stdlib.h> | |
c6b52d18 SB |
43 | #include <string.h> |
44 | ||
45 | #include <libtpms/tpm_library.h> | |
da8752b1 | 46 | #include <libtpms/tpm_error.h> |
1d5e0797 SB |
47 | |
48 | #include "capabilities.h" | |
49 | #include "logging.h" | |
50 | ||
c6b52d18 SB |
51 | /* Convert the RSA key size indicators supported by libtpms into capability |
52 | * strings. | |
53 | * libtpms may return us something like this here: | |
54 | * "TPMAttributes":{"manufacturer":"id:00001014",\ | |
55 | * "version":"id:20191023","model":"swtpm","RSAKeySizes":[1024,2048,3072]}} | |
56 | * | |
57 | * or an older version may not report RSA keysizes: | |
58 | * "TPMAttributes":{"manufacturer":"id:00001014",\ | |
59 | * "version":"id:20191023","model":"swtpm"}} | |
60 | */ | |
61 | static int get_rsa_keysize_caps(char **keysizecaps) | |
62 | { | |
63 | int ret = 0; | |
64 | char *start, *endptr; | |
65 | const char *needle = "\"RSAKeySizes\":["; | |
66 | char *info_data = TPMLIB_GetInfo(4 /*TPMLIB_INFO_TPMFEATURES*/); | |
67 | char buffer[128]; | |
68 | off_t offset = 0; | |
69 | int n; | |
70 | ||
71 | if (!info_data) | |
ccaf99f1 | 72 | goto cleanup; |
c6b52d18 SB |
73 | |
74 | start = strstr(info_data, needle); | |
75 | if (start) { | |
76 | start += strlen(needle); | |
77 | while (1) { | |
78 | unsigned long int keysize = strtoul(start, &endptr, 10); | |
79 | ||
80 | if (*endptr != ',' && *endptr != ']') { | |
81 | logprintf(STDERR_FILENO, "Malformed TPMLIB_GetInfo() string\n"); | |
82 | ret = -1; | |
83 | goto cleanup; | |
84 | } | |
85 | ||
86 | n = snprintf(buffer + offset, sizeof(buffer) - offset, | |
87 | ", \"rsa-keysize-%lu\"", | |
88 | keysize); | |
89 | if (n < 0 || (unsigned)n >= sizeof(buffer) - offset) { | |
90 | logprintf(STDERR_FILENO, "%s: buffer is too small\n", __func__); | |
91 | ret = -1; | |
92 | goto cleanup; | |
93 | } | |
94 | if (*endptr == ']') | |
95 | break; | |
96 | ||
97 | offset += n; | |
98 | start = endptr + 1; | |
99 | } | |
100 | ||
101 | *keysizecaps = strndup(buffer, sizeof(buffer) - 1); | |
102 | if (*keysizecaps == NULL) | |
103 | goto oom; | |
104 | } | |
105 | ||
106 | cleanup: | |
107 | free(info_data); | |
108 | return ret; | |
109 | ||
110 | oom: | |
111 | logprintf(STDERR_FILENO, "Out of memory\n"); | |
112 | ret = -1; | |
113 | goto cleanup; | |
114 | } | |
115 | ||
1d5e0797 SB |
116 | int capabilities_print_json(bool cusetpm) |
117 | { | |
118 | char *string = NULL; | |
119 | int ret = -1; | |
120 | int n; | |
121 | #ifdef WITH_SECCOMP | |
374b6691 | 122 | const char *cmdarg_seccomp = "\"cmdarg-seccomp\", "; |
1d5e0797 | 123 | #else |
374b6691 | 124 | const char *cmdarg_seccomp = ""; |
1d5e0797 | 125 | #endif |
da8752b1 MAL |
126 | const char *with_tpm1 = ""; |
127 | const char *with_tpm2 = ""; | |
c6b52d18 SB |
128 | char *keysizecaps = NULL; |
129 | ||
130 | ret = get_rsa_keysize_caps(&keysizecaps); | |
131 | if (ret < 0) | |
132 | goto cleanup; | |
1d5e0797 | 133 | |
da8752b1 MAL |
134 | if (TPMLIB_ChooseTPMVersion(TPMLIB_TPM_VERSION_1_2) == TPM_SUCCESS) |
135 | with_tpm1 = "\"tpm-1.2\", "; | |
136 | if (TPMLIB_ChooseTPMVersion(TPMLIB_TPM_VERSION_2) == TPM_SUCCESS) | |
137 | with_tpm2 = "\"tpm-2.0\", "; | |
138 | ||
1d5e0797 SB |
139 | n = asprintf(&string, |
140 | "{ " | |
141 | "\"type\": \"swtpm\", " | |
142 | "\"features\": [ " | |
da8752b1 | 143 | "%s%s%s%s%s%s%s%s" |
155ccdf5 MAL |
144 | " ], " |
145 | "\"version\": \"" VERSION "\" " | |
1d5e0797 | 146 | "}", |
da8752b1 MAL |
147 | with_tpm1, |
148 | with_tpm2, | |
1d5e0797 | 149 | !cusetpm ? "\"tpm-send-command-header\", ": "", |
e6bc4bdf | 150 | !cusetpm ? "\"flags-opt-startup\", " : "", |
374b6691 | 151 | cmdarg_seccomp, |
1d5e0797 | 152 | true ? "\"cmdarg-key-fd\", " : "", |
c6b52d18 SB |
153 | true ? "\"cmdarg-pwd-fd\"" : "", |
154 | keysizecaps ? keysizecaps : "" | |
1d5e0797 SB |
155 | ); |
156 | ||
157 | if (n < 0) { | |
158 | logprintf(STDERR_FILENO, "Out of memory\n"); | |
159 | goto cleanup; | |
160 | } | |
161 | ||
162 | ret = 0; | |
163 | ||
164 | fprintf(stdout, "%s\n", string); | |
165 | ||
166 | cleanup: | |
c6b52d18 | 167 | free(keysizecaps); |
1d5e0797 SB |
168 | free(string); |
169 | ||
170 | return ret; | |
171 | } |