]>
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 | |
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 | ||
2a6a4076 MA |
21 | #ifndef QCRYPTO_SECRET_H |
22 | #define QCRYPTO_SECRET_H | |
ac1d8878 | 23 | |
ac1d8878 DB |
24 | #include "qom/object.h" |
25 | ||
26 | #define TYPE_QCRYPTO_SECRET "secret" | |
27 | #define QCRYPTO_SECRET(obj) \ | |
28 | OBJECT_CHECK(QCryptoSecret, (obj), TYPE_QCRYPTO_SECRET) | |
29 | ||
30 | typedef struct QCryptoSecret QCryptoSecret; | |
31 | typedef struct QCryptoSecretClass QCryptoSecretClass; | |
32 | ||
33 | /** | |
34 | * QCryptoSecret: | |
35 | * | |
36 | * The QCryptoSecret object provides storage of secrets, | |
37 | * which may be user passwords, encryption keys or any | |
38 | * other kind of sensitive data that is represented as | |
39 | * a sequence of bytes. | |
40 | * | |
41 | * The sensitive data associated with the secret can | |
42 | * be provided directly via the 'data' property, or | |
43 | * indirectly via the 'file' property. In the latter | |
44 | * case there is support for file descriptor passing | |
45 | * via the usual /dev/fdset/NN syntax that QEMU uses. | |
46 | * | |
47 | * The data for a secret can be provided in two formats, | |
48 | * either as a UTF-8 string (the default), or as base64 | |
49 | * encoded 8-bit binary data. The latter is appropriate | |
50 | * for raw encryption keys, while the former is appropriate | |
51 | * for user entered passwords. | |
52 | * | |
53 | * The data may be optionally encrypted with AES-256-CBC, | |
54 | * and the decryption key provided by another | |
55 | * QCryptoSecret instance identified by the 'keyid' | |
56 | * property. When passing sensitive data directly | |
57 | * via the 'data' property it is strongly recommended | |
58 | * to use the AES encryption facility to prevent the | |
59 | * sensitive data being exposed in the process listing | |
60 | * or system log files. | |
61 | * | |
62 | * Providing data directly, insecurely (suitable for | |
63 | * ad hoc developer testing only) | |
64 | * | |
65 | * $QEMU -object secret,id=sec0,data=letmein | |
66 | * | |
67 | * Providing data indirectly: | |
68 | * | |
69 | * # printf "letmein" > password.txt | |
70 | * # $QEMU \ | |
71 | * -object secret,id=sec0,file=password.txt | |
72 | * | |
73 | * Using a master encryption key with data. | |
74 | * | |
75 | * The master key needs to be created as 32 secure | |
76 | * random bytes (optionally base64 encoded) | |
77 | * | |
78 | * # openssl rand -base64 32 > key.b64 | |
79 | * # KEY=$(base64 -d key.b64 | hexdump -v -e '/1 "%02X"') | |
80 | * | |
81 | * Each secret to be encrypted needs to have a random | |
82 | * initialization vector generated. These do not need | |
83 | * to be kept secret | |
84 | * | |
85 | * # openssl rand -base64 16 > iv.b64 | |
86 | * # IV=$(base64 -d iv.b64 | hexdump -v -e '/1 "%02X"') | |
87 | * | |
88 | * A secret to be defined can now be encrypted | |
89 | * | |
90 | * # SECRET=$(printf "letmein" | | |
91 | * openssl enc -aes-256-cbc -a -K $KEY -iv $IV) | |
92 | * | |
93 | * When launching QEMU, create a master secret pointing | |
94 | * to key.b64 and specify that to be used to decrypt | |
95 | * the user password | |
96 | * | |
97 | * # $QEMU \ | |
98 | * -object secret,id=secmaster0,format=base64,file=key.b64 \ | |
99 | * -object secret,id=sec0,keyid=secmaster0,format=base64,\ | |
100 | * data=$SECRET,iv=$(<iv.b64) | |
101 | * | |
102 | * When encrypting, the data can still be provided via an | |
103 | * external file, in which case it is possible to use either | |
104 | * raw binary data, or base64 encoded. This example uses | |
105 | * raw format | |
106 | * | |
107 | * # printf "letmein" | | |
108 | * openssl enc -aes-256-cbc -K $KEY -iv $IV -o pw.aes | |
109 | * # $QEMU \ | |
110 | * -object secret,id=secmaster0,format=base64,file=key.b64 \ | |
111 | * -object secret,id=sec0,keyid=secmaster0,\ | |
112 | * file=pw.aes,iv=$(<iv.b64) | |
113 | * | |
114 | * Note that the ciphertext can be in either raw or base64 | |
115 | * format, as indicated by the 'format' parameter, but the | |
116 | * plaintext resulting from decryption is expected to always | |
117 | * be in raw format. | |
118 | */ | |
119 | ||
120 | struct QCryptoSecret { | |
121 | Object parent_obj; | |
122 | uint8_t *rawdata; | |
123 | size_t rawlen; | |
124 | QCryptoSecretFormat format; | |
125 | char *data; | |
126 | char *file; | |
127 | char *keyid; | |
128 | char *iv; | |
129 | }; | |
130 | ||
131 | ||
132 | struct QCryptoSecretClass { | |
133 | ObjectClass parent_class; | |
134 | }; | |
135 | ||
136 | ||
137 | extern int qcrypto_secret_lookup(const char *secretid, | |
138 | uint8_t **data, | |
139 | size_t *datalen, | |
140 | Error **errp); | |
141 | extern char *qcrypto_secret_lookup_as_utf8(const char *secretid, | |
142 | Error **errp); | |
143 | extern char *qcrypto_secret_lookup_as_base64(const char *secretid, | |
144 | Error **errp); | |
145 | ||
2a6a4076 | 146 | #endif /* QCRYPTO_SECRET_H */ |