* Remove individual option fields. Common field have been left. Signed-off-by: Alexey Krasikov <alex-krasi...@yandex-team.ru> --- crypto/Makefile.objs | 1 + crypto/secret_interface.c | 156 ++++++------------------------ include/crypto/secret_interface.h | 119 ++++------------------- 3 files changed, 51 insertions(+), 225 deletions(-)
diff --git a/crypto/Makefile.objs b/crypto/Makefile.objs index c2a371b0b4..3ae0dfd1a4 100644 --- a/crypto/Makefile.objs +++ b/crypto/Makefile.objs @@ -18,6 +18,7 @@ crypto-obj-y += tlscredsanon.o crypto-obj-y += tlscredspsk.o crypto-obj-y += tlscredsx509.o crypto-obj-y += tlssession.o +crypto-obj-y += secret_interface.o crypto-obj-y += secret.o crypto-obj-y += pbkdf.o crypto-obj-$(CONFIG_NETTLE) += pbkdf-nettle.o diff --git a/crypto/secret_interface.c b/crypto/secret_interface.c index 1cf0ad0ce8..9d8accdea3 100644 --- a/crypto/secret_interface.c +++ b/crypto/secret_interface.c @@ -19,7 +19,7 @@ */ #include "qemu/osdep.h" -#include "crypto/secret.h" +#include "crypto/secret_interface.h" #include "crypto/cipher.h" #include "qapi/error.h" #include "qom/object_interfaces.h" @@ -28,44 +28,7 @@ #include "trace.h" -static void -qcrypto_secret_load_data(QCryptoSecret *secret, - uint8_t **output, - size_t *outputlen, - Error **errp) -{ - char *data = NULL; - size_t length = 0; - GError *gerr = NULL; - - *output = NULL; - *outputlen = 0; - - if (secret->file) { - if (secret->data) { - error_setg(errp, - "'file' and 'data' are mutually exclusive"); - return; - } - if (!g_file_get_contents(secret->file, &data, &length, &gerr)) { - error_setg(errp, - "Unable to read %s: %s", - secret->file, gerr->message); - g_error_free(gerr); - return; - } - *output = (uint8_t *)data; - *outputlen = length; - } else if (secret->data) { - *outputlen = strlen(secret->data); - *output = (uint8_t *)g_strdup(secret->data); - } else { - error_setg(errp, "Either 'file' or 'data' must be provided"); - } -} - - -static void qcrypto_secret_decrypt(QCryptoSecret *secret, +static void qcrypto_secret_decrypt(QCryptoSecretCommon *secret, const uint8_t *input, size_t inputlen, uint8_t **output, @@ -178,7 +141,9 @@ qcrypto_secret_prop_set_loaded(Object *obj, bool value, Error **errp) { - QCryptoSecret *secret = QCRYPTO_SECRET(obj); + QCryptoSecretCommon *secret = QCRYPTO_SECRET_COMMON(obj); + QCryptoSecretCommonClass *sec_class + = QCRYPTO_SECRET_COMMON_GET_CLASS(obj); if (value) { Error *local_err = NULL; @@ -187,9 +152,14 @@ qcrypto_secret_prop_set_loaded(Object *obj, uint8_t *output = NULL; size_t outputlen = 0; - qcrypto_secret_load_data(secret, &input, &inputlen, &local_err); - if (local_err) { - error_propagate(errp, local_err); + if (sec_class->load_data) { + sec_class->load_data(obj, &input, &inputlen, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + } else { + error_setg(errp, "'load_data' metod has not been initiated"); return; } @@ -230,7 +200,7 @@ static bool qcrypto_secret_prop_get_loaded(Object *obj, Error **errp G_GNUC_UNUSED) { - QCryptoSecret *secret = QCRYPTO_SECRET(obj); + QCryptoSecretCommon *secret = QCRYPTO_SECRET_COMMON(obj); return secret->data != NULL; } @@ -240,7 +210,7 @@ qcrypto_secret_prop_set_format(Object *obj, int value, Error **errp G_GNUC_UNUSED) { - QCryptoSecret *creds = QCRYPTO_SECRET(obj); + QCryptoSecretCommon *creds = QCRYPTO_SECRET_COMMON(obj); creds->format = value; } @@ -250,60 +220,18 @@ static int qcrypto_secret_prop_get_format(Object *obj, Error **errp G_GNUC_UNUSED) { - QCryptoSecret *creds = QCRYPTO_SECRET(obj); + QCryptoSecretCommon *creds = QCRYPTO_SECRET_COMMON(obj); return creds->format; } -static void -qcrypto_secret_prop_set_data(Object *obj, - const char *value, - Error **errp) -{ - QCryptoSecret *secret = QCRYPTO_SECRET(obj); - - g_free(secret->data); - secret->data = g_strdup(value); -} - - -static char * -qcrypto_secret_prop_get_data(Object *obj, - Error **errp) -{ - QCryptoSecret *secret = QCRYPTO_SECRET(obj); - return g_strdup(secret->data); -} - - -static void -qcrypto_secret_prop_set_file(Object *obj, - const char *value, - Error **errp) -{ - QCryptoSecret *secret = QCRYPTO_SECRET(obj); - - g_free(secret->file); - secret->file = g_strdup(value); -} - - -static char * -qcrypto_secret_prop_get_file(Object *obj, - Error **errp) -{ - QCryptoSecret *secret = QCRYPTO_SECRET(obj); - return g_strdup(secret->file); -} - - static void qcrypto_secret_prop_set_iv(Object *obj, const char *value, Error **errp) { - QCryptoSecret *secret = QCRYPTO_SECRET(obj); + QCryptoSecretCommon *secret = QCRYPTO_SECRET_COMMON(obj); g_free(secret->iv); secret->iv = g_strdup(value); @@ -314,7 +242,7 @@ static char * qcrypto_secret_prop_get_iv(Object *obj, Error **errp) { - QCryptoSecret *secret = QCRYPTO_SECRET(obj); + QCryptoSecretCommon *secret = QCRYPTO_SECRET_COMMON(obj); return g_strdup(secret->iv); } @@ -324,7 +252,7 @@ qcrypto_secret_prop_set_keyid(Object *obj, const char *value, Error **errp) { - QCryptoSecret *secret = QCRYPTO_SECRET(obj); + QCryptoSecretCommon *secret = QCRYPTO_SECRET_COMMON(obj); g_free(secret->keyid); secret->keyid = g_strdup(value); @@ -335,37 +263,24 @@ static char * qcrypto_secret_prop_get_keyid(Object *obj, Error **errp) { - QCryptoSecret *secret = QCRYPTO_SECRET(obj); + QCryptoSecretCommon *secret = QCRYPTO_SECRET_COMMON(obj); return g_strdup(secret->keyid); } -static void -qcrypto_secret_complete(UserCreatable *uc, Error **errp) -{ - object_property_set_bool(OBJECT(uc), true, "loaded", errp); -} - - static void qcrypto_secret_finalize(Object *obj) { - QCryptoSecret *secret = QCRYPTO_SECRET(obj); + QCryptoSecretCommon *secret = QCRYPTO_SECRET_COMMON(obj); g_free(secret->iv); - g_free(secret->file); g_free(secret->keyid); g_free(secret->rawdata); - g_free(secret->data); } static void qcrypto_secret_class_init(ObjectClass *oc, void *data) { - UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc); - - ucc->complete = qcrypto_secret_complete; - object_class_property_add_bool(oc, "loaded", qcrypto_secret_prop_get_loaded, qcrypto_secret_prop_set_loaded, @@ -376,14 +291,6 @@ qcrypto_secret_class_init(ObjectClass *oc, void *data) qcrypto_secret_prop_get_format, qcrypto_secret_prop_set_format, NULL); - object_class_property_add_str(oc, "data", - qcrypto_secret_prop_get_data, - qcrypto_secret_prop_set_data, - NULL); - object_class_property_add_str(oc, "file", - qcrypto_secret_prop_get_file, - qcrypto_secret_prop_set_file, - NULL); object_class_property_add_str(oc, "keyid", qcrypto_secret_prop_get_keyid, qcrypto_secret_prop_set_keyid, @@ -401,7 +308,7 @@ int qcrypto_secret_lookup(const char *secretid, Error **errp) { Object *obj; - QCryptoSecret *secret; + QCryptoSecretCommon *secret; obj = object_resolve_path_component( object_get_objects_root(), secretid); @@ -410,9 +317,9 @@ int qcrypto_secret_lookup(const char *secretid, return -1; } - secret = (QCryptoSecret *) + secret = (QCryptoSecretCommon *) object_dynamic_cast(obj, - TYPE_QCRYPTO_SECRET); + TYPE_QCRYPTO_SECRET_COMMON); if (!secret) { error_setg(errp, "Object with id '%s' is not a secret", secretid); @@ -480,16 +387,13 @@ char *qcrypto_secret_lookup_as_base64(const char *secretid, static const TypeInfo qcrypto_secret_info = { - .parent = TYPE_OBJECT, - .name = TYPE_QCRYPTO_SECRET, - .instance_size = sizeof(QCryptoSecret), + .parent = TYPE_OBJECT, + .name = TYPE_QCRYPTO_SECRET_COMMON, + .instance_size = sizeof(QCryptoSecretCommon), .instance_finalize = qcrypto_secret_finalize, - .class_size = sizeof(QCryptoSecretClass), - .class_init = qcrypto_secret_class_init, - .interfaces = (InterfaceInfo[]) { - { TYPE_USER_CREATABLE }, - { } - } + .class_size = sizeof(QCryptoSecretCommonClass), + .class_init = qcrypto_secret_class_init, + .abstract = true, }; diff --git a/include/crypto/secret_interface.h b/include/crypto/secret_interface.h index 5e07e29bae..4cd20503d5 100644 --- a/include/crypto/secret_interface.h +++ b/include/crypto/secret_interface.h @@ -18,120 +18,41 @@ * */ -#ifndef QCRYPTO_SECRET_H -#define QCRYPTO_SECRET_H +#ifndef QCRYPTO_SECRET_COMMON_H +#define QCRYPTO_SECRET_COMMON_H #include "qapi/qapi-types-crypto.h" #include "qom/object.h" -#define TYPE_QCRYPTO_SECRET "secret" -#define QCRYPTO_SECRET(obj) \ - OBJECT_CHECK(QCryptoSecret, (obj), TYPE_QCRYPTO_SECRET) +#define TYPE_QCRYPTO_SECRET_COMMON "secret_common" +#define QCRYPTO_SECRET_COMMON(obj) \ + OBJECT_CHECK(QCryptoSecretCommon, (obj), TYPE_QCRYPTO_SECRET_COMMON) +#define QCRYPTO_SECRET_COMMON_CLASS(class) \ + OBJECT_CLASS_CHECK(QCryptoSecretCommonClass, \ + (class), TYPE_QCRYPTO_SECRET_COMMON) +#define QCRYPTO_SECRET_COMMON_GET_CLASS(obj) \ + OBJECT_GET_CLASS(QCryptoSecretCommonClass, \ + (obj), TYPE_QCRYPTO_SECRET_COMMON) -typedef struct QCryptoSecret QCryptoSecret; -typedef struct QCryptoSecretClass QCryptoSecretClass; +typedef struct QCryptoSecretCommon QCryptoSecretCommon; +typedef struct QCryptoSecretCommonClass QCryptoSecretCommonClass; -/** - * QCryptoSecret: - * - * The QCryptoSecret object provides storage of secrets, - * which may be user passwords, encryption keys or any - * other kind of sensitive data that is represented as - * a sequence of bytes. - * - * The sensitive data associated with the secret can - * be provided directly via the 'data' property, or - * indirectly via the 'file' property. In the latter - * case there is support for file descriptor passing - * via the usual /dev/fdset/NN syntax that QEMU uses. - * - * The data for a secret can be provided in two formats, - * either as a UTF-8 string (the default), or as base64 - * encoded 8-bit binary data. The latter is appropriate - * for raw encryption keys, while the former is appropriate - * for user entered passwords. - * - * The data may be optionally encrypted with AES-256-CBC, - * and the decryption key provided by another - * QCryptoSecret instance identified by the 'keyid' - * property. When passing sensitive data directly - * via the 'data' property it is strongly recommended - * to use the AES encryption facility to prevent the - * sensitive data being exposed in the process listing - * or system log files. - * - * Providing data directly, insecurely (suitable for - * ad hoc developer testing only) - * - * $QEMU -object secret,id=sec0,data=letmein - * - * Providing data indirectly: - * - * # printf "letmein" > password.txt - * # $QEMU \ - * -object secret,id=sec0,file=password.txt - * - * Using a master encryption key with data. - * - * The master key needs to be created as 32 secure - * random bytes (optionally base64 encoded) - * - * # openssl rand -base64 32 > key.b64 - * # KEY=$(base64 -d key.b64 | hexdump -v -e '/1 "%02X"') - * - * Each secret to be encrypted needs to have a random - * initialization vector generated. These do not need - * to be kept secret - * - * # openssl rand -base64 16 > iv.b64 - * # IV=$(base64 -d iv.b64 | hexdump -v -e '/1 "%02X"') - * - * A secret to be defined can now be encrypted - * - * # SECRET=$(printf "letmein" | - * openssl enc -aes-256-cbc -a -K $KEY -iv $IV) - * - * When launching QEMU, create a master secret pointing - * to key.b64 and specify that to be used to decrypt - * the user password - * - * # $QEMU \ - * -object secret,id=secmaster0,format=base64,file=key.b64 \ - * -object secret,id=sec0,keyid=secmaster0,format=base64,\ - * data=$SECRET,iv=$(<iv.b64) - * - * When encrypting, the data can still be provided via an - * external file, in which case it is possible to use either - * raw binary data, or base64 encoded. This example uses - * raw format - * - * # printf "letmein" | - * openssl enc -aes-256-cbc -K $KEY -iv $IV -o pw.aes - * # $QEMU \ - * -object secret,id=secmaster0,format=base64,file=key.b64 \ - * -object secret,id=sec0,keyid=secmaster0,\ - * file=pw.aes,iv=$(<iv.b64) - * - * Note that the ciphertext can be in either raw or base64 - * format, as indicated by the 'format' parameter, but the - * plaintext resulting from decryption is expected to always - * be in raw format. - */ - -struct QCryptoSecret { +struct QCryptoSecretCommon { Object parent_obj; uint8_t *rawdata; size_t rawlen; QCryptoSecretFormat format; - char *data; - char *file; char *keyid; char *iv; }; -struct QCryptoSecretClass { +struct QCryptoSecretCommonClass { ObjectClass parent_class; + void (*load_data)(Object *obj, + uint8_t **output, + size_t *outputlen, + Error **errp); }; @@ -144,4 +65,4 @@ extern char *qcrypto_secret_lookup_as_utf8(const char *secretid, extern char *qcrypto_secret_lookup_as_base64(const char *secretid, Error **errp); -#endif /* QCRYPTO_SECRET_H */ +#endif /* QCRYPTO_SECRET_COMMON_H */ -- 2.17.1