tlssession.c (393aac1629c8f82b7c448c8615745e89984899a8) tlssession.c (b76806d4ec5c55d36bf5508f1405d132a4b862de)
1/*
2 * QEMU crypto TLS session 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

--- 10 unchanged lines hidden (view full) ---

19 */
20
21#include "qemu/osdep.h"
22#include "crypto/tlssession.h"
23#include "crypto/tlscredsanon.h"
24#include "crypto/tlscredspsk.h"
25#include "crypto/tlscredsx509.h"
26#include "qapi/error.h"
1/*
2 * QEMU crypto TLS session 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

--- 10 unchanged lines hidden (view full) ---

19 */
20
21#include "qemu/osdep.h"
22#include "crypto/tlssession.h"
23#include "crypto/tlscredsanon.h"
24#include "crypto/tlscredspsk.h"
25#include "crypto/tlscredsx509.h"
26#include "qapi/error.h"
27#include "qemu/acl.h"
27#include "authz/base.h"
28#include "trace.h"
29
30#ifdef CONFIG_GNUTLS
31
32
33#include <gnutls/x509.h>
34
35
36struct QCryptoTLSSession {
37 QCryptoTLSCreds *creds;
38 gnutls_session_t handle;
39 char *hostname;
28#include "trace.h"
29
30#ifdef CONFIG_GNUTLS
31
32
33#include <gnutls/x509.h>
34
35
36struct QCryptoTLSSession {
37 QCryptoTLSCreds *creds;
38 gnutls_session_t handle;
39 char *hostname;
40 char *aclname;
40 char *authzid;
41 bool handshakeComplete;
42 QCryptoTLSSessionWriteFunc writeFunc;
43 QCryptoTLSSessionReadFunc readFunc;
44 void *opaque;
45 char *peername;
46};
47
48
49void
50qcrypto_tls_session_free(QCryptoTLSSession *session)
51{
52 if (!session) {
53 return;
54 }
55
56 gnutls_deinit(session->handle);
57 g_free(session->hostname);
58 g_free(session->peername);
41 bool handshakeComplete;
42 QCryptoTLSSessionWriteFunc writeFunc;
43 QCryptoTLSSessionReadFunc readFunc;
44 void *opaque;
45 char *peername;
46};
47
48
49void
50qcrypto_tls_session_free(QCryptoTLSSession *session)
51{
52 if (!session) {
53 return;
54 }
55
56 gnutls_deinit(session->handle);
57 g_free(session->hostname);
58 g_free(session->peername);
59 g_free(session->aclname);
59 g_free(session->authzid);
60 object_unref(OBJECT(session->creds));
61 g_free(session);
62}
63
64
65static ssize_t
66qcrypto_tls_session_push(void *opaque, const void *buf, size_t len)
67{

--- 22 unchanged lines hidden (view full) ---

90}
91
92#define TLS_PRIORITY_ADDITIONAL_ANON "+ANON-DH"
93#define TLS_PRIORITY_ADDITIONAL_PSK "+ECDHE-PSK:+DHE-PSK:+PSK"
94
95QCryptoTLSSession *
96qcrypto_tls_session_new(QCryptoTLSCreds *creds,
97 const char *hostname,
60 object_unref(OBJECT(session->creds));
61 g_free(session);
62}
63
64
65static ssize_t
66qcrypto_tls_session_push(void *opaque, const void *buf, size_t len)
67{

--- 22 unchanged lines hidden (view full) ---

90}
91
92#define TLS_PRIORITY_ADDITIONAL_ANON "+ANON-DH"
93#define TLS_PRIORITY_ADDITIONAL_PSK "+ECDHE-PSK:+DHE-PSK:+PSK"
94
95QCryptoTLSSession *
96qcrypto_tls_session_new(QCryptoTLSCreds *creds,
97 const char *hostname,
98 const char *aclname,
98 const char *authzid,
99 QCryptoTLSCredsEndpoint endpoint,
100 Error **errp)
101{
102 QCryptoTLSSession *session;
103 int ret;
104
105 session = g_new0(QCryptoTLSSession, 1);
106 trace_qcrypto_tls_session_new(
107 session, creds, hostname ? hostname : "<none>",
99 QCryptoTLSCredsEndpoint endpoint,
100 Error **errp)
101{
102 QCryptoTLSSession *session;
103 int ret;
104
105 session = g_new0(QCryptoTLSSession, 1);
106 trace_qcrypto_tls_session_new(
107 session, creds, hostname ? hostname : "<none>",
108 aclname ? aclname : "<none>", endpoint);
108 authzid ? authzid : "<none>", endpoint);
109
110 if (hostname) {
111 session->hostname = g_strdup(hostname);
112 }
109
110 if (hostname) {
111 session->hostname = g_strdup(hostname);
112 }
113 if (aclname) {
114 session->aclname = g_strdup(aclname);
113 if (authzid) {
114 session->authzid = g_strdup(authzid);
115 }
116 session->creds = creds;
117 object_ref(OBJECT(creds));
118
119 if (creds->endpoint != endpoint) {
120 error_setg(errp, "Credentials endpoint doesn't match session");
121 goto error;
122 }

--- 134 unchanged lines hidden (view full) ---

257 Error **errp)
258{
259 int ret;
260 unsigned int status;
261 const gnutls_datum_t *certs;
262 unsigned int nCerts, i;
263 time_t now;
264 gnutls_x509_crt_t cert = NULL;
115 }
116 session->creds = creds;
117 object_ref(OBJECT(creds));
118
119 if (creds->endpoint != endpoint) {
120 error_setg(errp, "Credentials endpoint doesn't match session");
121 goto error;
122 }

--- 134 unchanged lines hidden (view full) ---

257 Error **errp)
258{
259 int ret;
260 unsigned int status;
261 const gnutls_datum_t *certs;
262 unsigned int nCerts, i;
263 time_t now;
264 gnutls_x509_crt_t cert = NULL;
265 Error *err = NULL;
265
266 now = time(NULL);
267 if (now == ((time_t)-1)) {
268 error_setg_errno(errp, errno, "Cannot get current time");
269 return -1;
270 }
271
272 ret = gnutls_certificate_verify_peers2(session->handle, &status);

--- 71 unchanged lines hidden (view full) ---

344 session->peername = g_realloc(session->peername,
345 dnameSize);
346 goto requery;
347 }
348 error_setg(errp, "Cannot get client distinguished name: %s",
349 gnutls_strerror(ret));
350 goto error;
351 }
266
267 now = time(NULL);
268 if (now == ((time_t)-1)) {
269 error_setg_errno(errp, errno, "Cannot get current time");
270 return -1;
271 }
272
273 ret = gnutls_certificate_verify_peers2(session->handle, &status);

