qemu/crypto/secret.c
<<
>>
Prefs
   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
  29static void
  30qcrypto_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
  68static void
  69qcrypto_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
  80static char *
  81qcrypto_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
  89static void
  90qcrypto_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
 101static char *
 102qcrypto_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
 110static void
 111qcrypto_secret_finalize(Object *obj)
 112{
 113    QCryptoSecret *secret = QCRYPTO_SECRET(obj);
 114
 115    g_free(secret->file);
 116    g_free(secret->data);
 117}
 118
 119static void
 120qcrypto_secret_class_init(ObjectClass *oc, void *data)
 121{
 122    QCryptoSecretCommonClass *sic = QCRYPTO_SECRET_COMMON_CLASS(oc);
 123    sic->load_data = qcrypto_secret_load_data;
 124
 125    object_class_property_add_str(oc, "data",
 126                                  qcrypto_secret_prop_get_data,
 127                                  qcrypto_secret_prop_set_data);
 128    object_class_property_add_str(oc, "file",
 129                                  qcrypto_secret_prop_get_file,
 130                                  qcrypto_secret_prop_set_file);
 131}
 132
 133
 134static const TypeInfo qcrypto_secret_info = {
 135    .parent = TYPE_QCRYPTO_SECRET_COMMON,
 136    .name = TYPE_QCRYPTO_SECRET,
 137    .instance_size = sizeof(QCryptoSecret),
 138    .instance_finalize = qcrypto_secret_finalize,
 139    .class_size = sizeof(QCryptoSecretClass),
 140    .class_init = qcrypto_secret_class_init,
 141};
 142
 143
 144static void
 145qcrypto_secret_register_types(void)
 146{
 147    type_register_static(&qcrypto_secret_info);
 148}
 149
 150
 151type_init(qcrypto_secret_register_types);
 152