qapi/error: Check format string argument in error_*prepend()
[qemu/armbru.git] / tests / test-crypto-secret.c
blob603a093f104bc980b9540fe4f570fbbcc7ce3b77
1 /*
2 * QEMU Crypto secret handling
4 * Copyright (c) 2015 Red Hat, Inc.
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.
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.
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/>.
21 #include "qemu/osdep.h"
23 #include "crypto/init.h"
24 #include "crypto/secret.h"
25 #include "qapi/error.h"
26 #include "qemu/module.h"
27 #ifdef CONFIG_TEST_SECRET_KEYRING
28 #include "crypto/secret_keyring.h"
29 #include <keyutils.h>
30 #endif
32 static void test_secret_direct(void)
34 Object *sec = object_new_with_props(
35 TYPE_QCRYPTO_SECRET,
36 object_get_objects_root(),
37 "sec0",
38 &error_abort,
39 "data", "123456",
40 NULL);
42 char *pw = qcrypto_secret_lookup_as_utf8("sec0",
43 &error_abort);
45 g_assert_cmpstr(pw, ==, "123456");
47 object_unparent(sec);
48 g_free(pw);
52 static void test_secret_indirect_good(void)
54 Object *sec;
55 char *fname = NULL;
56 int fd = g_file_open_tmp("qemu-test-crypto-secret-XXXXXX",
57 &fname,
58 NULL);
60 g_assert(fd >= 0);
61 g_assert_nonnull(fname);
63 g_assert(write(fd, "123456", 6) == 6);
65 sec = object_new_with_props(
66 TYPE_QCRYPTO_SECRET,
67 object_get_objects_root(),
68 "sec0",
69 &error_abort,
70 "file", fname,
71 NULL);
73 char *pw = qcrypto_secret_lookup_as_utf8("sec0",
74 &error_abort);
76 g_assert_cmpstr(pw, ==, "123456");
78 object_unparent(sec);
79 g_free(pw);
80 close(fd);
81 unlink(fname);
82 g_free(fname);
86 static void test_secret_indirect_badfile(void)
88 Object *sec = object_new_with_props(
89 TYPE_QCRYPTO_SECRET,
90 object_get_objects_root(),
91 "sec0",
92 NULL,
93 "file", "does-not-exist",
94 NULL);
96 g_assert(sec == NULL);
100 static void test_secret_indirect_emptyfile(void)
102 Object *sec;
103 char *fname = NULL;
104 int fd = g_file_open_tmp("qemu-test-crypto-secretXXXXXX",
105 &fname,
106 NULL);
108 g_assert(fd >= 0);
109 g_assert_nonnull(fname);
111 sec = object_new_with_props(
112 TYPE_QCRYPTO_SECRET,
113 object_get_objects_root(),
114 "sec0",
115 &error_abort,
116 "file", fname,
117 NULL);
119 char *pw = qcrypto_secret_lookup_as_utf8("sec0",
120 &error_abort);
122 g_assert_cmpstr(pw, ==, "");
124 object_unparent(sec);
125 g_free(pw);
126 close(fd);
127 unlink(fname);
128 g_free(fname);
131 #ifdef CONFIG_TEST_SECRET_KEYRING
133 #define DESCRIPTION "qemu_test_secret"
134 #define PAYLOAD "Test Payload"
137 static void test_secret_keyring_good(void)
139 char key_str[16];
140 Object *sec;
141 int32_t key = add_key("user", DESCRIPTION, PAYLOAD,
142 strlen(PAYLOAD), KEY_SPEC_PROCESS_KEYRING);
144 g_assert(key >= 0);
146 snprintf(key_str, sizeof(key_str), "0x%08x", key);
147 sec = object_new_with_props(
148 TYPE_QCRYPTO_SECRET_KEYRING,
149 object_get_objects_root(),
150 "sec0",
151 &error_abort,
152 "serial", key_str,
153 NULL);
155 assert(0 <= keyctl_unlink(key, KEY_SPEC_PROCESS_KEYRING));
156 char *pw = qcrypto_secret_lookup_as_utf8("sec0",
157 &error_abort);
158 g_assert_cmpstr(pw, ==, PAYLOAD);
160 object_unparent(sec);
161 g_free(pw);
165 static void test_secret_keyring_revoked_key(void)
167 char key_str[16];
168 Object *sec;
169 int32_t key = add_key("user", DESCRIPTION, PAYLOAD,
170 strlen(PAYLOAD), KEY_SPEC_PROCESS_KEYRING);
171 g_assert(key >= 0);
172 g_assert_false(keyctl_revoke(key));
174 snprintf(key_str, sizeof(key_str), "0x%08x", key);
175 sec = object_new_with_props(
176 TYPE_QCRYPTO_SECRET_KEYRING,
177 object_get_objects_root(),
178 "sec0",
179 NULL,
180 "serial", key_str,
181 NULL);
183 g_assert(errno == EKEYREVOKED);
184 g_assert(sec == NULL);
186 keyctl_unlink(key, KEY_SPEC_PROCESS_KEYRING);
190 static void test_secret_keyring_expired_key(void)
192 char key_str[16];
193 Object *sec;
194 int32_t key = add_key("user", DESCRIPTION, PAYLOAD,
195 strlen(PAYLOAD), KEY_SPEC_PROCESS_KEYRING);
196 g_assert(key >= 0);
197 g_assert_false(keyctl_set_timeout(key, 1));
198 sleep(1);
200 snprintf(key_str, sizeof(key_str), "0x%08x", key);
201 sec = object_new_with_props(
202 TYPE_QCRYPTO_SECRET_KEYRING,
203 object_get_objects_root(),
204 "sec0",
205 NULL,
206 "serial", key_str,
207 NULL);
209 g_assert(errno == EKEYEXPIRED);
210 g_assert(sec == NULL);
212 keyctl_unlink(key, KEY_SPEC_PROCESS_KEYRING);
216 static void test_secret_keyring_bad_serial_key(void)
218 Object *sec;
220 sec = object_new_with_props(
221 TYPE_QCRYPTO_SECRET_KEYRING,
222 object_get_objects_root(),
223 "sec0",
224 NULL,
225 "serial", "1",
226 NULL);
228 g_assert(errno == ENOKEY);
229 g_assert(sec == NULL);
233 * TODO
234 * test_secret_keyring_bad_key_access_right() is not working yet.
235 * We don't know yet if this due a bug in the Linux kernel or
236 * whether it's normal syscall behavior.
237 * We've requested information from kernel maintainers.
238 * See: <https://www.spinics.net/lists/keyrings/index.html>
239 * Thread: 'security/keys: remove possessor verify after key permission check'
242 static void test_secret_keyring_bad_key_access_right(void)
244 char key_str[16];
245 Object *sec;
247 g_test_skip("TODO: Need responce from Linux kernel maintainers");
248 return;
250 int32_t key = add_key("user", DESCRIPTION, PAYLOAD,
251 strlen(PAYLOAD), KEY_SPEC_PROCESS_KEYRING);
252 g_assert(key >= 0);
253 g_assert_false(keyctl_setperm(key, KEY_POS_ALL & (~KEY_POS_READ)));
255 snprintf(key_str, sizeof(key_str), "0x%08x", key);
257 sec = object_new_with_props(
258 TYPE_QCRYPTO_SECRET_KEYRING,
259 object_get_objects_root(),
260 "sec0",
261 NULL,
262 "serial", key_str,
263 NULL);
265 g_assert(errno == EACCES);
266 g_assert(sec == NULL);
268 keyctl_unlink(key, KEY_SPEC_PROCESS_KEYRING);
271 #endif /* CONFIG_TEST_SECRET_KEYRING */
273 static void test_secret_noconv_base64_good(void)
275 Object *sec = object_new_with_props(
276 TYPE_QCRYPTO_SECRET,
277 object_get_objects_root(),
278 "sec0",
279 &error_abort,
280 "data", "MTIzNDU2",
281 "format", "base64",
282 NULL);
284 char *pw = qcrypto_secret_lookup_as_base64("sec0",
285 &error_abort);
287 g_assert_cmpstr(pw, ==, "MTIzNDU2");
289 object_unparent(sec);
290 g_free(pw);
294 static void test_secret_noconv_base64_bad(void)
296 Object *sec = object_new_with_props(
297 TYPE_QCRYPTO_SECRET,
298 object_get_objects_root(),
299 "sec0",
300 NULL,
301 "data", "MTI$NDU2",
302 "format", "base64",
303 NULL);
305 g_assert(sec == NULL);
309 static void test_secret_noconv_utf8(void)
311 Object *sec = object_new_with_props(
312 TYPE_QCRYPTO_SECRET,
313 object_get_objects_root(),
314 "sec0",
315 &error_abort,
316 "data", "123456",
317 "format", "raw",
318 NULL);
320 char *pw = qcrypto_secret_lookup_as_utf8("sec0",
321 &error_abort);
323 g_assert_cmpstr(pw, ==, "123456");
325 object_unparent(sec);
326 g_free(pw);
330 static void test_secret_conv_base64_utf8valid(void)
332 Object *sec = object_new_with_props(
333 TYPE_QCRYPTO_SECRET,
334 object_get_objects_root(),
335 "sec0",
336 &error_abort,
337 "data", "MTIzNDU2",
338 "format", "base64",
339 NULL);
341 char *pw = qcrypto_secret_lookup_as_utf8("sec0",
342 &error_abort);
344 g_assert_cmpstr(pw, ==, "123456");
346 object_unparent(sec);
347 g_free(pw);
351 static void test_secret_conv_base64_utf8invalid(void)
353 Object *sec = object_new_with_props(
354 TYPE_QCRYPTO_SECRET,
355 object_get_objects_root(),
356 "sec0",
357 &error_abort,
358 "data", "f0VMRgIBAQAAAA==",
359 "format", "base64",
360 NULL);
362 char *pw = qcrypto_secret_lookup_as_utf8("sec0",
363 NULL);
364 g_assert(pw == NULL);
366 object_unparent(sec);
370 static void test_secret_conv_utf8_base64(void)
372 Object *sec = object_new_with_props(
373 TYPE_QCRYPTO_SECRET,
374 object_get_objects_root(),
375 "sec0",
376 &error_abort,
377 "data", "123456",
378 NULL);
380 char *pw = qcrypto_secret_lookup_as_base64("sec0",
381 &error_abort);
383 g_assert_cmpstr(pw, ==, "MTIzNDU2");
385 object_unparent(sec);
386 g_free(pw);
390 static void test_secret_crypt_raw(void)
392 Object *master = object_new_with_props(
393 TYPE_QCRYPTO_SECRET,
394 object_get_objects_root(),
395 "master",
396 &error_abort,
397 "data", "9miloPQCzGy+TL6aonfzVcptibCmCIhKzrnlfwiWivk=",
398 "format", "base64",
399 NULL);
400 Object *sec = object_new_with_props(
401 TYPE_QCRYPTO_SECRET,
402 object_get_objects_root(),
403 "sec0",
404 &error_abort,
405 "data",
406 "\xCC\xBF\xF7\x09\x46\x19\x0B\x52\x2A\x3A\xB4\x6B\xCD\x7A\xB0\xB0",
407 "format", "raw",
408 "keyid", "master",
409 "iv", "0I7Gw/TKuA+Old2W2apQ3g==",
410 NULL);
412 char *pw = qcrypto_secret_lookup_as_utf8("sec0",
413 &error_abort);
415 g_assert_cmpstr(pw, ==, "123456");
417 object_unparent(sec);
418 object_unparent(master);
419 g_free(pw);
423 static void test_secret_crypt_base64(void)
425 Object *master = object_new_with_props(
426 TYPE_QCRYPTO_SECRET,
427 object_get_objects_root(),
428 "master",
429 &error_abort,
430 "data", "9miloPQCzGy+TL6aonfzVcptibCmCIhKzrnlfwiWivk=",
431 "format", "base64",
432 NULL);
433 Object *sec = object_new_with_props(
434 TYPE_QCRYPTO_SECRET,
435 object_get_objects_root(),
436 "sec0",
437 &error_abort,
438 "data", "zL/3CUYZC1IqOrRrzXqwsA==",
439 "format", "base64",
440 "keyid", "master",
441 "iv", "0I7Gw/TKuA+Old2W2apQ3g==",
442 NULL);
444 char *pw = qcrypto_secret_lookup_as_utf8("sec0",
445 &error_abort);
447 g_assert_cmpstr(pw, ==, "123456");
449 object_unparent(sec);
450 object_unparent(master);
451 g_free(pw);
455 static void test_secret_crypt_short_key(void)
457 Object *master = object_new_with_props(
458 TYPE_QCRYPTO_SECRET,
459 object_get_objects_root(),
460 "master",
461 &error_abort,
462 "data", "9miloPQCzGy+TL6aonfzVc",
463 "format", "base64",
464 NULL);
465 Object *sec = object_new_with_props(
466 TYPE_QCRYPTO_SECRET,
467 object_get_objects_root(),
468 "sec0",
469 NULL,
470 "data", "zL/3CUYZC1IqOrRrzXqwsA==",
471 "format", "raw",
472 "keyid", "master",
473 "iv", "0I7Gw/TKuA+Old2W2apQ3g==",
474 NULL);
476 g_assert(sec == NULL);
477 object_unparent(master);
481 static void test_secret_crypt_short_iv(void)
483 Object *master = object_new_with_props(
484 TYPE_QCRYPTO_SECRET,
485 object_get_objects_root(),
486 "master",
487 &error_abort,
488 "data", "9miloPQCzGy+TL6aonfzVcptibCmCIhKzrnlfwiWivk=",
489 "format", "base64",
490 NULL);
491 Object *sec = object_new_with_props(
492 TYPE_QCRYPTO_SECRET,
493 object_get_objects_root(),
494 "sec0",
495 NULL,
496 "data", "zL/3CUYZC1IqOrRrzXqwsA==",
497 "format", "raw",
498 "keyid", "master",
499 "iv", "0I7Gw/TKuA+Old2W2a",
500 NULL);
502 g_assert(sec == NULL);
503 object_unparent(master);
507 static void test_secret_crypt_missing_iv(void)
509 Object *master = object_new_with_props(
510 TYPE_QCRYPTO_SECRET,
511 object_get_objects_root(),
512 "master",
513 &error_abort,
514 "data", "9miloPQCzGy+TL6aonfzVcptibCmCIhKzrnlfwiWivk=",
515 "format", "base64",
516 NULL);
517 Object *sec = object_new_with_props(
518 TYPE_QCRYPTO_SECRET,
519 object_get_objects_root(),
520 "sec0",
521 NULL,
522 "data", "zL/3CUYZC1IqOrRrzXqwsA==",
523 "format", "raw",
524 "keyid", "master",
525 NULL);
527 g_assert(sec == NULL);
528 object_unparent(master);
532 static void test_secret_crypt_bad_iv(void)
534 Object *master = object_new_with_props(
535 TYPE_QCRYPTO_SECRET,
536 object_get_objects_root(),
537 "master",
538 &error_abort,
539 "data", "9miloPQCzGy+TL6aonfzVcptibCmCIhKzrnlfwiWivk=",
540 "format", "base64",
541 NULL);
542 Object *sec = object_new_with_props(
543 TYPE_QCRYPTO_SECRET,
544 object_get_objects_root(),
545 "sec0",
546 NULL,
547 "data", "zL/3CUYZC1IqOrRrzXqwsA==",
548 "format", "raw",
549 "keyid", "master",
550 "iv", "0I7Gw/TK$$uA+Old2W2a",
551 NULL);
553 g_assert(sec == NULL);
554 object_unparent(master);
558 int main(int argc, char **argv)
560 module_call_init(MODULE_INIT_QOM);
561 g_test_init(&argc, &argv, NULL);
563 g_assert(qcrypto_init(NULL) == 0);
565 g_test_add_func("/crypto/secret/direct",
566 test_secret_direct);
567 g_test_add_func("/crypto/secret/indirect/good",
568 test_secret_indirect_good);
569 g_test_add_func("/crypto/secret/indirect/badfile",
570 test_secret_indirect_badfile);
571 g_test_add_func("/crypto/secret/indirect/emptyfile",
572 test_secret_indirect_emptyfile);
574 #ifdef CONFIG_TEST_SECRET_KEYRING
575 g_test_add_func("/crypto/secret/keyring/good",
576 test_secret_keyring_good);
577 g_test_add_func("/crypto/secret/keyring/revoked_key",
578 test_secret_keyring_revoked_key);
579 g_test_add_func("/crypto/secret/keyring/expired_key",
580 test_secret_keyring_expired_key);
581 g_test_add_func("/crypto/secret/keyring/bad_serial_key",
582 test_secret_keyring_bad_serial_key);
583 g_test_add_func("/crypto/secret/keyring/bad_key_access_right",
584 test_secret_keyring_bad_key_access_right);
585 #endif /* CONFIG_TEST_SECRET_KEYRING */
587 g_test_add_func("/crypto/secret/noconv/base64/good",
588 test_secret_noconv_base64_good);
589 g_test_add_func("/crypto/secret/noconv/base64/bad",
590 test_secret_noconv_base64_bad);
591 g_test_add_func("/crypto/secret/noconv/utf8",
592 test_secret_noconv_utf8);
593 g_test_add_func("/crypto/secret/conv/base64/utf8valid",
594 test_secret_conv_base64_utf8valid);
595 g_test_add_func("/crypto/secret/conv/base64/utf8invalid",
596 test_secret_conv_base64_utf8invalid);
597 g_test_add_func("/crypto/secret/conv/utf8/base64",
598 test_secret_conv_utf8_base64);
600 g_test_add_func("/crypto/secret/crypt/raw",
601 test_secret_crypt_raw);
602 g_test_add_func("/crypto/secret/crypt/base64",
603 test_secret_crypt_base64);
604 g_test_add_func("/crypto/secret/crypt/shortkey",
605 test_secret_crypt_short_key);
606 g_test_add_func("/crypto/secret/crypt/shortiv",
607 test_secret_crypt_short_iv);
608 g_test_add_func("/crypto/secret/crypt/missingiv",
609 test_secret_crypt_missing_iv);
610 g_test_add_func("/crypto/secret/crypt/badiv",
611 test_secret_crypt_bad_iv);
613 return g_test_run();