--- 71 unchanged lines hidden (view full) ---

345 session->peername = g_realloc(session->peername,
346 dnameSize);
347 goto requery;
348 }
349 error_setg(errp, "Cannot get client distinguished name: %s",
350 gnutls_strerror(ret));
351 goto error;
352 }
352 if (session->aclname) {
353 qemu_acl *acl = qemu_acl_find(session->aclname);
354 int allow;
355 if (!acl) {
356 error_setg(errp, "Cannot find ACL %s",
357 session->aclname);
353 if (session->authzid) {
354 bool allow;
355
356 allow = qauthz_is_allowed_by_id(session->authzid,
357 session->peername, &err);
358 if (err) {
359 error_propagate(errp, err);
358 goto error;
359 }
360 goto error;
361 }
360
361 allow = qemu_acl_party_is_allowed(acl, session->peername);
362
363 if (!allow) {
362 if (!allow) {
364 error_setg(errp, "TLS x509 ACL check for %s is denied",
363 error_setg(errp, "TLS x509 authz check for %s is denied",
365 session->peername);
366 goto error;
367 }
368 }
369 if (session->hostname) {
370 if (!gnutls_x509_crt_check_hostname(cert, session->hostname)) {
371 error_setg(errp,
372 "Certificate does not match the hostname %s",

--- 177 unchanged lines hidden (view full) ---

550
551
552#else /* ! CONFIG_GNUTLS */
553
554
555QCryptoTLSSession *
556qcrypto_tls_session_new(QCryptoTLSCreds *creds G_GNUC_UNUSED,
557 const char *hostname G_GNUC_UNUSED,
364 session->peername);
365 goto error;
366 }
367 }
368 if (session->hostname) {
369 if (!gnutls_x509_crt_check_hostname(cert, session->hostname)) {
370 error_setg(errp,
371 "Certificate does not match the hostname %s",

--- 177 unchanged lines hidden (view full) ---

549
550
551#else /* ! CONFIG_GNUTLS */
552
553
554QCryptoTLSSession *
555qcrypto_tls_session_new(QCryptoTLSCreds *creds G_GNUC_UNUSED,
556 const char *hostname G_GNUC_UNUSED,
558 const char *aclname G_GNUC_UNUSED,
557 const char *authzid G_GNUC_UNUSED,
559 QCryptoTLSCredsEndpoint endpoint G_GNUC_UNUSED,
560 Error **errp)
561{
562 error_setg(errp, "TLS requires GNUTLS support");
563 return NULL;
564}
565
566

--- 77 unchanged lines hidden ---
558 QCryptoTLSCredsEndpoint endpoint G_GNUC_UNUSED,
559 Error **errp)
560{
561 error_setg(errp, "TLS requires GNUTLS support");
562 return NULL;
563}
564
565

--- 77 unchanged lines hidden ---