cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

tlssession.h (11078B)


      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.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#ifndef QCRYPTO_TLSSESSION_H
     22#define QCRYPTO_TLSSESSION_H
     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,
     59 *                           Error **errp)
     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
    117 * @errp: pointer to a NULL-initialized error object
    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
    163G_DEFINE_AUTOPTR_CLEANUP_FUNC(QCryptoTLSSession, qcrypto_tls_session_free)
    164
    165/**
    166 * qcrypto_tls_session_check_credentials:
    167 * @sess: the TLS session object
    168 * @errp: pointer to a NULL-initialized error object
    169 *
    170 * Validate the peer's credentials after a successful
    171 * TLS handshake. It is an error to call this before
    172 * qcrypto_tls_session_get_handshake_status() returns
    173 * QCRYPTO_TLS_HANDSHAKE_COMPLETE
    174 *
    175 * Returns 0 if the credentials validated, -1 on error
    176 */
    177int qcrypto_tls_session_check_credentials(QCryptoTLSSession *sess,
    178                                          Error **errp);
    179
    180typedef ssize_t (*QCryptoTLSSessionWriteFunc)(const char *buf,
    181                                              size_t len,
    182                                              void *opaque);
    183typedef ssize_t (*QCryptoTLSSessionReadFunc)(char *buf,
    184                                             size_t len,
    185                                             void *opaque);
    186
    187/**
    188 * qcrypto_tls_session_set_callbacks:
    189 * @sess: the TLS session object
    190 * @writeFunc: callback for sending data
    191 * @readFunc: callback to receiving data
    192 * @opaque: data to pass to callbacks
    193 *
    194 * Sets the callback functions that are to be used for sending
    195 * and receiving data on the underlying data channel. Typically
    196 * the callbacks to write/read to/from a TCP socket, but there
    197 * is no assumption made about the type of channel used.
    198 *
    199 * The @writeFunc callback will be passed the encrypted
    200 * data to send to the remote peer.
    201 *
    202 * The @readFunc callback will be passed a pointer to fill
    203 * with encrypted data received from the remote peer
    204 */
    205void qcrypto_tls_session_set_callbacks(QCryptoTLSSession *sess,
    206                                       QCryptoTLSSessionWriteFunc writeFunc,
    207                                       QCryptoTLSSessionReadFunc readFunc,
    208                                       void *opaque);
    209
    210/**
    211 * qcrypto_tls_session_write:
    212 * @sess: the TLS session object
    213 * @buf: the plain text to send
    214 * @len: the length of @buf
    215 *
    216 * Encrypt @len bytes of the data in @buf and send
    217 * it to the remote peer using the callback previously
    218 * registered with qcrypto_tls_session_set_callbacks()
    219 *
    220 * It is an error to call this before
    221 * qcrypto_tls_session_get_handshake_status() returns
    222 * QCRYPTO_TLS_HANDSHAKE_COMPLETE
    223 *
    224 * Returns: the number of bytes sent, or -1 on error
    225 */
    226ssize_t qcrypto_tls_session_write(QCryptoTLSSession *sess,
    227                                  const char *buf,
    228                                  size_t len);
    229
    230/**
    231 * qcrypto_tls_session_read:
    232 * @sess: the TLS session object
    233 * @buf: to fill with plain text received
    234 * @len: the length of @buf
    235 *
    236 * Receive up to @len bytes of data from the remote peer
    237 * using the callback previously registered with
    238 * qcrypto_tls_session_set_callbacks(), decrypt it and
    239 * store it in @buf.
    240 *
    241 * It is an error to call this before
    242 * qcrypto_tls_session_get_handshake_status() returns
    243 * QCRYPTO_TLS_HANDSHAKE_COMPLETE
    244 *
    245 * Returns: the number of bytes received, or -1 on error
    246 */
    247ssize_t qcrypto_tls_session_read(QCryptoTLSSession *sess,
    248                                 char *buf,
    249                                 size_t len);
    250
    251/**
    252 * qcrypto_tls_session_handshake:
    253 * @sess: the TLS session object
    254 * @errp: pointer to a NULL-initialized error object
    255 *
    256 * Start, or continue, a TLS handshake sequence. If
    257 * the underlying data channel is non-blocking, then
    258 * this method may return control before the handshake
    259 * is complete. On non-blocking channels the
    260 * qcrypto_tls_session_get_handshake_status() method
    261 * should be used to determine whether the handshake
    262 * has completed, or is waiting to send or receive
    263 * data. In the latter cases, the caller should setup
    264 * an event loop watch and call this method again
    265 * once the underlying data channel is ready to read
    266 * or write again
    267 */
    268int qcrypto_tls_session_handshake(QCryptoTLSSession *sess,
    269                                  Error **errp);
    270
    271typedef enum {
    272    QCRYPTO_TLS_HANDSHAKE_COMPLETE,
    273    QCRYPTO_TLS_HANDSHAKE_SENDING,
    274    QCRYPTO_TLS_HANDSHAKE_RECVING,
    275} QCryptoTLSSessionHandshakeStatus;
    276
    277/**
    278 * qcrypto_tls_session_get_handshake_status:
    279 * @sess: the TLS session object
    280 *
    281 * Check the status of the TLS handshake. This
    282 * is used with non-blocking data channels to
    283 * determine whether the handshake is waiting
    284 * to send or receive further data to/from the
    285 * remote peer.
    286 *
    287 * Once this returns QCRYPTO_TLS_HANDSHAKE_COMPLETE
    288 * it is permitted to send/receive payload data on
    289 * the channel
    290 */
    291QCryptoTLSSessionHandshakeStatus
    292qcrypto_tls_session_get_handshake_status(QCryptoTLSSession *sess);
    293
    294/**
    295 * qcrypto_tls_session_get_key_size:
    296 * @sess: the TLS session object
    297 * @errp: pointer to a NULL-initialized error object
    298 *
    299 * Check the size of the data channel encryption key
    300 *
    301 * Returns: the length in bytes of the encryption key
    302 * or -1 on error
    303 */
    304int qcrypto_tls_session_get_key_size(QCryptoTLSSession *sess,
    305                                     Error **errp);
    306
    307/**
    308 * qcrypto_tls_session_get_peer_name:
    309 * @sess: the TLS session object
    310 *
    311 * Get the identified name of the remote peer. If the
    312 * TLS session was negotiated using x509 certificate
    313 * credentials, this will return the CommonName from
    314 * the peer's certificate. If no identified name is
    315 * available it will return NULL.
    316 *
    317 * The returned data must be released with g_free()
    318 * when no longer required.
    319 *
    320 * Returns: the peer's name or NULL.
    321 */
    322char *qcrypto_tls_session_get_peer_name(QCryptoTLSSession *sess);
    323
    324#endif /* QCRYPTO_TLSSESSION_H */