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 "crypto/cipher.h" 24 #include "qapi/error.h" 25 #include "qom/object_interfaces.h" 26 #include "qemu/base64.h" 27 #include "qemu/module.h" 28 #include "trace.h" 29 30 31 static void 32 qcrypto_secret_load_data(QCryptoSecret *secret, 33 uint8_t **output, 34 size_t *outputlen, 35 Error **errp) 36 { 37 char *data = NULL; 38 size_t length = 0; 39 GError *gerr = NULL; 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 qcrypto_secret_decrypt(QCryptoSecret *secret, 69 const uint8_t *input, 70 size_t inputlen, 71 uint8_t **output, 72 size_t *outputlen, 73 Error **errp) 74 { 75 g_autofree uint8_t *key = NULL; 76 g_autofree uint8_t *ciphertext = NULL; 77 g_autofree uint8_t *iv = NULL; 78 size_t keylen, ciphertextlen, ivlen; 79 g_autoptr(QCryptoCipher) aes = NULL; 80 g_autofree uint8_t *plaintext = NULL; 81 82 *output = NULL; 83 *outputlen = 0; 84 85 if (qcrypto_secret_lookup(secret->keyid, 86 &key, &keylen, 87 errp) < 0) { 88 return; 89 } 90 91 if (keylen != 32) { 92 error_setg(errp, "Key should be 32 bytes in length"); 93 return; 94 } 95 96 if (!secret->iv) { 97 error_setg(errp, "IV is required to decrypt secret"); 98 return; 99 } 100 101 iv = qbase64_decode(secret->iv, -1, &ivlen, errp); 102 if (!iv) { 103 return; 104 } 105 if (ivlen != 16) { 106 error_setg(errp, "IV should be 16 bytes in length not %zu", 107 ivlen); 108 return; 109 } 110 111 aes = qcrypto_cipher_new(QCRYPTO_CIPHER_ALG_AES_256, 112 QCRYPTO_CIPHER_MODE_CBC, 113 key, keylen, 114 errp); 115 if (!aes) { 116 return; 117 } 118 119 if (qcrypto_cipher_setiv(aes, iv, ivlen, errp) < 0) { 120 return; 121 } 122 123 if (secret->format == QCRYPTO_SECRET_FORMAT_BASE64) { 124 ciphertext = qbase64_decode((const gchar*)input, 125 inputlen, 126 &ciphertextlen, 127 errp); 128 if (!ciphertext) { 129 return; 130 } 131 plaintext = g_new0(uint8_t, ciphertextlen + 1); 132 } else { 133 ciphertextlen = inputlen; 134 plaintext = g_new0(uint8_t, inputlen + 1); 135 } 136 if (qcrypto_cipher_decrypt(aes, 137 ciphertext ? ciphertext : input, 138 plaintext, 139 ciphertextlen, 140 errp) < 0) { 141 return; 142 } 143 144 if (plaintext[ciphertextlen - 1] > 16 || 145 plaintext[ciphertextlen - 1] > ciphertextlen) { 146 error_setg(errp, "Incorrect number of padding bytes (%d) " 147 "found on decrypted data", 148 (int)plaintext[ciphertextlen - 1]); 149 return; 150 } 151 152 /* Even though plaintext may contain arbitrary NUL 153 * ensure it is explicitly NUL terminated. 154 */ 155 ciphertextlen -= plaintext[ciphertextlen - 1]; 156 plaintext[ciphertextlen] = '\0'; 157 158 *output = g_steal_pointer(&plaintext); 159 *outputlen = ciphertextlen; 160 } 161 162 163 static void qcrypto_secret_decode(const uint8_t *input, 164 size_t inputlen, 165 uint8_t **output, 166 size_t *outputlen, 167 Error **errp) 168 { 169 *output = qbase64_decode((const gchar*)input, 170 inputlen, 171 outputlen, 172 errp); 173 } 174 175 176 static void 177 qcrypto_secret_prop_set_loaded(Object *obj, 178 bool value, 179 Error **errp) 180 { 181 QCryptoSecret *secret = QCRYPTO_SECRET(obj); 182 183 if (value) { 184 Error *local_err = NULL; 185 uint8_t *input = NULL; 186 size_t inputlen = 0; 187 uint8_t *output = NULL; 188 size_t outputlen = 0; 189 190 qcrypto_secret_load_data(secret, &input, &inputlen, &local_err); 191 if (local_err) { 192 error_propagate(errp, local_err); 193 return; 194 } 195 196 if (secret->keyid) { 197 qcrypto_secret_decrypt(secret, input, inputlen, 198 &output, &outputlen, &local_err); 199 g_free(input); 200 if (local_err) { 201 error_propagate(errp, local_err); 202 return; 203 } 204 input = output; 205 inputlen = outputlen; 206 } else { 207 if (secret->format != QCRYPTO_SECRET_FORMAT_RAW) { 208 qcrypto_secret_decode(input, inputlen, 209 &output, &outputlen, &local_err); 210 g_free(input); 211 if (local_err) { 212 error_propagate(errp, local_err); 213 return; 214 } 215 input = output; 216 inputlen = outputlen; 217 } 218 } 219 220 secret->rawdata = input; 221 secret->rawlen = inputlen; 222 } else { 223 g_free(secret->rawdata); 224 secret->rawlen = 0; 225 } 226 } 227 228 229 static bool 230 qcrypto_secret_prop_get_loaded(Object *obj, 231 Error **errp G_GNUC_UNUSED) 232 { 233 QCryptoSecret *secret = QCRYPTO_SECRET(obj); 234 return secret->data != NULL; 235 } 236 237 238 static void 239 qcrypto_secret_prop_set_format(Object *obj, 240 int value, 241 Error **errp G_GNUC_UNUSED) 242 { 243 QCryptoSecret *creds = QCRYPTO_SECRET(obj); 244 245 creds->format = value; 246 } 247 248 249 static int 250 qcrypto_secret_prop_get_format(Object *obj, 251 Error **errp G_GNUC_UNUSED) 252 { 253 QCryptoSecret *creds = QCRYPTO_SECRET(obj); 254 255 return creds->format; 256 } 257 258 259 static void 260 qcrypto_secret_prop_set_data(Object *obj, 261 const char *value, 262 Error **errp) 263 { 264 QCryptoSecret *secret = QCRYPTO_SECRET(obj); 265 266 g_free(secret->data); 267 secret->data = g_strdup(value); 268 } 269 270 271 static char * 272 qcrypto_secret_prop_get_data(Object *obj, 273 Error **errp) 274 { 275 QCryptoSecret *secret = QCRYPTO_SECRET(obj); 276 return g_strdup(secret->data); 277 } 278 279 280 static void 281 qcrypto_secret_prop_set_file(Object *obj, 282 const char *value, 283 Error **errp) 284 { 285 QCryptoSecret *secret = QCRYPTO_SECRET(obj); 286 287 g_free(secret->file); 288 secret->file = g_strdup(value); 289 } 290 291 292 static char * 293 qcrypto_secret_prop_get_file(Object *obj, 294 Error **errp) 295 { 296 QCryptoSecret *secret = QCRYPTO_SECRET(obj); 297 return g_strdup(secret->file); 298 } 299 300 301 static void 302 qcrypto_secret_prop_set_iv(Object *obj, 303 const char *value, 304 Error **errp) 305 { 306 QCryptoSecret *secret = QCRYPTO_SECRET(obj); 307 308 g_free(secret->iv); 309 secret->iv = g_strdup(value); 310 } 311 312 313 static char * 314 qcrypto_secret_prop_get_iv(Object *obj, 315 Error **errp) 316 { 317 QCryptoSecret *secret = QCRYPTO_SECRET(obj); 318 return g_strdup(secret->iv); 319 } 320 321 322 static void 323 qcrypto_secret_prop_set_keyid(Object *obj, 324 const char *value, 325 Error **errp) 326 { 327 QCryptoSecret *secret = QCRYPTO_SECRET(obj); 328 329 g_free(secret->keyid); 330 secret->keyid = g_strdup(value); 331 } 332 333 334 static char * 335 qcrypto_secret_prop_get_keyid(Object *obj, 336 Error **errp) 337 { 338 QCryptoSecret *secret = QCRYPTO_SECRET(obj); 339 return g_strdup(secret->keyid); 340 } 341 342 343 static void 344 qcrypto_secret_complete(UserCreatable *uc, Error **errp) 345 { 346 object_property_set_bool(OBJECT(uc), true, "loaded", errp); 347 } 348 349 350 static void 351 qcrypto_secret_finalize(Object *obj) 352 { 353 QCryptoSecret *secret = QCRYPTO_SECRET(obj); 354 355 g_free(secret->iv); 356 g_free(secret->file); 357 g_free(secret->keyid); 358 g_free(secret->rawdata); 359 g_free(secret->data); 360 } 361 362 static void 363 qcrypto_secret_class_init(ObjectClass *oc, void *data) 364 { 365 UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc); 366 367 ucc->complete = qcrypto_secret_complete; 368 369 object_class_property_add_bool(oc, "loaded", 370 qcrypto_secret_prop_get_loaded, 371 qcrypto_secret_prop_set_loaded, 372 NULL); 373 object_class_property_add_enum(oc, "format", 374 "QCryptoSecretFormat", 375 &QCryptoSecretFormat_lookup, 376 qcrypto_secret_prop_get_format, 377 qcrypto_secret_prop_set_format, 378 NULL); 379 object_class_property_add_str(oc, "data", 380 qcrypto_secret_prop_get_data, 381 qcrypto_secret_prop_set_data, 382 NULL); 383 object_class_property_add_str(oc, "file", 384 qcrypto_secret_prop_get_file, 385 qcrypto_secret_prop_set_file, 386 NULL); 387 object_class_property_add_str(oc, "keyid", 388 qcrypto_secret_prop_get_keyid, 389 qcrypto_secret_prop_set_keyid, 390 NULL); 391 object_class_property_add_str(oc, "iv", 392 qcrypto_secret_prop_get_iv, 393 qcrypto_secret_prop_set_iv, 394 NULL); 395 } 396 397 398 int qcrypto_secret_lookup(const char *secretid, 399 uint8_t **data, 400 size_t *datalen, 401 Error **errp) 402 { 403 Object *obj; 404 QCryptoSecret *secret; 405 406 obj = object_resolve_path_component( 407 object_get_objects_root(), secretid); 408 if (!obj) { 409 error_setg(errp, "No secret with id '%s'", secretid); 410 return -1; 411 } 412 413 secret = (QCryptoSecret *) 414 object_dynamic_cast(obj, 415 TYPE_QCRYPTO_SECRET); 416 if (!secret) { 417 error_setg(errp, "Object with id '%s' is not a secret", 418 secretid); 419 return -1; 420 } 421 422 if (!secret->rawdata) { 423 error_setg(errp, "Secret with id '%s' has no data", 424 secretid); 425 return -1; 426 } 427 428 *data = g_new0(uint8_t, secret->rawlen + 1); 429 memcpy(*data, secret->rawdata, secret->rawlen); 430 (*data)[secret->rawlen] = '\0'; 431 *datalen = secret->rawlen; 432 433 return 0; 434 } 435 436 437 char *qcrypto_secret_lookup_as_utf8(const char *secretid, 438 Error **errp) 439 { 440 uint8_t *data; 441 size_t datalen; 442 443 if (qcrypto_secret_lookup(secretid, 444 &data, 445 &datalen, 446 errp) < 0) { 447 return NULL; 448 } 449 450 if (!g_utf8_validate((const gchar*)data, datalen, NULL)) { 451 error_setg(errp, 452 "Data from secret %s is not valid UTF-8", 453 secretid); 454 g_free(data); 455 return NULL; 456 } 457 458 return (char *)data; 459 } 460 461 462 char *qcrypto_secret_lookup_as_base64(const char *secretid, 463 Error **errp) 464 { 465 uint8_t *data; 466 size_t datalen; 467 char *ret; 468 469 if (qcrypto_secret_lookup(secretid, 470 &data, 471 &datalen, 472 errp) < 0) { 473 return NULL; 474 } 475 476 ret = g_base64_encode(data, datalen); 477 g_free(data); 478 return ret; 479 } 480 481 482 static const TypeInfo qcrypto_secret_info = { 483 .parent = TYPE_OBJECT, 484 .name = TYPE_QCRYPTO_SECRET, 485 .instance_size = sizeof(QCryptoSecret), 486 .instance_finalize = qcrypto_secret_finalize, 487 .class_size = sizeof(QCryptoSecretClass), 488 .class_init = qcrypto_secret_class_init, 489 .interfaces = (InterfaceInfo[]) { 490 { TYPE_USER_CREATABLE }, 491 { } 492 } 493 }; 494 495 496 static void 497 qcrypto_secret_register_types(void) 498 { 499 type_register_static(&qcrypto_secret_info); 500 } 501 502 503 type_init(qcrypto_secret_register_types); 504