]>
Commit | Line | Data |
---|---|---|
ac1d8878 DB |
1 | /* |
2 | * QEMU Crypto secret handling | |
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 | |
9 | * version 2 of the License, or (at your option) any later version. | |
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 | ||
681c28a3 | 21 | #include "qemu/osdep.h" |
ac1d8878 DB |
22 | #include <glib.h> |
23 | ||
24 | #include "crypto/init.h" | |
25 | #include "crypto/secret.h" | |
da34e65c | 26 | #include "qapi/error.h" |
ac1d8878 DB |
27 | |
28 | static void test_secret_direct(void) | |
29 | { | |
30 | Object *sec = object_new_with_props( | |
31 | TYPE_QCRYPTO_SECRET, | |
32 | object_get_objects_root(), | |
33 | "sec0", | |
34 | &error_abort, | |
35 | "data", "123456", | |
36 | NULL); | |
37 | ||
38 | char *pw = qcrypto_secret_lookup_as_utf8("sec0", | |
39 | &error_abort); | |
40 | ||
41 | g_assert_cmpstr(pw, ==, "123456"); | |
42 | ||
43 | object_unparent(sec); | |
44 | g_free(pw); | |
45 | } | |
46 | ||
47 | ||
48 | static void test_secret_indirect_good(void) | |
49 | { | |
50 | Object *sec; | |
51 | char *fname = NULL; | |
52 | int fd = g_file_open_tmp("secretXXXXXX", | |
53 | &fname, | |
54 | NULL); | |
55 | ||
56 | g_assert(fd >= 0); | |
57 | g_assert_nonnull(fname); | |
58 | ||
59 | g_assert(write(fd, "123456", 6) == 6); | |
60 | ||
61 | sec = object_new_with_props( | |
62 | TYPE_QCRYPTO_SECRET, | |
63 | object_get_objects_root(), | |
64 | "sec0", | |
65 | &error_abort, | |
66 | "file", fname, | |
67 | NULL); | |
68 | ||
69 | char *pw = qcrypto_secret_lookup_as_utf8("sec0", | |
70 | &error_abort); | |
71 | ||
72 | g_assert_cmpstr(pw, ==, "123456"); | |
73 | ||
74 | object_unparent(sec); | |
75 | g_free(pw); | |
76 | close(fd); | |
77 | g_free(fname); | |
78 | } | |
79 | ||
80 | ||
81 | static void test_secret_indirect_badfile(void) | |
82 | { | |
83 | Object *sec = object_new_with_props( | |
84 | TYPE_QCRYPTO_SECRET, | |
85 | object_get_objects_root(), | |
86 | "sec0", | |
87 | NULL, | |
88 | "file", "does-not-exist", | |
89 | NULL); | |
90 | ||
91 | g_assert(sec == NULL); | |
92 | } | |
93 | ||
94 | ||
95 | static void test_secret_indirect_emptyfile(void) | |
96 | { | |
97 | Object *sec; | |
98 | char *fname = NULL; | |
99 | int fd = g_file_open_tmp("secretXXXXXX", | |
100 | &fname, | |
101 | NULL); | |
102 | ||
103 | g_assert(fd >= 0); | |
104 | g_assert_nonnull(fname); | |
105 | ||
106 | sec = object_new_with_props( | |
107 | TYPE_QCRYPTO_SECRET, | |
108 | object_get_objects_root(), | |
109 | "sec0", | |
110 | &error_abort, | |
111 | "file", fname, | |
112 | NULL); | |
113 | ||
114 | char *pw = qcrypto_secret_lookup_as_utf8("sec0", | |
115 | &error_abort); | |
116 | ||
117 | g_assert_cmpstr(pw, ==, ""); | |
118 | ||
119 | object_unparent(sec); | |
120 | g_free(pw); | |
121 | close(fd); | |
122 | g_free(fname); | |
123 | } | |
124 | ||
125 | ||
126 | static void test_secret_noconv_base64_good(void) | |
127 | { | |
128 | Object *sec = object_new_with_props( | |
129 | TYPE_QCRYPTO_SECRET, | |
130 | object_get_objects_root(), | |
131 | "sec0", | |
132 | &error_abort, | |
133 | "data", "MTIzNDU2", | |
134 | "format", "base64", | |
135 | NULL); | |
136 | ||
137 | char *pw = qcrypto_secret_lookup_as_base64("sec0", | |
138 | &error_abort); | |
139 | ||
140 | g_assert_cmpstr(pw, ==, "MTIzNDU2"); | |
141 | ||
142 | object_unparent(sec); | |
143 | g_free(pw); | |
144 | } | |
145 | ||
146 | ||
147 | static void test_secret_noconv_base64_bad(void) | |
148 | { | |
149 | Object *sec = object_new_with_props( | |
150 | TYPE_QCRYPTO_SECRET, | |
151 | object_get_objects_root(), | |
152 | "sec0", | |
153 | NULL, | |
154 | "data", "MTI$NDU2", | |
155 | "format", "base64", | |
156 | NULL); | |
157 | ||
158 | g_assert(sec == NULL); | |
159 | } | |
160 | ||
161 | ||
162 | static void test_secret_noconv_utf8(void) | |
163 | { | |
164 | Object *sec = object_new_with_props( | |
165 | TYPE_QCRYPTO_SECRET, | |
166 | object_get_objects_root(), | |
167 | "sec0", | |
168 | &error_abort, | |
169 | "data", "123456", | |
170 | "format", "raw", | |
171 | NULL); | |
172 | ||
173 | char *pw = qcrypto_secret_lookup_as_utf8("sec0", | |
174 | &error_abort); | |
175 | ||
176 | g_assert_cmpstr(pw, ==, "123456"); | |
177 | ||
178 | object_unparent(sec); | |
179 | g_free(pw); | |
180 | } | |
181 | ||
182 | ||
183 | static void test_secret_conv_base64_utf8valid(void) | |
184 | { | |
185 | Object *sec = object_new_with_props( | |
186 | TYPE_QCRYPTO_SECRET, | |
187 | object_get_objects_root(), | |
188 | "sec0", | |
189 | &error_abort, | |
190 | "data", "MTIzNDU2", | |
191 | "format", "base64", | |
192 | NULL); | |
193 | ||
194 | char *pw = qcrypto_secret_lookup_as_utf8("sec0", | |
195 | &error_abort); | |
196 | ||
197 | g_assert_cmpstr(pw, ==, "123456"); | |
198 | ||
199 | object_unparent(sec); | |
200 | g_free(pw); | |
201 | } | |
202 | ||
203 | ||
204 | static void test_secret_conv_base64_utf8invalid(void) | |
205 | { | |
206 | Object *sec = object_new_with_props( | |
207 | TYPE_QCRYPTO_SECRET, | |
208 | object_get_objects_root(), | |
209 | "sec0", | |
210 | &error_abort, | |
211 | "data", "f0VMRgIBAQAAAA==", | |
212 | "format", "base64", | |
213 | NULL); | |
214 | ||
215 | char *pw = qcrypto_secret_lookup_as_utf8("sec0", | |
216 | NULL); | |
217 | g_assert(pw == NULL); | |
218 | ||
219 | object_unparent(sec); | |
220 | } | |
221 | ||
222 | ||
223 | static void test_secret_conv_utf8_base64(void) | |
224 | { | |
225 | Object *sec = object_new_with_props( | |
226 | TYPE_QCRYPTO_SECRET, | |
227 | object_get_objects_root(), | |
228 | "sec0", | |
229 | &error_abort, | |
230 | "data", "123456", | |
231 | NULL); | |
232 | ||
233 | char *pw = qcrypto_secret_lookup_as_base64("sec0", | |
234 | &error_abort); | |
235 | ||
236 | g_assert_cmpstr(pw, ==, "MTIzNDU2"); | |
237 | ||
238 | object_unparent(sec); | |
239 | g_free(pw); | |
240 | } | |
241 | ||
242 | ||
243 | static void test_secret_crypt_raw(void) | |
244 | { | |
245 | Object *master = object_new_with_props( | |
246 | TYPE_QCRYPTO_SECRET, | |
247 | object_get_objects_root(), | |
248 | "master", | |
249 | &error_abort, | |
250 | "data", "9miloPQCzGy+TL6aonfzVcptibCmCIhKzrnlfwiWivk=", | |
251 | "format", "base64", | |
252 | NULL); | |
253 | Object *sec = object_new_with_props( | |
254 | TYPE_QCRYPTO_SECRET, | |
255 | object_get_objects_root(), | |
256 | "sec0", | |
257 | &error_abort, | |
258 | "data", | |
259 | "\xCC\xBF\xF7\x09\x46\x19\x0B\x52\x2A\x3A\xB4\x6B\xCD\x7A\xB0\xB0", | |
260 | "format", "raw", | |
261 | "keyid", "master", | |
262 | "iv", "0I7Gw/TKuA+Old2W2apQ3g==", | |
263 | NULL); | |
264 | ||
265 | char *pw = qcrypto_secret_lookup_as_utf8("sec0", | |
266 | &error_abort); | |
267 | ||
268 | g_assert_cmpstr(pw, ==, "123456"); | |
269 | ||
270 | object_unparent(sec); | |
271 | object_unparent(master); | |
272 | g_free(pw); | |
273 | } | |
274 | ||
275 | ||
276 | static void test_secret_crypt_base64(void) | |
277 | { | |
278 | Object *master = object_new_with_props( | |
279 | TYPE_QCRYPTO_SECRET, | |
280 | object_get_objects_root(), | |
281 | "master", | |
282 | &error_abort, | |
283 | "data", "9miloPQCzGy+TL6aonfzVcptibCmCIhKzrnlfwiWivk=", | |
284 | "format", "base64", | |
285 | NULL); | |
286 | Object *sec = object_new_with_props( | |
287 | TYPE_QCRYPTO_SECRET, | |
288 | object_get_objects_root(), | |
289 | "sec0", | |
290 | &error_abort, | |
291 | "data", "zL/3CUYZC1IqOrRrzXqwsA==", | |
292 | "format", "base64", | |
293 | "keyid", "master", | |
294 | "iv", "0I7Gw/TKuA+Old2W2apQ3g==", | |
295 | NULL); | |
296 | ||
297 | char *pw = qcrypto_secret_lookup_as_utf8("sec0", | |
298 | &error_abort); | |
299 | ||
300 | g_assert_cmpstr(pw, ==, "123456"); | |
301 | ||
302 | object_unparent(sec); | |
303 | object_unparent(master); | |
304 | g_free(pw); | |
305 | } | |
306 | ||
307 | ||
308 | static void test_secret_crypt_short_key(void) | |
309 | { | |
310 | Object *master = object_new_with_props( | |
311 | TYPE_QCRYPTO_SECRET, | |
312 | object_get_objects_root(), | |
313 | "master", | |
314 | &error_abort, | |
315 | "data", "9miloPQCzGy+TL6aonfzVc", | |
316 | "format", "base64", | |
317 | NULL); | |
318 | Object *sec = object_new_with_props( | |
319 | TYPE_QCRYPTO_SECRET, | |
320 | object_get_objects_root(), | |
321 | "sec0", | |
322 | NULL, | |
323 | "data", "zL/3CUYZC1IqOrRrzXqwsA==", | |
324 | "format", "raw", | |
325 | "keyid", "master", | |
326 | "iv", "0I7Gw/TKuA+Old2W2apQ3g==", | |
327 | NULL); | |
328 | ||
329 | g_assert(sec == NULL); | |
330 | object_unparent(master); | |
331 | } | |
332 | ||
333 | ||
334 | static void test_secret_crypt_short_iv(void) | |
335 | { | |
336 | Object *master = object_new_with_props( | |
337 | TYPE_QCRYPTO_SECRET, | |
338 | object_get_objects_root(), | |
339 | "master", | |
340 | &error_abort, | |
341 | "data", "9miloPQCzGy+TL6aonfzVcptibCmCIhKzrnlfwiWivk=", | |
342 | "format", "base64", | |
343 | NULL); | |
344 | Object *sec = object_new_with_props( | |
345 | TYPE_QCRYPTO_SECRET, | |
346 | object_get_objects_root(), | |
347 | "sec0", | |
348 | NULL, | |
349 | "data", "zL/3CUYZC1IqOrRrzXqwsA==", | |
350 | "format", "raw", | |
351 | "keyid", "master", | |
352 | "iv", "0I7Gw/TKuA+Old2W2a", | |
353 | NULL); | |
354 | ||
355 | g_assert(sec == NULL); | |
356 | object_unparent(master); | |
357 | } | |
358 | ||
359 | ||
360 | static void test_secret_crypt_missing_iv(void) | |
361 | { | |
362 | Object *master = object_new_with_props( | |
363 | TYPE_QCRYPTO_SECRET, | |
364 | object_get_objects_root(), | |
365 | "master", | |
366 | &error_abort, | |
367 | "data", "9miloPQCzGy+TL6aonfzVcptibCmCIhKzrnlfwiWivk=", | |
368 | "format", "base64", | |
369 | NULL); | |
370 | Object *sec = object_new_with_props( | |
371 | TYPE_QCRYPTO_SECRET, | |
372 | object_get_objects_root(), | |
373 | "sec0", | |
374 | NULL, | |
375 | "data", "zL/3CUYZC1IqOrRrzXqwsA==", | |
376 | "format", "raw", | |
377 | "keyid", "master", | |
378 | NULL); | |
379 | ||
380 | g_assert(sec == NULL); | |
381 | object_unparent(master); | |
382 | } | |
383 | ||
384 | ||
385 | static void test_secret_crypt_bad_iv(void) | |
386 | { | |
387 | Object *master = object_new_with_props( | |
388 | TYPE_QCRYPTO_SECRET, | |
389 | object_get_objects_root(), | |
390 | "master", | |
391 | &error_abort, | |
392 | "data", "9miloPQCzGy+TL6aonfzVcptibCmCIhKzrnlfwiWivk=", | |
393 | "format", "base64", | |
394 | NULL); | |
395 | Object *sec = object_new_with_props( | |
396 | TYPE_QCRYPTO_SECRET, | |
397 | object_get_objects_root(), | |
398 | "sec0", | |
399 | NULL, | |
400 | "data", "zL/3CUYZC1IqOrRrzXqwsA==", | |
401 | "format", "raw", | |
402 | "keyid", "master", | |
403 | "iv", "0I7Gw/TK$$uA+Old2W2a", | |
404 | NULL); | |
405 | ||
406 | g_assert(sec == NULL); | |
407 | object_unparent(master); | |
408 | } | |
409 | ||
410 | ||
411 | int main(int argc, char **argv) | |
412 | { | |
413 | module_call_init(MODULE_INIT_QOM); | |
414 | g_test_init(&argc, &argv, NULL); | |
415 | ||
416 | g_assert(qcrypto_init(NULL) == 0); | |
417 | ||
418 | g_test_add_func("/crypto/secret/direct", | |
419 | test_secret_direct); | |
420 | g_test_add_func("/crypto/secret/indirect/good", | |
421 | test_secret_indirect_good); | |
422 | g_test_add_func("/crypto/secret/indirect/badfile", | |
423 | test_secret_indirect_badfile); | |
424 | g_test_add_func("/crypto/secret/indirect/emptyfile", | |
425 | test_secret_indirect_emptyfile); | |
426 | ||
427 | g_test_add_func("/crypto/secret/noconv/base64/good", | |
428 | test_secret_noconv_base64_good); | |
429 | g_test_add_func("/crypto/secret/noconv/base64/bad", | |
430 | test_secret_noconv_base64_bad); | |
431 | g_test_add_func("/crypto/secret/noconv/utf8", | |
432 | test_secret_noconv_utf8); | |
433 | g_test_add_func("/crypto/secret/conv/base64/utf8valid", | |
434 | test_secret_conv_base64_utf8valid); | |
435 | g_test_add_func("/crypto/secret/conv/base64/utf8invalid", | |
436 | test_secret_conv_base64_utf8invalid); | |
437 | g_test_add_func("/crypto/secret/conv/utf8/base64", | |
438 | test_secret_conv_utf8_base64); | |
439 | ||
440 | g_test_add_func("/crypto/secret/crypt/raw", | |
441 | test_secret_crypt_raw); | |
442 | g_test_add_func("/crypto/secret/crypt/base64", | |
443 | test_secret_crypt_base64); | |
444 | g_test_add_func("/crypto/secret/crypt/shortkey", | |
445 | test_secret_crypt_short_key); | |
446 | g_test_add_func("/crypto/secret/crypt/shortiv", | |
447 | test_secret_crypt_short_iv); | |
448 | g_test_add_func("/crypto/secret/crypt/missingiv", | |
449 | test_secret_crypt_missing_iv); | |
450 | g_test_add_func("/crypto/secret/crypt/badiv", | |
451 | test_secret_crypt_bad_iv); | |
452 | ||
453 | return g_test_run(); | |
454 | } |