qemu

Форк
0
/
tlscreds.c 
294 строки · 8.0 Кб
1
/*
2
 * QEMU crypto TLS credential 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 "qapi/error.h"
23
#include "qapi-types-crypto.h"
24
#include "qemu/module.h"
25
#include "tlscredspriv.h"
26
#include "trace.h"
27

28
#define DH_BITS 2048
29

30
#ifdef CONFIG_GNUTLS
31
int
32
qcrypto_tls_creds_get_dh_params_file(QCryptoTLSCreds *creds,
33
                                     const char *filename,
34
                                     gnutls_dh_params_t *dh_params,
35
                                     Error **errp)
36
{
37
    int ret;
38

39
    trace_qcrypto_tls_creds_load_dh(creds, filename ? filename : "<generated>");
40

41
    if (filename == NULL) {
42
        ret = gnutls_dh_params_init(dh_params);
43
        if (ret < 0) {
44
            error_setg(errp, "Unable to initialize DH parameters: %s",
45
                       gnutls_strerror(ret));
46
            return -1;
47
        }
48
        ret = gnutls_dh_params_generate2(*dh_params, DH_BITS);
49
        if (ret < 0) {
50
            gnutls_dh_params_deinit(*dh_params);
51
            *dh_params = NULL;
52
            error_setg(errp, "Unable to generate DH parameters: %s",
53
                       gnutls_strerror(ret));
54
            return -1;
55
        }
56
    } else {
57
        GError *gerr = NULL;
58
        gchar *contents;
59
        gsize len;
60
        gnutls_datum_t data;
61
        if (!g_file_get_contents(filename,
62
                                 &contents,
63
                                 &len,
64
                                 &gerr)) {
65

66
            error_setg(errp, "%s", gerr->message);
67
            g_error_free(gerr);
68
            return -1;
69
        }
70
        data.data = (unsigned char *)contents;
71
        data.size = len;
72
        ret = gnutls_dh_params_init(dh_params);
73
        if (ret < 0) {
74
            g_free(contents);
75
            error_setg(errp, "Unable to initialize DH parameters: %s",
76
                       gnutls_strerror(ret));
77
            return -1;
78
        }
79
        ret = gnutls_dh_params_import_pkcs3(*dh_params,
80
                                            &data,
81
                                            GNUTLS_X509_FMT_PEM);
82
        g_free(contents);
83
        if (ret < 0) {
84
            gnutls_dh_params_deinit(*dh_params);
85
            *dh_params = NULL;
86
            error_setg(errp, "Unable to load DH parameters from %s: %s",
87
                       filename, gnutls_strerror(ret));
88
            return -1;
89
        }
90
    }
91

92
    return 0;
93
}
94

95

96
int
97
qcrypto_tls_creds_get_path(QCryptoTLSCreds *creds,
98
                           const char *filename,
99
                           bool required,
100
                           char **cred,
101
                           Error **errp)
102
{
103
    struct stat sb;
104
    int ret = -1;
105

106
    if (!creds->dir) {
107
        if (required) {
108
            error_setg(errp, "Missing 'dir' property value");
109
            return -1;
110
        } else {
111
            return 0;
112
        }
113
    }
114

115
    *cred = g_strdup_printf("%s/%s", creds->dir, filename);
116

117
    if (stat(*cred, &sb) < 0) {
118
        if (errno == ENOENT && !required) {
119
            ret = 0;
120
        } else {
121
            error_setg_errno(errp, errno,
122
                             "Unable to access credentials %s",
123
                             *cred);
124
        }
125
        g_free(*cred);
126
        *cred = NULL;
127
        goto cleanup;
128
    }
129

130
    ret = 0;
131
 cleanup:
132
    trace_qcrypto_tls_creds_get_path(creds, filename,
133
                                     *cred ? *cred : "<none>");
134
    return ret;
135
}
136

137

138
#endif /* ! CONFIG_GNUTLS */
139

140

141
static void
142
qcrypto_tls_creds_prop_set_verify(Object *obj,
143
                                  bool value,
144
                                  Error **errp G_GNUC_UNUSED)
145
{
146
    QCryptoTLSCreds *creds = QCRYPTO_TLS_CREDS(obj);
147

148
    creds->verifyPeer = value;
149
}
150

151

152
static bool
153
qcrypto_tls_creds_prop_get_verify(Object *obj,
154
                                  Error **errp G_GNUC_UNUSED)
155
{
156
    QCryptoTLSCreds *creds = QCRYPTO_TLS_CREDS(obj);
157

158
    return creds->verifyPeer;
159
}
160

161

162
static void
163
qcrypto_tls_creds_prop_set_dir(Object *obj,
164
                               const char *value,
165
                               Error **errp G_GNUC_UNUSED)
