]>
Commit | Line | Data |
---|---|---|
ac1d8878 DB |
1 | /* |
2 | * QEMU crypto secret support | |
3 | * | |
4 | * Copyright (c) 2015 Red Hat, Inc. | |
5 | * | |
6 | * This library is free software; you can redistribute it and/or | |
7 | * modify it under the terms of the GNU Lesser General Public | |
8 | * License as published by the Free Software Foundation; either | |
b7cbb874 | 9 | * version 2.1 of the License, or (at your option) any later version. |
ac1d8878 DB |
10 | * |
11 | * This library is distributed in the hope that it will be useful, | |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 | * Lesser General Public License for more details. | |
15 | * | |
16 | * You should have received a copy of the GNU Lesser General Public | |
17 | * License along with this library; if not, see <http://www.gnu.org/licenses/>. | |
18 | * | |
19 | */ | |
20 | ||
42f7a448 | 21 | #include "qemu/osdep.h" |
ac1d8878 | 22 | #include "crypto/secret.h" |
da34e65c | 23 | #include "qapi/error.h" |
ac1d8878 | 24 | #include "qom/object_interfaces.h" |
0b8fa32f | 25 | #include "qemu/module.h" |
ac1d8878 DB |
26 | #include "trace.h" |
27 | ||
28 | ||
29 | static void | |
4862bd3c | 30 | qcrypto_secret_load_data(QCryptoSecretCommon *sec_common, |
ac1d8878 DB |
31 | uint8_t **output, |
32 | size_t *outputlen, | |
33 | Error **errp) | |
34 | { | |
35 | char *data = NULL; | |
36 | size_t length = 0; | |
37 | GError *gerr = NULL; | |
38 | ||
4862bd3c AK |
39 | QCryptoSecret *secret = QCRYPTO_SECRET(sec_common); |
40 | ||
ac1d8878 DB |
41 | *output = NULL; |
42 | *outputlen = 0; | |
43 | ||
44 | if (secret->file) { | |
45 | if (secret->data) { | |
46 | error_setg(errp, | |
47 | "'file' and 'data' are mutually exclusive"); | |
48 | return; | |
49 | } | |
50 | if (!g_file_get_contents(secret->file, &data, &length, &gerr)) { | |
51 | error_setg(errp, | |
52 | "Unable to read %s: %s", | |
53 | secret->file, gerr->message); | |
54 | g_error_free(gerr); | |
55 | return; | |
56 | } | |
57 | *output = (uint8_t *)data; | |
58 | *outputlen = length; | |
59 | } else if (secret->data) { | |
60 | *outputlen = strlen(secret->data); | |
61 | *output = (uint8_t *)g_strdup(secret->data); | |
62 | } else { | |
63 | error_setg(errp, "Either 'file' or 'data' must be provided"); | |
64 | } | |
65 | } | |
66 | ||
67 | ||
ac1d8878 DB |
68 | static void |
69 | qcrypto_secret_prop_set_data(Object *obj, | |
70 | const char *value, | |
71 | Error **errp) | |
72 | { | |
73 | QCryptoSecret *secret = QCRYPTO_SECRET(obj); | |
74 | ||
75 | g_free(secret->data); | |
76 | secret->data = g_strdup(value); | |
77 | } | |
78 | ||
79 | ||
80 | static char * | |
81 | qcrypto_secret_prop_get_data(Object *obj, | |
82 | Error **errp) | |
83 | { | |
84 | QCryptoSecret *secret = QCRYPTO_SECRET(obj); | |
85 | return g_strdup(secret->data); | |
86 | } | |
87 | ||
88 | ||
89 | static void | |
90 | qcrypto_secret_prop_set_file(Object *obj, | |
91 | const char *value, | |
92 | Error **errp) | |
93 | { | |
94 | QCryptoSecret *secret = QCRYPTO_SECRET(obj); | |
95 | ||
96 | g_free(secret->file); | |
97 | secret->file = g_strdup(value); | |
98 | } | |
99 | ||
100 | ||
101 | static char * | |
102 | qcrypto_secret_prop_get_file(Object *obj, | |
103 | Error **errp) | |
104 | { | |
105 | QCryptoSecret *secret = QCRYPTO_SECRET(obj); | |
106 | return g_strdup(secret->file); | |
107 | } | |
108 | ||
109 | ||
ac1d8878 DB |
110 | static void |
111 | qcrypto_secret_complete(UserCreatable *uc, Error **errp) | |
112 | { | |
5325cc34 | 113 | object_property_set_bool(OBJECT(uc), "loaded", true, errp); |
ac1d8878 DB |
114 | } |
115 | ||
116 | ||
ac1d8878 DB |
117 | static void |
118 | qcrypto_secret_finalize(Object *obj) | |
119 | { | |
120 | QCryptoSecret *secret = QCRYPTO_SECRET(obj); | |
121 | ||
ac1d8878 | 122 | g_free(secret->file); |
ac1d8878 DB |
123 | g_free(secret->data); |
124 | } | |
125 | ||
126 | static void | |
127 | qcrypto_secret_class_init(ObjectClass *oc, void *data) | |
128 | { | |
4862bd3c AK |
129 | QCryptoSecretCommonClass *sic = QCRYPTO_SECRET_COMMON_CLASS(oc); |
130 | sic->load_data = qcrypto_secret_load_data; | |
ac1d8878 | 131 | |
4862bd3c | 132 | UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc); |
ac1d8878 | 133 | ucc->complete = qcrypto_secret_complete; |
9884abee | 134 | |
9884abee DB |
135 | object_class_property_add_str(oc, "data", |
136 | qcrypto_secret_prop_get_data, | |
d2623129 | 137 | qcrypto_secret_prop_set_data); |
9884abee DB |
138 | object_class_property_add_str(oc, "file", |
139 | qcrypto_secret_prop_get_file, | |
d2623129 | 140 | qcrypto_secret_prop_set_file); |
ac1d8878 DB |
141 | } |
142 | ||
143 | ||
144 | static const TypeInfo qcrypto_secret_info = { | |
4862bd3c | 145 | .parent = TYPE_QCRYPTO_SECRET_COMMON, |
ac1d8878 DB |
146 | .name = TYPE_QCRYPTO_SECRET, |
147 | .instance_size = sizeof(QCryptoSecret), | |
ac1d8878 DB |
148 | .instance_finalize = qcrypto_secret_finalize, |
149 | .class_size = sizeof(QCryptoSecretClass), | |
150 | .class_init = qcrypto_secret_class_init, | |
151 | .interfaces = (InterfaceInfo[]) { | |
152 | { TYPE_USER_CREATABLE }, | |
153 | { } | |
154 | } | |
155 | }; | |
156 | ||
157 | ||
158 | static void | |
159 | qcrypto_secret_register_types(void) | |
160 | { | |
161 | type_register_static(&qcrypto_secret_info); | |
162 | } | |
163 | ||
164 | ||
165 | type_init(qcrypto_secret_register_types); |