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.1 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 21 #include "qemu/osdep.h" 22 #include "crypto/secret.h" 23 #include "qapi/error.h" 24 #include "qom/object_interfaces.h" 25 #include "qemu/module.h" 26 #include "trace.h" 27 28 29 static void 30 qcrypto_secret_load_data(QCryptoSecretCommon *sec_common, 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 39 QCryptoSecret *secret = QCRYPTO_SECRET(sec_common); 40 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 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 110 static void 111 qcrypto_secret_complete(UserCreatable *uc, Error **errp) 112 { 113 object_property_set_bool(OBJECT(uc), true, "loaded", errp); 114 } 115 116 117 static void 118 qcrypto_secret_finalize(Object *obj) 119 { 120 QCryptoSecret *secret = QCRYPTO_SECRET(obj); 121 122 g_free(secret->file); 123 g_free(secret->data); 124 } 125 126 static void 127 qcrypto_secret_class_init(ObjectClass *oc, void *data) 128 { 129 QCryptoSecretCommonClass *sic = QCRYPTO_SECRET_COMMON_CLASS(oc); 130 sic->load_data = qcrypto_secret_load_data; 131 132 UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc); 133 ucc->complete = qcrypto_secret_complete; 134 135 object_class_property_add_str(oc, "data", 136 qcrypto_secret_prop_get_data, 137 qcrypto_secret_prop_set_data); 138 object_class_property_add_str(oc, "file", 139 qcrypto_secret_prop_get_file, 140 qcrypto_secret_prop_set_file); 141 } 142 143 144 static const TypeInfo qcrypto_secret_info = { 145 .parent = TYPE_QCRYPTO_SECRET_COMMON, 146 .name = TYPE_QCRYPTO_SECRET, 147 .instance_size = sizeof(QCryptoSecret), 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); 166