166
{
167
    QCryptoTLSCreds *creds = QCRYPTO_TLS_CREDS(obj);
168

169
    creds->dir = g_strdup(value);
170
}
171

172

173
static char *
174
qcrypto_tls_creds_prop_get_dir(Object *obj,
175
                               Error **errp G_GNUC_UNUSED)
176
{
177
    QCryptoTLSCreds *creds = QCRYPTO_TLS_CREDS(obj);
178

179
    return g_strdup(creds->dir);
180
}
181

182

183
static void
184
qcrypto_tls_creds_prop_set_priority(Object *obj,
185
                                    const char *value,
186
                                    Error **errp G_GNUC_UNUSED)
187
{
188
    QCryptoTLSCreds *creds = QCRYPTO_TLS_CREDS(obj);
189

190
    creds->priority = g_strdup(value);
191
}
192

193

194
static char *
195
qcrypto_tls_creds_prop_get_priority(Object *obj,
196
                                    Error **errp G_GNUC_UNUSED)
197
{
198
    QCryptoTLSCreds *creds = QCRYPTO_TLS_CREDS(obj);
199

200
    return g_strdup(creds->priority);
201
}
202

203

204
static void
205
qcrypto_tls_creds_prop_set_endpoint(Object *obj,
206
                                    int value,
207
                                    Error **errp G_GNUC_UNUSED)
208
{
209
    QCryptoTLSCreds *creds = QCRYPTO_TLS_CREDS(obj);
210

211
    creds->endpoint = value;
212
}
213

214

215
static int
216
qcrypto_tls_creds_prop_get_endpoint(Object *obj,
217
                                    Error **errp G_GNUC_UNUSED)
218
{
219
    QCryptoTLSCreds *creds = QCRYPTO_TLS_CREDS(obj);
220

221
    return creds->endpoint;
222
}
223

224

225
static void
226
qcrypto_tls_creds_class_init(ObjectClass *oc, void *data)
227
{
228
    object_class_property_add_bool(oc, "verify-peer",
229
                                   qcrypto_tls_creds_prop_get_verify,
230
                                   qcrypto_tls_creds_prop_set_verify);
231
    object_class_property_add_str(oc, "dir",
232
                                  qcrypto_tls_creds_prop_get_dir,
233
                                  qcrypto_tls_creds_prop_set_dir);
234
    object_class_property_add_enum(oc, "endpoint",
235
                                   "QCryptoTLSCredsEndpoint",
236
                                   &QCryptoTLSCredsEndpoint_lookup,
237
                                   qcrypto_tls_creds_prop_get_endpoint,
238
                                   qcrypto_tls_creds_prop_set_endpoint);
239
    object_class_property_add_str(oc, "priority",
240
                                  qcrypto_tls_creds_prop_get_priority,
241
                                  qcrypto_tls_creds_prop_set_priority);
242
}
243

244

245
static void
246
qcrypto_tls_creds_init(Object *obj)
247
{
248
    QCryptoTLSCreds *creds = QCRYPTO_TLS_CREDS(obj);
249

250
    creds->verifyPeer = true;
251
}
252

253

254
static void
255
qcrypto_tls_creds_finalize(Object *obj)
256
{
257
    QCryptoTLSCreds *creds = QCRYPTO_TLS_CREDS(obj);
258

259
    g_free(creds->dir);
260
    g_free(creds->priority);
261
}
262

263
bool qcrypto_tls_creds_check_endpoint(QCryptoTLSCreds *creds,
264
                                      QCryptoTLSCredsEndpoint endpoint,
265
                                      Error **errp)
266
{
267
    if (creds->endpoint != endpoint) {
268
        error_setg(errp, "Expected TLS credentials for a %s endpoint",
269
                   QCryptoTLSCredsEndpoint_str(endpoint));
270
        return false;
271
    }
272
    return true;
273
}
274

275
static const TypeInfo qcrypto_tls_creds_info = {
276
    .parent = TYPE_OBJECT,
277
    .name = TYPE_QCRYPTO_TLS_CREDS,
278
    .instance_size = sizeof(QCryptoTLSCreds),
279
    .instance_init = qcrypto_tls_creds_init,
280
    .instance_finalize = qcrypto_tls_creds_finalize,
281
    .class_init = qcrypto_tls_creds_class_init,
282
    .class_size = sizeof(QCryptoTLSCredsClass),
283
    .abstract = true,
284
};
285

286

287
static void
288
qcrypto_tls_creds_register_types(void)
289
{
290
    type_register_static(&qcrypto_tls_creds_info);
291
}
292

293

294
type_init(qcrypto_tls_creds_register_types);
295

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.