]> git.proxmox.com Git - mirror_qemu.git/blame - include/crypto/tlssession.h
migration/savevm: wrap into qemu_loadvm_state_header()
[mirror_qemu.git] / include / crypto / tlssession.h
CommitLineData
d321e1e5
DB
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
9 * version 2 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
121d0712
MA
21#ifndef QCRYPTO_TLSSESSION_H
22#define QCRYPTO_TLSSESSION_H
d321e1e5
DB
23
24#include "crypto/tlscreds.h"
25
26/**
27 * QCryptoTLSSession:
28 *
29 * The QCryptoTLSSession object encapsulates the
30 * logic to integrate with a TLS providing library such
31 * as GNUTLS, to setup and run TLS sessions.
32 *
33 * The API is designed such that it has no assumption about
34 * the type of transport it is running over. It may be a
35 * traditional TCP socket, or something else entirely. The
36 * only requirement is a full-duplex stream of some kind.
37 *
38 * <example>
39 * <title>Using TLS session objects</title>
40 * <programlisting>
41 * static ssize_t mysock_send(const char *buf, size_t len,
42 * void *opaque)
43 * {
44 * int fd = GPOINTER_TO_INT(opaque);
45 *
46 * return write(*fd, buf, len);
47 * }
48 *
49 * static ssize_t mysock_recv(const char *buf, size_t len,
50 * void *opaque)
51 * {
52 * int fd = GPOINTER_TO_INT(opaque);
53 *
54 * return read(*fd, buf, len);
55 * }
56 *
57 * static int mysock_run_tls(int sockfd,
58 * QCryptoTLSCreds *creds,
b3afe335 59 * Error *errp)
d321e1e5
DB
60 * {
61 * QCryptoTLSSession *sess;
62 *
63 * sess = qcrypto_tls_session_new(creds,
64 * "vnc.example.com",
65 * NULL,
66 * QCRYPTO_TLS_CREDS_ENDPOINT_CLIENT,
67 * errp);
68 * if (sess == NULL) {
69 * return -1;
70 * }
71 *
72 * qcrypto_tls_session_set_callbacks(sess,
73 * mysock_send,
74 * mysock_recv
75 * GINT_TO_POINTER(fd));
76 *
77 * while (1) {
78 * if (qcrypto_tls_session_handshake(sess, errp) < 0) {
79 * qcrypto_tls_session_free(sess);
80 * return -1;
81 * }
82 *
83 * switch(qcrypto_tls_session_get_handshake_status(sess)) {
84 * case QCRYPTO_TLS_HANDSHAKE_COMPLETE:
85 * if (qcrypto_tls_session_check_credentials(sess, errp) < )) {
86 * qcrypto_tls_session_free(sess);
87 * return -1;
88 * }
89 * goto done;
90 * case QCRYPTO_TLS_HANDSHAKE_RECVING:
91 * ...wait for GIO_IN event on fd...
92 * break;
93 * case QCRYPTO_TLS_HANDSHAKE_SENDING:
94 * ...wait for GIO_OUT event on fd...
95 * break;
96 * }
97 * }
98 * done:
99 *
100 * ....send/recv payload data on sess...
101 *
102 * qcrypto_tls_session_free(sess):
103 * }
104 * </programlisting>
105 * </example>
106 */
107
108typedef struct QCryptoTLSSession QCryptoTLSSession;
109
110
111/**
112 * qcrypto_tls_session_new:
113 * @creds: pointer to a TLS credentials object
114 * @hostname: optional hostname to validate
115 * @aclname: optional ACL to validate peer credentials against
116 * @endpoint: role of the TLS session, client or server
07982d2e 117 * @errp: pointer to a NULL-initialized error object
d321e1e5
DB
118 *
119 * Create a new TLS session object that will be used to
120 * negotiate a TLS session over an arbitrary data channel.
121 * The session object can operate as either the server or
122 * client, according to the value of the @endpoint argument.
123 *
124 * For clients, the @hostname parameter should hold the full
125 * unmodified hostname as requested by the user. This will
126 * be used to verify the against the hostname reported in
127 * the server's credentials (aka x509 certificate).
128 *
129 * The @aclname parameter (optionally) specifies the name
130 * of an access control list that will be used to validate
131 * the peer's credentials. For x509 credentials, the ACL
132 * will be matched against the CommonName shown in the peer's
133 * certificate. If the session is acting as a server, setting
134 * an ACL will require that the client provide a validate
135 * x509 client certificate.
136 *
137 * After creating the session object, the I/O callbacks
138 * must be set using the qcrypto_tls_session_set_callbacks()
139 * method. A TLS handshake sequence must then be completed
140 * using qcrypto_tls_session_handshake(), before payload
141 * data is permitted to be sent/received.
142 *
143 * The session object must be released by calling
144 * qcrypto_tls_session_free() when no longer required
145 *
146 * Returns: a TLS session object, or NULL on error.
147 */
148QCryptoTLSSession *qcrypto_tls_session_new(QCryptoTLSCreds *creds,
149 const char *hostname,
150 const char *aclname,
151 QCryptoTLSCredsEndpoint endpoint,
152 Error **errp);
153
154/**
155 * qcrypto_tls_session_free:
156 * @sess: the TLS session object
157 *
158 * Release all memory associated with the TLS session
159 * object previously allocated by qcrypto_tls_session_new()
160 */
161void qcrypto_tls_session_free(QCryptoTLSSession *sess);
162
163/**
164 * qcrypto_tls_session_check_credentials:
165 * @sess: the TLS session object
07982d2e 166 * @errp: pointer to a NULL-initialized error object
d321e1e5
DB
167 *
168 * Validate the peer's credentials after a successful
169 * TLS handshake. It is an error to call this before
170 * qcrypto_tls_session_get_handshake_status() returns
171 * QCRYPTO_TLS_HANDSHAKE_COMPLETE
172 *
173 * Returns 0 if the credentials validated, -1 on error
174 */
175int qcrypto_tls_session_check_credentials(QCryptoTLSSession *sess,
176 Error **errp);
177
178typedef ssize_t (*QCryptoTLSSessionWriteFunc)(const char *buf,
179 size_t len,
180 void *opaque);
181typedef ssize_t (*QCryptoTLSSessionReadFunc)(char *buf,
182 size_t len,
183 void *opaque);
184
185/**
186 * qcrypto_tls_session_set_callbacks:
187 * @sess: the TLS session object
188 * @writeFunc: callback for sending data
189 * @readFunc: callback to receiving data
190 * @opaque: data to pass to callbacks
191 *
192 * Sets the callback functions that are to be used for sending
193 * and receiving data on the underlying data channel. Typically
194 * the callbacks to write/read to/from a TCP socket, but there
195 * is no assumption made about the type of channel used.
196 *
197 * The @writeFunc callback will be passed the encrypted
198 * data to send to the remote peer.
199 *
200 * The @readFunc callback will be passed a pointer to fill
201 * with encrypted data received from the remote peer
202 */
203void qcrypto_tls_session_set_callbacks(QCryptoTLSSession *sess,
204 QCryptoTLSSessionWriteFunc writeFunc,
205 QCryptoTLSSessionReadFunc readFunc,
206 void *opaque);
207
208/**
209 * qcrypto_tls_session_write:
210 * @sess: the TLS session object
211 * @buf: the plain text to send
212 * @len: the length of @buf
213 *
214 * Encrypt @len bytes of the data in @buf and send
215 * it to the remote peer using the callback previously
216 * registered with qcrypto_tls_session_set_callbacks()
217 *
218 * It is an error to call this before
219 * qcrypto_tls_session_get_handshake_status() returns
220 * QCRYPTO_TLS_HANDSHAKE_COMPLETE
221 *
222 * Returns: the number of bytes sent, or -1 on error
223 */
224ssize_t qcrypto_tls_session_write(QCryptoTLSSession *sess,
225 const char *buf,
226 size_t len);
227
228/**
229 * qcrypto_tls_session_read:
230 * @sess: the TLS session object
231 * @buf: to fill with plain text received
232 * @len: the length of @buf
233 *
234 * Receive up to @len bytes of data from the remote peer
235 * using the callback previously registered with
236 * qcrypto_tls_session_set_callbacks(), decrypt it and
237 * store it in @buf.
238 *
239 * It is an error to call this before
240 * qcrypto_tls_session_get_handshake_status() returns
241 * QCRYPTO_TLS_HANDSHAKE_COMPLETE
242 *
243 * Returns: the number of bytes received, or -1 on error
244 */
245ssize_t qcrypto_tls_session_read(QCryptoTLSSession *sess,
246 char *buf,
247 size_t len);
248
249/**
250 * qcrypto_tls_session_handshake:
251 * @sess: the TLS session object
07982d2e 252 * @errp: pointer to a NULL-initialized error object
d321e1e5
DB
253 *
254 * Start, or continue, a TLS handshake sequence. If
255 * the underlying data channel is non-blocking, then
256 * this method may return control before the handshake
257 * is complete. On non-blocking channels the
258 * qcrypto_tls_session_get_handshake_status() method
259 * should be used to determine whether the handshake
260 * has completed, or is waiting to send or receive
261 * data. In the latter cases, the caller should setup
262 * an event loop watch and call this method again
263 * once the underlying data channel is ready to read
264 * or write again
265 */
266int qcrypto_tls_session_handshake(QCryptoTLSSession *sess,
267 Error **errp);
268
269typedef enum {
270 QCRYPTO_TLS_HANDSHAKE_COMPLETE,
271 QCRYPTO_TLS_HANDSHAKE_SENDING,
272 QCRYPTO_TLS_HANDSHAKE_RECVING,
273} QCryptoTLSSessionHandshakeStatus;
274
275/**
276 * qcrypto_tls_session_get_handshake_status:
277 * @sess: the TLS session object
278 *
279 * Check the status of the TLS handshake. This
280 * is used with non-blocking data channels to
281 * determine whether the handshake is waiting
282 * to send or receive further data to/from the
283 * remote peer.
284 *
285 * Once this returns QCRYPTO_TLS_HANDSHAKE_COMPLETE
286 * it is permitted to send/receive payload data on
287 * the channel
288 */
289QCryptoTLSSessionHandshakeStatus
290qcrypto_tls_session_get_handshake_status(QCryptoTLSSession *sess);
291
292/**
293 * qcrypto_tls_session_get_key_size:
294 * @sess: the TLS session object
07982d2e 295 * @errp: pointer to a NULL-initialized error object
d321e1e5
DB
296 *
297 * Check the size of the data channel encryption key
298 *
299 * Returns: the length in bytes of the encryption key
300 * or -1 on error
301 */
302int qcrypto_tls_session_get_key_size(QCryptoTLSSession *sess,
303 Error **errp);
304
305/**
306 * qcrypto_tls_session_get_peer_name:
307 * @sess: the TLS session object
308 *
309 * Get the identified name of the remote peer. If the
310 * TLS session was negotiated using x509 certificate
311 * credentials, this will return the CommonName from
312 * the peer's certificate. If no identified name is
313 * available it will return NULL.
314 *
315 * The returned data must be released with g_free()
316 * when no longer required.
317 *
318 * Returns: the peer's name or NULL.
319 */
320char *qcrypto_tls_session_get_peer_name(QCryptoTLSSession *sess);
321
121d0712 322#endif /* QCRYPTO_TLSSESSION_H */