LCOV - code coverage report
Current view: top level - lib - stream-ssl.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 354 532 66.5 %
Date: 2016-09-14 01:02:56 Functions: 39 42 92.9 %
Branches: 162 401 40.4 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Nicira, Inc.
       3                 :            :  *
       4                 :            :  * Licensed under the Apache License, Version 2.0 (the "License");
       5                 :            :  * you may not use this file except in compliance with the License.
       6                 :            :  * You may obtain a copy of the License at:
       7                 :            :  *
       8                 :            :  *     http://www.apache.org/licenses/LICENSE-2.0
       9                 :            :  *
      10                 :            :  * Unless required by applicable law or agreed to in writing, software
      11                 :            :  * distributed under the License is distributed on an "AS IS" BASIS,
      12                 :            :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      13                 :            :  * See the License for the specific language governing permissions and
      14                 :            :  * limitations under the License.
      15                 :            :  */
      16                 :            : 
      17                 :            : #include <config.h>
      18                 :            : #include "stream-ssl.h"
      19                 :            : #include "dhparams.h"
      20                 :            : #include <ctype.h>
      21                 :            : #include <errno.h>
      22                 :            : #include <inttypes.h>
      23                 :            : #include <string.h>
      24                 :            : #include <sys/types.h>
      25                 :            : #include <sys/socket.h>
      26                 :            : #include <netinet/tcp.h>
      27                 :            : #include <openssl/err.h>
      28                 :            : #include <openssl/rand.h>
      29                 :            : #include <openssl/ssl.h>
      30                 :            : #include <openssl/x509v3.h>
      31                 :            : #include <poll.h>
      32                 :            : #include <fcntl.h>
      33                 :            : #include <sys/stat.h>
      34                 :            : #include <unistd.h>
      35                 :            : #include "coverage.h"
      36                 :            : #include "openvswitch/dynamic-string.h"
      37                 :            : #include "entropy.h"
      38                 :            : #include "openvswitch/ofpbuf.h"
      39                 :            : #include "openflow/openflow.h"
      40                 :            : #include "packets.h"
      41                 :            : #include "poll-loop.h"
      42                 :            : #include "openvswitch/shash.h"
      43                 :            : #include "socket-util.h"
      44                 :            : #include "util.h"
      45                 :            : #include "stream-provider.h"
      46                 :            : #include "stream.h"
      47                 :            : #include "timeval.h"
      48                 :            : #include "openvswitch/vlog.h"
      49                 :            : 
      50                 :            : #ifdef _WIN32
      51                 :            : /* Ref: https://www.openssl.org/support/faq.html#PROG2
      52                 :            :  * Your application must link against the same version of the Win32 C-Runtime
      53                 :            :  * against which your openssl libraries were linked.  The default version for
      54                 :            :  * OpenSSL is /MD - "Multithreaded DLL". If we compile Open vSwitch with
      55                 :            :  * something other than /MD, instead of re-compiling OpenSSL
      56                 :            :  * toolkit, openssl/applink.c can be #included. Also, it is important
      57                 :            :  * to add CRYPTO_malloc_init prior first call to OpenSSL.
      58                 :            :  *
      59                 :            :  * XXX: The behavior of the following #include when Open vSwitch is
      60                 :            :  * compiled with /MD is not tested. */
      61                 :            : #include <openssl/applink.c>
      62                 :            : #define SHUT_RDWR SD_BOTH
      63                 :            : #endif
      64                 :            : 
      65                 :      53956 : VLOG_DEFINE_THIS_MODULE(stream_ssl);
      66                 :            : 
      67                 :            : /* Active SSL. */
      68                 :            : 
      69                 :            : enum ssl_state {
      70                 :            :     STATE_TCP_CONNECTING,
      71                 :            :     STATE_SSL_CONNECTING
      72                 :            : };
      73                 :            : 
      74                 :            : enum session_type {
      75                 :            :     CLIENT,
      76                 :            :     SERVER
      77                 :            : };
      78                 :            : 
      79                 :            : struct ssl_stream
      80                 :            : {
      81                 :            :     struct stream stream;
      82                 :            :     enum ssl_state state;
      83                 :            :     enum session_type type;
      84                 :            :     int fd;
      85                 :            :     SSL *ssl;
      86                 :            :     struct ofpbuf *txbuf;
      87                 :            :     unsigned int session_nr;
      88                 :            : 
      89                 :            :     /* rx_want and tx_want record the result of the last call to SSL_read()
      90                 :            :      * and SSL_write(), respectively:
      91                 :            :      *
      92                 :            :      *    - If the call reported that data needed to be read from the file
      93                 :            :      *      descriptor, the corresponding member is set to SSL_READING.
      94                 :            :      *
      95                 :            :      *    - If the call reported that data needed to be written to the file
      96                 :            :      *      descriptor, the corresponding member is set to SSL_WRITING.
      97                 :            :      *
      98                 :            :      *    - Otherwise, the member is set to SSL_NOTHING, indicating that the
      99                 :            :      *      call completed successfully (or with an error) and that there is no
     100                 :            :      *      need to block.
     101                 :            :      *
     102                 :            :      * These are needed because there is no way to ask OpenSSL what a data read
     103                 :            :      * or write would require without giving it a buffer to receive into or
     104                 :            :      * data to send, respectively.  (Note that the SSL_want() status is
     105                 :            :      * overwritten by each SSL_read() or SSL_write() call, so we can't rely on
     106                 :            :      * its value.)
     107                 :            :      *
     108                 :            :      * A single call to SSL_read() or SSL_write() can perform both reading
     109                 :            :      * and writing and thus invalidate not one of these values but actually
     110                 :            :      * both.  Consider this situation, for example:
     111                 :            :      *
     112                 :            :      *    - SSL_write() blocks on a read, so tx_want gets SSL_READING.
     113                 :            :      *
     114                 :            :      *    - SSL_read() laters succeeds reading from 'fd' and clears out the
     115                 :            :      *      whole receive buffer, so rx_want gets SSL_READING.
     116                 :            :      *
     117                 :            :      *    - Client calls stream_wait(STREAM_RECV) and stream_wait(STREAM_SEND)
     118                 :            :      *      and blocks.
     119                 :            :      *
     120                 :            :      *    - Now we're stuck blocking until the peer sends us data, even though
     121                 :            :      *      SSL_write() could now succeed, which could easily be a deadlock
     122                 :            :      *      condition.
     123                 :            :      *
     124                 :            :      * On the other hand, we can't reset both tx_want and rx_want on every call
     125                 :            :      * to SSL_read() or SSL_write(), because that would produce livelock,
     126                 :            :      * e.g. in this situation:
     127                 :            :      *
     128                 :            :      *    - SSL_write() blocks, so tx_want gets SSL_READING or SSL_WRITING.
     129                 :            :      *
     130                 :            :      *    - SSL_read() blocks, so rx_want gets SSL_READING or SSL_WRITING,
     131                 :            :      *      but tx_want gets reset to SSL_NOTHING.
     132                 :            :      *
     133                 :            :      *    - Client calls stream_wait(STREAM_RECV) and stream_wait(STREAM_SEND)
     134                 :            :      *      and blocks.
     135                 :            :      *
     136                 :            :      *    - Client wakes up immediately since SSL_NOTHING in tx_want indicates
     137                 :            :      *      that no blocking is necessary.
     138                 :            :      *
     139                 :            :      * The solution we adopt here is to set tx_want to SSL_NOTHING after
     140                 :            :      * calling SSL_read() only if the SSL state of the connection changed,
     141                 :            :      * which indicates that an SSL-level renegotiation made some progress, and
     142                 :            :      * similarly for rx_want and SSL_write().  This prevents both the
     143                 :            :      * deadlock and livelock situations above.
     144                 :            :      */
     145                 :            :     int rx_want, tx_want;
     146                 :            : 
     147                 :            :     /* A few bytes of header data in case SSL negotiation fails. */
     148                 :            :     uint8_t head[2];
     149                 :            :     short int n_head;
     150                 :            : };
     151                 :            : 
     152                 :            : /* SSL context created by ssl_init(). */
     153                 :            : static SSL_CTX *ctx;
     154                 :            : 
     155                 :            : struct ssl_config_file {
     156                 :            :     bool read;                  /* Whether the file was successfully read. */
     157                 :            :     char *file_name;            /* Configured file name, if any. */
     158                 :            :     struct timespec mtime;      /* File mtime as of last time we read it. */
     159                 :            : };
     160                 :            : 
     161                 :            : /* SSL configuration files. */
     162                 :            : static struct ssl_config_file private_key;
     163                 :            : static struct ssl_config_file certificate;
     164                 :            : static struct ssl_config_file ca_cert;
     165                 :            : 
     166                 :            : /* Ordinarily, the SSL client and server verify each other's certificates using
     167                 :            :  * a CA certificate.  Setting this to false disables this behavior.  (This is a
     168                 :            :  * security risk.) */
     169                 :            : static bool verify_peer_cert = true;
     170                 :            : 
     171                 :            : /* Ordinarily, we require a CA certificate for the peer to be locally
     172                 :            :  * available.  We can, however, bootstrap the CA certificate from the peer at
     173                 :            :  * the beginning of our first connection then use that certificate on all
     174                 :            :  * subsequent connections, saving it to a file for use in future runs also.  In
     175                 :            :  * this case, 'bootstrap_ca_cert' is true. */
     176                 :            : static bool bootstrap_ca_cert;
     177                 :            : 
     178                 :            : /* Session number.  Used in debug logging messages to uniquely identify a
     179                 :            :  * session. */
     180                 :            : static unsigned int next_session_nr;
     181                 :            : 
     182                 :            : /* Who knows what can trigger various SSL errors, so let's throttle them down
     183                 :            :  * quite a bit. */
     184                 :            : static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(10, 25);
     185                 :            : 
     186                 :            : static int ssl_init(void);
     187                 :            : static int do_ssl_init(void);
     188                 :            : static bool ssl_wants_io(int ssl_error);
     189                 :            : static void ssl_close(struct stream *);
     190                 :            : static void ssl_clear_txbuf(struct ssl_stream *);
     191                 :            : static void interpret_queued_ssl_error(const char *function);
     192                 :            : static int interpret_ssl_error(const char *function, int ret, int error,
     193                 :            :                                int *want);
     194                 :            : static DH *tmp_dh_callback(SSL *ssl, int is_export OVS_UNUSED, int keylength);
     195                 :            : static void log_ca_cert(const char *file_name, X509 *cert);
     196                 :            : static void stream_ssl_set_ca_cert_file__(const char *file_name,
     197                 :            :                                           bool bootstrap, bool force);
     198                 :            : static void ssl_protocol_cb(int write_p, int version, int content_type,
     199                 :            :                             const void *, size_t, SSL *, void *sslv_);
     200                 :            : static bool update_ssl_config(struct ssl_config_file *, const char *file_name);
     201                 :            : static int sock_errno(void);
     202                 :            : 
     203                 :            : static short int
     204                 :        523 : want_to_poll_events(int want)
     205                 :            : {
     206   [ -  +  -  - ]:        523 :     switch (want) {
     207                 :            :     case SSL_NOTHING:
     208                 :          0 :         OVS_NOT_REACHED();
     209                 :            : 
     210                 :            :     case SSL_READING:
     211                 :        523 :         return POLLIN;
     212                 :            : 
     213                 :            :     case SSL_WRITING:
     214                 :          0 :         return POLLOUT;
     215                 :            : 
     216                 :            :     default:
     217                 :          0 :         OVS_NOT_REACHED();
     218                 :            :     }
     219                 :            : }
     220                 :            : 
     221                 :            : static int
     222                 :        233 : new_ssl_stream(const char *name, int fd, enum session_type type,
     223                 :            :                enum ssl_state state, struct stream **streamp)
     224                 :            : {
     225                 :            :     struct ssl_stream *sslv;
     226                 :        233 :     SSL *ssl = NULL;
     227                 :            :     int retval;
     228                 :            : 
     229                 :            :     /* Check for all the needful configuration. */
     230                 :        233 :     retval = 0;
     231         [ -  + ]:        233 :     if (!private_key.read) {
     232         [ #  # ]:          0 :         VLOG_ERR("Private key must be configured to use SSL");
     233                 :          0 :         retval = ENOPROTOOPT;
     234                 :            :     }
     235         [ -  + ]:        233 :     if (!certificate.read) {
     236         [ #  # ]:          0 :         VLOG_ERR("Certificate must be configured to use SSL");
     237                 :          0 :         retval = ENOPROTOOPT;
     238                 :            :     }
     239 [ -  + ][ #  # ]:        233 :     if (!ca_cert.read && verify_peer_cert && !bootstrap_ca_cert) {
                 [ #  # ]
     240         [ #  # ]:          0 :         VLOG_ERR("CA certificate must be configured to use SSL");
     241                 :          0 :         retval = ENOPROTOOPT;
     242                 :            :     }
     243 [ +  - ][ -  + ]:        233 :     if (!retval && !SSL_CTX_check_private_key(ctx)) {
     244         [ #  # ]:          0 :         VLOG_ERR("Private key does not match certificate public key: %s",
     245                 :            :                  ERR_error_string(ERR_get_error(), NULL));
     246                 :          0 :         retval = ENOPROTOOPT;
     247                 :            :     }
     248         [ -  + ]:        233 :     if (retval) {
     249                 :          0 :         goto error;
     250                 :            :     }
     251                 :            : 
     252                 :            :     /* Disable Nagle.
     253                 :            :      * On windows platforms, this can only be called upon TCP connected.
     254                 :            :      */
     255         [ +  + ]:        233 :     if (state == STATE_SSL_CONNECTING) {
     256                 :        116 :         setsockopt_tcp_nodelay(fd);
     257                 :            :     }
     258                 :            : 
     259                 :            :     /* Create and configure OpenSSL stream. */
     260                 :        233 :     ssl = SSL_new(ctx);
     261         [ -  + ]:        233 :     if (ssl == NULL) {
     262         [ #  # ]:          0 :         VLOG_ERR("SSL_new: %s", ERR_error_string(ERR_get_error(), NULL));
     263                 :          0 :         retval = ENOPROTOOPT;
     264                 :          0 :         goto error;
     265                 :            :     }
     266         [ -  + ]:        233 :     if (SSL_set_fd(ssl, fd) == 0) {
     267         [ #  # ]:          0 :         VLOG_ERR("SSL_set_fd: %s", ERR_error_string(ERR_get_error(), NULL));
     268                 :          0 :         retval = ENOPROTOOPT;
     269                 :          0 :         goto error;
     270                 :            :     }
     271 [ +  - ][ +  + ]:        233 :     if (!verify_peer_cert || (bootstrap_ca_cert && type == CLIENT)) {
                 [ +  - ]
     272                 :          2 :         SSL_set_verify(ssl, SSL_VERIFY_NONE, NULL);
     273                 :            :     }
     274                 :            : 
     275                 :            :     /* Create and return the ssl_stream. */
     276                 :        233 :     sslv = xmalloc(sizeof *sslv);
     277                 :        233 :     stream_init(&sslv->stream, &ssl_stream_class, EAGAIN, name);
     278                 :        233 :     sslv->state = state;
     279                 :        233 :     sslv->type = type;
     280                 :        233 :     sslv->fd = fd;
     281                 :        233 :     sslv->ssl = ssl;
     282                 :        233 :     sslv->txbuf = NULL;
     283                 :        233 :     sslv->rx_want = sslv->tx_want = SSL_NOTHING;
     284                 :        233 :     sslv->session_nr = next_session_nr++;
     285                 :        233 :     sslv->n_head = 0;
     286                 :            : 
     287         [ +  + ]:        233 :     if (VLOG_IS_DBG_ENABLED()) {
     288                 :         15 :         SSL_set_msg_callback(ssl, ssl_protocol_cb);
     289                 :         15 :         SSL_set_msg_callback_arg(ssl, sslv);
     290                 :            :     }
     291                 :            : 
     292                 :        233 :     *streamp = &sslv->stream;
     293                 :        233 :     return 0;
     294                 :            : 
     295                 :            : error:
     296         [ #  # ]:          0 :     if (ssl) {
     297                 :          0 :         SSL_free(ssl);
     298                 :            :     }
     299                 :          0 :     closesocket(fd);
     300                 :          0 :     return retval;
     301                 :            : }
     302                 :            : 
     303                 :            : static struct ssl_stream *
     304                 :       4630 : ssl_stream_cast(struct stream *stream)
     305                 :            : {
     306                 :       4630 :     stream_assert_class(stream, &ssl_stream_class);
     307                 :       4630 :     return CONTAINER_OF(stream, struct ssl_stream, stream);
     308                 :            : }
     309                 :            : 
     310                 :            : static int
     311                 :        117 : ssl_open(const char *name, char *suffix, struct stream **streamp, uint8_t dscp)
     312                 :            : {
     313                 :            :     int error, fd;
     314                 :            : 
     315                 :        117 :     error = ssl_init();
     316         [ -  + ]:        117 :     if (error) {
     317                 :          0 :         return error;
     318                 :            :     }
     319                 :            : 
     320                 :        117 :     error = inet_open_active(SOCK_STREAM, suffix, OFP_PORT, NULL, &fd,
     321                 :            :                              dscp);
     322         [ +  - ]:        117 :     if (fd >= 0) {
     323                 :        117 :         int state = error ? STATE_TCP_CONNECTING : STATE_SSL_CONNECTING;
     324                 :        117 :         return new_ssl_stream(name, fd, CLIENT, state, streamp);
     325                 :            :     } else {
     326         [ #  # ]:          0 :         VLOG_ERR("%s: connect: %s", name, ovs_strerror(error));
     327                 :        117 :         return error;
     328                 :            :     }
     329                 :            : }
     330                 :            : 
     331                 :            : static int
     332                 :          2 : do_ca_cert_bootstrap(struct stream *stream)
     333                 :            : {
     334                 :          2 :     struct ssl_stream *sslv = ssl_stream_cast(stream);
     335                 :            :     STACK_OF(X509) *chain;
     336                 :            :     X509 *cert;
     337                 :            :     FILE *file;
     338                 :            :     int error;
     339                 :            :     int fd;
     340                 :            : 
     341                 :          2 :     chain = SSL_get_peer_cert_chain(sslv->ssl);
     342 [ +  - ][ -  + ]:          2 :     if (!chain || !sk_X509_num(chain)) {
     343         [ #  # ]:          0 :         VLOG_ERR("could not bootstrap CA cert: no certificate presented by "
     344                 :            :                  "peer");
     345                 :          0 :         return EPROTO;
     346                 :            :     }
     347                 :          2 :     cert = sk_X509_value(chain, sk_X509_num(chain) - 1);
     348                 :            : 
     349                 :            :     /* Check that 'cert' is self-signed.  Otherwise it is not a CA
     350                 :            :      * certificate and we should not attempt to use it as one. */
     351                 :          2 :     error = X509_check_issued(cert, cert);
     352         [ -  + ]:          2 :     if (error) {
     353         [ #  # ]:          0 :         VLOG_ERR("could not bootstrap CA cert: obtained certificate is "
     354                 :            :                  "not self-signed (%s)",
     355                 :            :                  X509_verify_cert_error_string(error));
     356         [ #  # ]:          0 :         if (sk_X509_num(chain) < 2) {
     357         [ #  # ]:          0 :             VLOG_ERR("only one certificate was received, so probably the peer "
     358                 :            :                      "is not configured to send its CA certificate");
     359                 :            :         }
     360                 :          0 :         return EPROTO;
     361                 :            :     }
     362                 :            : 
     363                 :          2 :     fd = open(ca_cert.file_name, O_CREAT | O_EXCL | O_WRONLY, 0444);
     364         [ -  + ]:          2 :     if (fd < 0) {
     365         [ #  # ]:          0 :         if (errno == EEXIST) {
     366         [ #  # ]:          0 :             VLOG_INFO_RL(&rl, "reading CA cert %s created by another process",
     367                 :            :                          ca_cert.file_name);
     368                 :          0 :             stream_ssl_set_ca_cert_file__(ca_cert.file_name, true, true);
     369                 :          0 :             return EPROTO;
     370                 :            :         } else {
     371         [ #  # ]:          0 :             VLOG_ERR("could not bootstrap CA cert: creating %s failed: %s",
     372                 :            :                      ca_cert.file_name, ovs_strerror(errno));
     373                 :          0 :             return errno;
     374                 :            :         }
     375                 :            :     }
     376                 :            : 
     377                 :          2 :     file = fdopen(fd, "w");
     378         [ -  + ]:          2 :     if (!file) {
     379                 :          0 :         error = errno;
     380         [ #  # ]:          0 :         VLOG_ERR("could not bootstrap CA cert: fdopen failed: %s",
     381                 :            :                  ovs_strerror(error));
     382                 :          0 :         unlink(ca_cert.file_name);
     383                 :          0 :         return error;
     384                 :            :     }
     385                 :            : 
     386         [ -  + ]:          2 :     if (!PEM_write_X509(file, cert)) {
     387         [ #  # ]:          0 :         VLOG_ERR("could not bootstrap CA cert: PEM_write_X509 to %s failed: "
     388                 :            :                  "%s", ca_cert.file_name,
     389                 :            :                  ERR_error_string(ERR_get_error(), NULL));
     390                 :          0 :         fclose(file);
     391                 :          0 :         unlink(ca_cert.file_name);
     392                 :          0 :         return EIO;
     393                 :            :     }
     394                 :            : 
     395         [ -  + ]:          2 :     if (fclose(file)) {
     396                 :          0 :         error = errno;
     397         [ #  # ]:          0 :         VLOG_ERR("could not bootstrap CA cert: writing %s failed: %s",
     398                 :            :                  ca_cert.file_name, ovs_strerror(error));
     399                 :          0 :         unlink(ca_cert.file_name);
     400                 :          0 :         return error;
     401                 :            :     }
     402                 :            : 
     403         [ +  - ]:          2 :     VLOG_INFO("successfully bootstrapped CA cert to %s", ca_cert.file_name);
     404                 :          2 :     log_ca_cert(ca_cert.file_name, cert);
     405                 :          2 :     bootstrap_ca_cert = false;
     406                 :          2 :     ca_cert.read = true;
     407                 :            : 
     408                 :            :     /* SSL_CTX_add_client_CA makes a copy of cert's relevant data. */
     409                 :          2 :     SSL_CTX_add_client_CA(ctx, cert);
     410                 :            : 
     411                 :          2 :     SSL_CTX_set_cert_store(ctx, X509_STORE_new());
     412         [ -  + ]:          2 :     if (SSL_CTX_load_verify_locations(ctx, ca_cert.file_name, NULL) != 1) {
     413         [ #  # ]:          0 :         VLOG_ERR("SSL_CTX_load_verify_locations: %s",
     414                 :            :                  ERR_error_string(ERR_get_error(), NULL));
     415                 :          0 :         return EPROTO;
     416                 :            :     }
     417         [ +  - ]:          2 :     VLOG_INFO("killing successful connection to retry using CA cert");
     418                 :          2 :     return EPROTO;
     419                 :            : }
     420                 :            : 
     421                 :            : static int
     422                 :        794 : ssl_connect(struct stream *stream)
     423                 :            : {
     424                 :        794 :     struct ssl_stream *sslv = ssl_stream_cast(stream);
     425                 :            :     int retval;
     426                 :            : 
     427      [ +  +  - ]:        794 :     switch (sslv->state) {
     428                 :            :     case STATE_TCP_CONNECTING:
     429                 :        117 :         retval = check_connection_completion(sslv->fd);
     430         [ -  + ]:        117 :         if (retval) {
     431                 :          0 :             return retval;
     432                 :            :         }
     433                 :        117 :         sslv->state = STATE_SSL_CONNECTING;
     434                 :        117 :         setsockopt_tcp_nodelay(sslv->fd);
     435                 :            :         /* Fall through. */
     436                 :            : 
     437                 :            :     case STATE_SSL_CONNECTING:
     438                 :            :         /* Capture the first few bytes of received data so that we can guess
     439                 :            :          * what kind of funny data we've been sent if SSL negotiation fails. */
     440         [ +  + ]:        794 :         if (sslv->n_head <= 0) {
     441                 :        529 :             sslv->n_head = recv(sslv->fd, sslv->head, sizeof sslv->head,
     442                 :            :                                 MSG_PEEK);
     443                 :            :         }
     444                 :            : 
     445                 :       1588 :         retval = (sslv->type == CLIENT
     446         [ +  + ]:        794 :                    ? SSL_connect(sslv->ssl) : SSL_accept(sslv->ssl));
     447         [ +  + ]:        794 :         if (retval != 1) {
     448                 :        564 :             int error = SSL_get_error(sslv->ssl, retval);
     449 [ +  + ][ +  - ]:        564 :             if (retval < 0 && ssl_wants_io(error)) {
     450                 :        562 :                 return EAGAIN;
     451                 :            :             } else {
     452                 :            :                 int unused;
     453                 :            : 
     454         [ +  - ]:          2 :                 interpret_ssl_error((sslv->type == CLIENT ? "SSL_connect"
     455                 :            :                                      : "SSL_accept"), retval, error, &unused);
     456                 :          2 :                 shutdown(sslv->fd, SHUT_RDWR);
     457                 :          2 :                 stream_report_content(sslv->head, sslv->n_head, STREAM_SSL,
     458                 :            :                                       &this_module, stream_get_name(stream));
     459                 :          2 :                 return EPROTO;
     460                 :            :             }
     461         [ +  + ]:        230 :         } else if (bootstrap_ca_cert) {
     462                 :          2 :             return do_ca_cert_bootstrap(stream);
     463         [ +  - ]:        228 :         } else if (verify_peer_cert
     464         [ -  + ]:        228 :                    && ((SSL_get_verify_mode(sslv->ssl)
     465                 :        228 :                        & (SSL_VERIFY_NONE | SSL_VERIFY_PEER))
     466                 :            :                        != SSL_VERIFY_PEER)) {
     467                 :            :             /* Two or more SSL connections completed at the same time while we
     468                 :            :              * were in bootstrap mode.  Only one of these can finish the
     469                 :            :              * bootstrap successfully.  The other one(s) must be rejected
     470                 :            :              * because they were not verified against the bootstrapped CA
     471                 :            :              * certificate.  (Alternatively we could verify them against the CA
     472                 :            :              * certificate, but that's more trouble than it's worth.  These
     473                 :            :              * connections will succeed the next time they retry, assuming that
     474                 :            :              * they have a certificate against the correct CA.) */
     475         [ #  # ]:          0 :             VLOG_INFO("rejecting SSL connection during bootstrap race window");
     476                 :          0 :             return EPROTO;
     477                 :            :         } else {
     478                 :        228 :             return 0;
     479                 :            :         }
     480                 :            :     }
     481                 :            : 
     482                 :          0 :     OVS_NOT_REACHED();
     483                 :            : }
     484                 :            : 
     485                 :            : static void
     486                 :        233 : ssl_close(struct stream *stream)
     487                 :            : {
     488                 :        233 :     struct ssl_stream *sslv = ssl_stream_cast(stream);
     489                 :        233 :     ssl_clear_txbuf(sslv);
     490                 :            : 
     491                 :            :     /* Attempt clean shutdown of the SSL connection.  This will work most of
     492                 :            :      * the time, as long as the kernel send buffer has some free space and the
     493                 :            :      * SSL connection isn't renegotiating, etc.  That has to be good enough,
     494                 :            :      * since we don't have any way to continue the close operation in the
     495                 :            :      * background. */
     496                 :        233 :     SSL_shutdown(sslv->ssl);
     497                 :            : 
     498                 :            :     /* SSL_shutdown() might have signaled an error, in which case we need to
     499                 :            :      * flush it out of the OpenSSL error queue or the next OpenSSL operation
     500                 :            :      * will falsely signal an error. */
     501                 :        233 :     ERR_clear_error();
     502                 :            : 
     503                 :        233 :     SSL_free(sslv->ssl);
     504                 :        233 :     closesocket(sslv->fd);
     505                 :        233 :     free(sslv);
     506                 :        233 : }
     507                 :            : 
     508                 :            : static void
     509                 :          0 : interpret_queued_ssl_error(const char *function)
     510                 :            : {
     511                 :          0 :     int queued_error = ERR_get_error();
     512         [ #  # ]:          0 :     if (queued_error != 0) {
     513         [ #  # ]:          0 :         VLOG_WARN_RL(&rl, "%s: %s",
     514                 :            :                      function, ERR_error_string(queued_error, NULL));
     515                 :            :     } else {
     516         [ #  # ]:          0 :         VLOG_ERR_RL(&rl, "%s: SSL_ERROR_SSL without queued error", function);
     517                 :            :     }
     518                 :          0 : }
     519                 :            : 
     520                 :            : static int
     521                 :        263 : interpret_ssl_error(const char *function, int ret, int error,
     522                 :            :                     int *want)
     523                 :            : {
     524                 :        263 :     *want = SSL_NOTHING;
     525                 :            : 
     526   [ -  -  +  -  :        263 :     switch (error) {
          -  -  -  +  -  
                      - ]
     527                 :            :     case SSL_ERROR_NONE:
     528         [ #  # ]:          0 :         VLOG_ERR_RL(&rl, "%s: unexpected SSL_ERROR_NONE", function);
     529                 :          0 :         break;
     530                 :            : 
     531                 :            :     case SSL_ERROR_ZERO_RETURN:
     532         [ #  # ]:          0 :         VLOG_ERR_RL(&rl, "%s: unexpected SSL_ERROR_ZERO_RETURN", function);
     533                 :          0 :         break;
     534                 :            : 
     535                 :            :     case SSL_ERROR_WANT_READ:
     536                 :        261 :         *want = SSL_READING;
     537                 :        261 :         return EAGAIN;
     538                 :            : 
     539                 :            :     case SSL_ERROR_WANT_WRITE:
     540                 :          0 :         *want = SSL_WRITING;
     541                 :          0 :         return EAGAIN;
     542                 :            : 
     543                 :            :     case SSL_ERROR_WANT_CONNECT:
     544         [ #  # ]:          0 :         VLOG_ERR_RL(&rl, "%s: unexpected SSL_ERROR_WANT_CONNECT", function);
     545                 :          0 :         break;
     546                 :            : 
     547                 :            :     case SSL_ERROR_WANT_ACCEPT:
     548         [ #  # ]:          0 :         VLOG_ERR_RL(&rl, "%s: unexpected SSL_ERROR_WANT_ACCEPT", function);
     549                 :          0 :         break;
     550                 :            : 
     551                 :            :     case SSL_ERROR_WANT_X509_LOOKUP:
     552         [ #  # ]:          0 :         VLOG_ERR_RL(&rl, "%s: unexpected SSL_ERROR_WANT_X509_LOOKUP",
     553                 :            :                     function);
     554                 :          0 :         break;
     555                 :            : 
     556                 :            :     case SSL_ERROR_SYSCALL: {
     557                 :          2 :         int queued_error = ERR_get_error();
     558         [ +  - ]:          2 :         if (queued_error == 0) {
     559         [ -  + ]:          2 :             if (ret < 0) {
     560                 :          0 :                 int status = errno;
     561         [ #  # ]:          0 :                 VLOG_WARN_RL(&rl, "%s: system error (%s)",
     562                 :            :                              function, ovs_strerror(status));
     563                 :          0 :                 return status;
     564                 :            :             } else {
     565         [ +  - ]:          2 :                 VLOG_WARN_RL(&rl, "%s: unexpected SSL connection close",
     566                 :            :                              function);
     567                 :          2 :                 return EPROTO;
     568                 :            :             }
     569                 :            :         } else {
     570         [ #  # ]:          0 :             VLOG_WARN_RL(&rl, "%s: %s",
     571                 :            :                          function, ERR_error_string(queued_error, NULL));
     572                 :          0 :             break;
     573                 :            :         }
     574                 :            :     }
     575                 :            : 
     576                 :            :     case SSL_ERROR_SSL:
     577                 :          0 :         interpret_queued_ssl_error(function);
     578                 :          0 :         break;
     579                 :            : 
     580                 :            :     default:
     581         [ #  # ]:          0 :         VLOG_ERR_RL(&rl, "%s: bad SSL error code %d", function, error);
     582                 :          0 :         break;
     583                 :            :     }
     584                 :          0 :     return EIO;
     585                 :            : }
     586                 :            : 
     587                 :            : static ssize_t
     588                 :        725 : ssl_recv(struct stream *stream, void *buffer, size_t n)
     589                 :            : {
     590                 :        725 :     struct ssl_stream *sslv = ssl_stream_cast(stream);
     591                 :            :     int old_state;
     592                 :            :     ssize_t ret;
     593                 :            : 
     594                 :            :     /* Behavior of zero-byte SSL_read is poorly defined. */
     595         [ -  + ]:        725 :     ovs_assert(n > 0);
     596                 :            : 
     597                 :        725 :     old_state = SSL_get_state(sslv->ssl);
     598                 :        725 :     ret = SSL_read(sslv->ssl, buffer, n);
     599         [ -  + ]:        725 :     if (old_state != SSL_get_state(sslv->ssl)) {
     600                 :          0 :         sslv->tx_want = SSL_NOTHING;
     601                 :            :     }
     602                 :        725 :     sslv->rx_want = SSL_NOTHING;
     603                 :            : 
     604         [ +  + ]:        725 :     if (ret > 0) {
     605                 :        352 :         return ret;
     606                 :            :     } else {
     607                 :        373 :         int error = SSL_get_error(sslv->ssl, ret);
     608         [ +  + ]:        373 :         if (error == SSL_ERROR_ZERO_RETURN) {
     609                 :        112 :             return 0;
     610                 :            :         } else {
     611                 :        261 :             return -interpret_ssl_error("SSL_read", ret, error,
     612                 :            :                                         &sslv->rx_want);
     613                 :            :         }
     614                 :            :     }
     615                 :            : }
     616                 :            : 
     617                 :            : static void
     618                 :        472 : ssl_clear_txbuf(struct ssl_stream *sslv)
     619                 :            : {
     620                 :        472 :     ofpbuf_delete(sslv->txbuf);
     621                 :        472 :     sslv->txbuf = NULL;
     622                 :        472 : }
     623                 :            : 
     624                 :            : static int
     625                 :        239 : ssl_do_tx(struct stream *stream)
     626                 :            : {
     627                 :        239 :     struct ssl_stream *sslv = ssl_stream_cast(stream);
     628                 :            : 
     629                 :            :     for (;;) {
     630                 :        239 :         int old_state = SSL_get_state(sslv->ssl);
     631                 :        239 :         int ret = SSL_write(sslv->ssl, sslv->txbuf->data, sslv->txbuf->size);
     632         [ -  + ]:        239 :         if (old_state != SSL_get_state(sslv->ssl)) {
     633                 :          0 :             sslv->rx_want = SSL_NOTHING;
     634                 :            :         }
     635                 :        239 :         sslv->tx_want = SSL_NOTHING;
     636         [ +  - ]:        239 :         if (ret > 0) {
     637                 :        239 :             ofpbuf_pull(sslv->txbuf, ret);
     638         [ +  - ]:        239 :             if (sslv->txbuf->size == 0) {
     639                 :        239 :                 return 0;
     640                 :            :             }
     641                 :            :         } else {
     642                 :          0 :             int ssl_error = SSL_get_error(sslv->ssl, ret);
     643         [ #  # ]:          0 :             if (ssl_error == SSL_ERROR_ZERO_RETURN) {
     644         [ #  # ]:          0 :                 VLOG_WARN_RL(&rl, "SSL_write: connection closed");
     645                 :          0 :                 return EPIPE;
     646                 :            :             } else {
     647                 :          0 :                 return interpret_ssl_error("SSL_write", ret, ssl_error,
     648                 :            :                                            &sslv->tx_want);
     649                 :            :             }
     650                 :            :         }
     651                 :          0 :     }
     652                 :            : }
     653                 :            : 
     654                 :            : static ssize_t
     655                 :        239 : ssl_send(struct stream *stream, const void *buffer, size_t n)
     656                 :            : {
     657                 :        239 :     struct ssl_stream *sslv = ssl_stream_cast(stream);
     658                 :            : 
     659         [ -  + ]:        239 :     if (sslv->txbuf) {
     660                 :          0 :         return -EAGAIN;
     661                 :            :     } else {
     662                 :            :         int error;
     663                 :            : 
     664                 :        239 :         sslv->txbuf = ofpbuf_clone_data(buffer, n);
     665                 :        239 :         error = ssl_do_tx(stream);
     666      [ +  -  - ]:        239 :         switch (error) {
     667                 :            :         case 0:
     668                 :        239 :             ssl_clear_txbuf(sslv);
     669                 :        239 :             return n;
     670                 :            :         case EAGAIN:
     671                 :          0 :             return n;
     672                 :            :         default:
     673                 :          0 :             sslv->txbuf = NULL;
     674                 :          0 :             return -error;
     675                 :            :         }
     676                 :            :     }
     677                 :            : }
     678                 :            : 
     679                 :            : static void
     680                 :       1100 : ssl_run(struct stream *stream)
     681                 :            : {
     682                 :       1100 :     struct ssl_stream *sslv = ssl_stream_cast(stream);
     683                 :            : 
     684 [ -  + ][ #  # ]:       1100 :     if (sslv->txbuf && ssl_do_tx(stream) != EAGAIN) {
     685                 :          0 :         ssl_clear_txbuf(sslv);
     686                 :            :     }
     687                 :       1100 : }
     688                 :            : 
     689                 :            : static void
     690                 :        642 : ssl_run_wait(struct stream *stream)
     691                 :            : {
     692                 :        642 :     struct ssl_stream *sslv = ssl_stream_cast(stream);
     693                 :            : 
     694         [ -  + ]:        642 :     if (sslv->tx_want != SSL_NOTHING) {
     695                 :          0 :         poll_fd_wait(sslv->fd, want_to_poll_events(sslv->tx_want));
     696                 :            :     }
     697                 :        642 : }
     698                 :            : 
     699                 :            : static void
     700                 :        656 : ssl_wait(struct stream *stream, enum stream_wait_type wait)
     701                 :            : {
     702                 :        656 :     struct ssl_stream *sslv = ssl_stream_cast(stream);
     703                 :            : 
     704   [ +  +  -  - ]:        656 :     switch (wait) {
     705                 :            :     case STREAM_CONNECT:
     706         [ +  + ]:        289 :         if (stream_connect(stream) != EAGAIN) {
     707                 :         20 :             poll_immediate_wake();
     708                 :            :         } else {
     709      [ -  +  - ]:        269 :             switch (sslv->state) {
     710                 :            :             case STATE_TCP_CONNECTING:
     711                 :          0 :                 poll_fd_wait(sslv->fd, POLLOUT);
     712                 :          0 :                 break;
     713                 :            : 
     714                 :            :             case STATE_SSL_CONNECTING:
     715                 :            :                 /* ssl_connect() called SSL_accept() or SSL_connect(), which
     716                 :            :                  * set up the status that we test here. */
     717                 :        269 :                 poll_fd_wait(sslv->fd,
     718                 :            :                                want_to_poll_events(SSL_want(sslv->ssl)));
     719                 :        269 :                 break;
     720                 :            : 
     721                 :            :             default:
     722                 :          0 :                 OVS_NOT_REACHED();
     723                 :            :             }
     724                 :            :         }
     725                 :        289 :         break;
     726                 :            : 
     727                 :            :     case STREAM_RECV:
     728         [ +  + ]:        367 :         if (sslv->rx_want != SSL_NOTHING) {
     729                 :        254 :             poll_fd_wait(sslv->fd, want_to_poll_events(sslv->rx_want));
     730                 :            :         } else {
     731                 :        113 :             poll_immediate_wake();
     732                 :            :         }
     733                 :        367 :         break;
     734                 :            : 
     735                 :            :     case STREAM_SEND:
     736         [ #  # ]:          0 :         if (!sslv->txbuf) {
     737                 :            :             /* We have room in our tx queue. */
     738                 :          0 :             poll_immediate_wake();
     739                 :            :         } else {
     740                 :            :             /* stream_run_wait() will do the right thing; don't bother with
     741                 :            :              * redundancy. */
     742                 :            :         }
     743                 :          0 :         break;
     744                 :            : 
     745                 :            :     default:
     746                 :          0 :         OVS_NOT_REACHED();
     747                 :            :     }
     748                 :        656 : }
     749                 :            : 
     750                 :            : const struct stream_class ssl_stream_class = {
     751                 :            :     "ssl",                      /* name */
     752                 :            :     true,                       /* needs_probes */
     753                 :            :     ssl_open,                   /* open */
     754                 :            :     ssl_close,                  /* close */
     755                 :            :     ssl_connect,                /* connect */
     756                 :            :     ssl_recv,                   /* recv */
     757                 :            :     ssl_send,                   /* send */
     758                 :            :     ssl_run,                    /* run */
     759                 :            :     ssl_run_wait,               /* run_wait */
     760                 :            :     ssl_wait,                   /* wait */
     761                 :            : };
     762                 :            : 
     763                 :            : /* Passive SSL. */
     764                 :            : 
     765                 :            : struct pssl_pstream
     766                 :            : {
     767                 :            :     struct pstream pstream;
     768                 :            :     int fd;
     769                 :            : };
     770                 :            : 
     771                 :            : const struct pstream_class pssl_pstream_class;
     772                 :            : 
     773                 :            : static struct pssl_pstream *
     774                 :       1744 : pssl_pstream_cast(struct pstream *pstream)
     775                 :            : {
     776                 :       1744 :     pstream_assert_class(pstream, &pssl_pstream_class);
     777                 :       1744 :     return CONTAINER_OF(pstream, struct pssl_pstream, pstream);
     778                 :            : }
     779                 :            : 
     780                 :            : static int
     781                 :         37 : pssl_open(const char *name OVS_UNUSED, char *suffix, struct pstream **pstreamp,
     782                 :            :           uint8_t dscp)
     783                 :            : {
     784                 :            :     char bound_name[SS_NTOP_BUFSIZE + 16];
     785                 :            :     char addrbuf[SS_NTOP_BUFSIZE];
     786                 :            :     struct sockaddr_storage ss;
     787                 :            :     struct pssl_pstream *pssl;
     788                 :            :     uint16_t port;
     789                 :            :     int retval;
     790                 :            :     int fd;
     791                 :            : 
     792                 :         37 :     retval = ssl_init();
     793         [ -  + ]:         37 :     if (retval) {
     794                 :          0 :         return retval;
     795                 :            :     }
     796                 :            : 
     797                 :         37 :     fd = inet_open_passive(SOCK_STREAM, suffix, OFP_PORT, &ss, dscp, true);
     798         [ -  + ]:         37 :     if (fd < 0) {
     799                 :          0 :         return -fd;
     800                 :            :     }
     801                 :            : 
     802                 :         37 :     port = ss_get_port(&ss);
     803                 :         37 :     snprintf(bound_name, sizeof bound_name, "pssl:%"PRIu16":%s",
     804                 :            :              port, ss_format_address(&ss, addrbuf, sizeof addrbuf));
     805                 :            : 
     806                 :         37 :     pssl = xmalloc(sizeof *pssl);
     807                 :         37 :     pstream_init(&pssl->pstream, &pssl_pstream_class, bound_name);
     808                 :         37 :     pstream_set_bound_port(&pssl->pstream, htons(port));
     809                 :         37 :     pssl->fd = fd;
     810                 :         37 :     *pstreamp = &pssl->pstream;
     811                 :         37 :     return 0;
     812                 :            : }
     813                 :            : 
     814                 :            : static void
     815                 :         37 : pssl_close(struct pstream *pstream)
     816                 :            : {
     817                 :         37 :     struct pssl_pstream *pssl = pssl_pstream_cast(pstream);
     818                 :         37 :     closesocket(pssl->fd);
     819                 :         37 :     free(pssl);
     820                 :         37 : }
     821                 :            : 
     822                 :            : static int
     823                 :        857 : pssl_accept(struct pstream *pstream, struct stream **new_streamp)
     824                 :            : {
     825                 :        857 :     struct pssl_pstream *pssl = pssl_pstream_cast(pstream);
     826                 :            :     char name[SS_NTOP_BUFSIZE + 16];
     827                 :            :     char addrbuf[SS_NTOP_BUFSIZE];
     828                 :            :     struct sockaddr_storage ss;
     829                 :        857 :     socklen_t ss_len = sizeof ss;
     830                 :            :     int new_fd;
     831                 :            :     int error;
     832                 :            : 
     833                 :        857 :     new_fd = accept(pssl->fd, (struct sockaddr *) &ss, &ss_len);
     834         [ +  + ]:        857 :     if (new_fd < 0) {
     835                 :        741 :         error = sock_errno();
     836                 :            : #ifdef _WIN32
     837                 :            :         if (error == WSAEWOULDBLOCK) {
     838                 :            :             error = EAGAIN;
     839                 :            :         }
     840                 :            : #endif
     841         [ -  + ]:        741 :         if (error != EAGAIN) {
     842         [ #  # ]:          0 :             VLOG_DBG_RL(&rl, "accept: %s", sock_strerror(error));
     843                 :            :         }
     844                 :        741 :         return error;
     845                 :            :     }
     846                 :            : 
     847                 :        116 :     error = set_nonblocking(new_fd);
     848         [ -  + ]:        116 :     if (error) {
     849                 :          0 :         closesocket(new_fd);
     850                 :          0 :         return error;
     851                 :            :     }
     852                 :            : 
     853                 :        116 :     snprintf(name, sizeof name, "ssl:%s:%"PRIu16,
     854                 :            :              ss_format_address(&ss, addrbuf, sizeof addrbuf),
     855                 :        116 :              ss_get_port(&ss));
     856                 :        857 :     return new_ssl_stream(name, new_fd, SERVER, STATE_SSL_CONNECTING,
     857                 :            :                           new_streamp);
     858                 :            : }
     859                 :            : 
     860                 :            : static void
     861                 :        850 : pssl_wait(struct pstream *pstream)
     862                 :            : {
     863                 :        850 :     struct pssl_pstream *pssl = pssl_pstream_cast(pstream);
     864                 :        850 :     poll_fd_wait(pssl->fd, POLLIN);
     865                 :        850 : }
     866                 :            : 
     867                 :            : const struct pstream_class pssl_pstream_class = {
     868                 :            :     "pssl",
     869                 :            :     true,
     870                 :            :     pssl_open,
     871                 :            :     pssl_close,
     872                 :            :     pssl_accept,
     873                 :            :     pssl_wait,
     874                 :            : };
     875                 :            : 
     876                 :            : /*
     877                 :            :  * Returns true if OpenSSL error is WANT_READ or WANT_WRITE, indicating that
     878                 :            :  * OpenSSL is requesting that we call it back when the socket is ready for read
     879                 :            :  * or writing, respectively.
     880                 :            :  */
     881                 :            : static bool
     882                 :        562 : ssl_wants_io(int ssl_error)
     883                 :            : {
     884                 :        562 :     return (ssl_error == SSL_ERROR_WANT_WRITE
     885 [ +  - ][ +  - ]:        562 :             || ssl_error == SSL_ERROR_WANT_READ);
     886                 :            : }
     887                 :            : 
     888                 :            : static int
     889                 :     181289 : ssl_init(void)
     890                 :            : {
     891                 :            :     static int init_status = -1;
     892         [ +  + ]:     181289 :     if (init_status < 0) {
     893                 :       1378 :         init_status = do_ssl_init();
     894         [ -  + ]:       1378 :         ovs_assert(init_status >= 0);
     895                 :            :     }
     896                 :     181289 :     return init_status;
     897                 :            : }
     898                 :            : 
     899                 :            : static int
     900                 :       1378 : do_ssl_init(void)
     901                 :            : {
     902                 :            :     SSL_METHOD *method;
     903                 :            : 
     904                 :            : #ifdef _WIN32
     905                 :            :     /* The following call is needed if we "#include <openssl/applink.c>". */
     906                 :            :     CRYPTO_malloc_init();
     907                 :            : #endif
     908                 :       1378 :     SSL_library_init();
     909                 :       1378 :     SSL_load_error_strings();
     910                 :            : 
     911         [ -  + ]:       1378 :     if (!RAND_status()) {
     912                 :            :         /* We occasionally see OpenSSL fail to seed its random number generator
     913                 :            :          * in heavily loaded hypervisors.  I suspect the following scenario:
     914                 :            :          *
     915                 :            :          * 1. OpenSSL calls read() to get 32 bytes from /dev/urandom.
     916                 :            :          * 2. The kernel generates 10 bytes of randomness and copies it out.
     917                 :            :          * 3. A signal arrives (perhaps SIGALRM).
     918                 :            :          * 4. The kernel interrupts the system call to service the signal.
     919                 :            :          * 5. Userspace gets 10 bytes of entropy.
     920                 :            :          * 6. OpenSSL doesn't read again to get the final 22 bytes.  Therefore
     921                 :            :          *    OpenSSL doesn't have enough entropy to consider itself
     922                 :            :          *    initialized.
     923                 :            :          *
     924                 :            :          * The only part I'm not entirely sure about is #6, because the OpenSSL
     925                 :            :          * code is so hard to read. */
     926                 :            :         uint8_t seed[32];
     927                 :            :         int retval;
     928                 :            : 
     929         [ #  # ]:          0 :         VLOG_WARN("OpenSSL random seeding failed, reseeding ourselves");
     930                 :            : 
     931                 :          0 :         retval = get_entropy(seed, sizeof seed);
     932         [ #  # ]:          0 :         if (retval) {
     933         [ #  # ]:          0 :             VLOG_ERR("failed to obtain entropy (%s)",
     934                 :            :                      ovs_retval_to_string(retval));
     935         [ #  # ]:          0 :             return retval > 0 ? retval : ENOPROTOOPT;
     936                 :            :         }
     937                 :            : 
     938                 :          0 :         RAND_seed(seed, sizeof seed);
     939                 :            :     }
     940                 :            : 
     941                 :            :     /* OpenSSL has a bunch of "connection methods": SSLv2_method(),
     942                 :            :      * SSLv3_method(), TLSv1_method(), SSLv23_method(), ...  Most of these
     943                 :            :      * support exactly one version of SSL, e.g. TLSv1_method() supports TLSv1
     944                 :            :      * only, not any earlier *or later* version.  The only exception is
     945                 :            :      * SSLv23_method(), which in fact supports *any* version of SSL and TLS.
     946                 :            :      * We don't want SSLv2 or SSLv3 support, so we turn it off below with
     947                 :            :      * SSL_CTX_set_options().
     948                 :            :      *
     949                 :            :      * The cast is needed to avoid a warning with newer versions of OpenSSL in
     950                 :            :      * which SSLv23_method() returns a "const" pointer. */
     951                 :       1378 :     method = CONST_CAST(SSL_METHOD *, SSLv23_method());
     952         [ -  + ]:       1378 :     if (method == NULL) {
     953         [ #  # ]:          0 :         VLOG_ERR("TLSv1_method: %s", ERR_error_string(ERR_get_error(), NULL));
     954                 :          0 :         return ENOPROTOOPT;
     955                 :            :     }
     956                 :            : 
     957                 :       1378 :     ctx = SSL_CTX_new(method);
     958         [ -  + ]:       1378 :     if (ctx == NULL) {
     959         [ #  # ]:          0 :         VLOG_ERR("SSL_CTX_new: %s", ERR_error_string(ERR_get_error(), NULL));
     960                 :          0 :         return ENOPROTOOPT;
     961                 :            :     }
     962                 :       1378 :     SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
     963                 :       1378 :     SSL_CTX_set_tmp_dh_callback(ctx, tmp_dh_callback);
     964                 :       1378 :     SSL_CTX_set_mode(ctx, SSL_MODE_ENABLE_PARTIAL_WRITE);
     965                 :       1378 :     SSL_CTX_set_mode(ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
     966                 :       1378 :     SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
     967                 :            :                        NULL);
     968                 :       1378 :     SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
     969                 :            : 
     970                 :       1378 :     return 0;
     971                 :            : }
     972                 :            : 
     973                 :            : static DH *
     974                 :          0 : tmp_dh_callback(SSL *ssl OVS_UNUSED, int is_export OVS_UNUSED, int keylength)
     975                 :            : {
     976                 :            :     struct dh {
     977                 :            :         int keylength;
     978                 :            :         DH *dh;
     979                 :            :         DH *(*constructor)(void);
     980                 :            :     };
     981                 :            : 
     982                 :            :     static struct dh dh_table[] = {
     983                 :            :         {1024, NULL, get_dh1024},
     984                 :            :         {2048, NULL, get_dh2048},
     985                 :            :         {4096, NULL, get_dh4096},
     986                 :            :     };
     987                 :            : 
     988                 :            :     struct dh *dh;
     989                 :            : 
     990         [ #  # ]:          0 :     for (dh = dh_table; dh < &dh_table[ARRAY_SIZE(dh_table)]; dh++) {
     991         [ #  # ]:          0 :         if (dh->keylength == keylength) {
     992         [ #  # ]:          0 :             if (!dh->dh) {
     993                 :          0 :                 dh->dh = dh->constructor();
     994         [ #  # ]:          0 :                 if (!dh->dh) {
     995                 :          0 :                     out_of_memory();
     996                 :            :                 }
     997                 :            :             }
     998                 :          0 :             return dh->dh;
     999                 :            :         }
    1000                 :            :     }
    1001         [ #  # ]:          0 :     VLOG_ERR_RL(&rl, "no Diffie-Hellman parameters for key length %d",
    1002                 :            :                 keylength);
    1003                 :          0 :     return NULL;
    1004                 :            : }
    1005                 :            : 
    1006                 :            : /* Returns true if SSL is at least partially configured. */
    1007                 :            : bool
    1008                 :          0 : stream_ssl_is_configured(void)
    1009                 :            : {
    1010 [ #  # ][ #  # ]:          0 :     return private_key.file_name || certificate.file_name || ca_cert.file_name;
                 [ #  # ]
    1011                 :            : }
    1012                 :            : 
    1013                 :            : static bool
    1014                 :     181134 : update_ssl_config(struct ssl_config_file *config, const char *file_name)
    1015                 :            : {
    1016                 :            :     struct timespec mtime;
    1017                 :            :     int error;
    1018                 :            : 
    1019 [ +  - ][ +  + ]:     181134 :     if (ssl_init() || !file_name) {
    1020                 :     178155 :         return false;
    1021                 :            :     }
    1022                 :            : 
    1023                 :            :     /* If the file name hasn't changed and neither has the file contents, stop
    1024                 :            :      * here. */
    1025                 :       2979 :     error = get_mtime(file_name, &mtime);
    1026 [ +  + ][ -  + ]:       2979 :     if (error && error != ENOENT) {
    1027         [ #  # ]:          0 :         VLOG_ERR_RL(&rl, "%s: stat failed (%s)",
    1028                 :            :                     file_name, ovs_strerror(error));
    1029                 :            :     }
    1030         [ +  + ]:       2979 :     if (config->file_name
    1031         [ +  - ]:       2538 :         && !strcmp(config->file_name, file_name)
    1032         [ +  - ]:       2538 :         && mtime.tv_sec == config->mtime.tv_sec
    1033         [ +  - ]:       2538 :         && mtime.tv_nsec == config->mtime.tv_nsec) {
    1034                 :       2538 :         return false;
    1035                 :            :     }
    1036                 :            : 
    1037                 :            :     /* Update 'config'. */
    1038                 :        441 :     config->mtime = mtime;
    1039         [ +  - ]:        441 :     if (file_name != config->file_name) {
    1040                 :        441 :         free(config->file_name);
    1041                 :        441 :         config->file_name = xstrdup(file_name);
    1042                 :            :     }
    1043                 :     181134 :     return true;
    1044                 :            : }
    1045                 :            : 
    1046                 :            : static void
    1047                 :        177 : stream_ssl_set_private_key_file__(const char *file_name)
    1048                 :            : {
    1049         [ +  + ]:        177 :     if (SSL_CTX_use_PrivateKey_file(ctx, file_name, SSL_FILETYPE_PEM) == 1) {
    1050                 :        175 :         private_key.read = true;
    1051                 :            :     } else {
    1052         [ +  - ]:          2 :         VLOG_ERR("SSL_use_PrivateKey_file: %s",
    1053                 :            :                  ERR_error_string(ERR_get_error(), NULL));
    1054                 :            :     }
    1055                 :        177 : }
    1056                 :            : 
    1057                 :            : void
    1058                 :        117 : stream_ssl_set_private_key_file(const char *file_name)
    1059                 :            : {
    1060         [ +  - ]:        117 :     if (update_ssl_config(&private_key, file_name)) {
    1061                 :        117 :         stream_ssl_set_private_key_file__(file_name);
    1062                 :            :     }
    1063                 :        117 : }
    1064                 :            : 
    1065                 :            : static void
    1066                 :        177 : stream_ssl_set_certificate_file__(const char *file_name)
    1067                 :            : {
    1068         [ +  + ]:        177 :     if (SSL_CTX_use_certificate_file(ctx, file_name, SSL_FILETYPE_PEM) == 1) {
    1069                 :        175 :         certificate.read = true;
    1070                 :            :     } else {
    1071         [ +  - ]:          2 :         VLOG_ERR("SSL_use_certificate_file: %s",
    1072                 :            :                  ERR_error_string(ERR_get_error(), NULL));
    1073                 :            :     }
    1074                 :        177 : }
    1075                 :            : 
    1076                 :            : void
    1077                 :        117 : stream_ssl_set_certificate_file(const char *file_name)
    1078                 :            : {
    1079         [ +  - ]:        117 :     if (update_ssl_config(&certificate, file_name)) {
    1080                 :        117 :         stream_ssl_set_certificate_file__(file_name);
    1081                 :            :     }
    1082                 :        117 : }
    1083                 :            : 
    1084                 :            : /* Sets the private key and certificate files in one operation.  Use this
    1085                 :            :  * interface, instead of calling stream_ssl_set_private_key_file() and
    1086                 :            :  * stream_ssl_set_certificate_file() individually, in the main loop of a
    1087                 :            :  * long-running program whose key and certificate might change at runtime.
    1088                 :            :  *
    1089                 :            :  * This is important because of OpenSSL's behavior.  If an OpenSSL context
    1090                 :            :  * already has a certificate, and stream_ssl_set_private_key_file() is called
    1091                 :            :  * to install a new private key, OpenSSL will report an error because the new
    1092                 :            :  * private key does not match the old certificate.  The other order, of setting
    1093                 :            :  * a new certificate, then setting a new private key, does work.
    1094                 :            :  *
    1095                 :            :  * If this were the only problem, calling stream_ssl_set_certificate_file()
    1096                 :            :  * before stream_ssl_set_private_key_file() would fix it.  But, if the private
    1097                 :            :  * key is changed before the certificate (e.g. someone "scp"s or "mv"s the new
    1098                 :            :  * private key in place before the certificate), then OpenSSL would reject that
    1099                 :            :  * change, and then the change of certificate would succeed, but there would be
    1100                 :            :  * no associated private key (because it had only changed once and therefore
    1101                 :            :  * there was no point in re-reading it).
    1102                 :            :  *
    1103                 :            :  * This function avoids both problems by, whenever either the certificate or
    1104                 :            :  * the private key file changes, re-reading both of them, in the correct order.
    1105                 :            :  */
    1106                 :            : void
    1107                 :      60271 : stream_ssl_set_key_and_cert(const char *private_key_file,
    1108                 :            :                             const char *certificate_file)
    1109                 :            : {
    1110         [ +  + ]:      60271 :     if (update_ssl_config(&private_key, private_key_file)
    1111         [ +  + ]:      60241 :         || update_ssl_config(&certificate, certificate_file)) {
    1112                 :         60 :         stream_ssl_set_certificate_file__(certificate_file);
    1113                 :         60 :         stream_ssl_set_private_key_file__(private_key_file);
    1114                 :            :     }
    1115                 :      60271 : }
    1116                 :            : 
    1117                 :            : /* Reads the X509 certificate or certificates in file 'file_name'.  On success,
    1118                 :            :  * stores the address of the first element in an array of pointers to
    1119                 :            :  * certificates in '*certs' and the number of certificates in the array in
    1120                 :            :  * '*n_certs', and returns 0.  On failure, stores a null pointer in '*certs', 0
    1121                 :            :  * in '*n_certs', and returns a positive errno value.
    1122                 :            :  *
    1123                 :            :  * The caller is responsible for freeing '*certs'. */
    1124                 :            : static int
    1125                 :          1 : read_cert_file(const char *file_name, X509 ***certs, size_t *n_certs)
    1126                 :            : {
    1127                 :            :     FILE *file;
    1128                 :          1 :     size_t allocated_certs = 0;
    1129                 :            : 
    1130                 :          1 :     *certs = NULL;
    1131                 :          1 :     *n_certs = 0;
    1132                 :            : 
    1133                 :          1 :     file = fopen(file_name, "r");
    1134         [ -  + ]:          1 :     if (!file) {
    1135         [ #  # ]:          0 :         VLOG_ERR("failed to open %s for reading: %s",
    1136                 :            :                  file_name, ovs_strerror(errno));
    1137                 :          0 :         return errno;
    1138                 :            :     }
    1139                 :            : 
    1140                 :            :     for (;;) {
    1141                 :            :         X509 *certificate;
    1142                 :            :         int c;
    1143                 :            : 
    1144                 :            :         /* Read certificate from file. */
    1145                 :          1 :         certificate = PEM_read_X509(file, NULL, NULL, NULL);
    1146         [ -  + ]:          1 :         if (!certificate) {
    1147                 :            :             size_t i;
    1148                 :            : 
    1149         [ #  # ]:          0 :             VLOG_ERR("PEM_read_X509 failed reading %s: %s",
    1150                 :            :                      file_name, ERR_error_string(ERR_get_error(), NULL));
    1151         [ #  # ]:          0 :             for (i = 0; i < *n_certs; i++) {
    1152                 :          0 :                 X509_free((*certs)[i]);
    1153                 :            :             }
    1154                 :          0 :             free(*certs);
    1155                 :          0 :             *certs = NULL;
    1156                 :          0 :             *n_certs = 0;
    1157                 :          0 :             fclose(file);
    1158                 :          0 :             return EIO;
    1159                 :            :         }
    1160                 :            : 
    1161                 :            :         /* Add certificate to array. */
    1162         [ +  - ]:          1 :         if (*n_certs >= allocated_certs) {
    1163                 :          1 :             *certs = x2nrealloc(*certs, &allocated_certs, sizeof **certs);
    1164                 :            :         }
    1165                 :          1 :         (*certs)[(*n_certs)++] = certificate;
    1166                 :            : 
    1167                 :            :         /* Are there additional certificates in the file? */
    1168                 :            :         do {
    1169                 :          1 :             c = getc(file);
    1170         [ -  + ]:          1 :         } while (isspace(c));
    1171         [ +  - ]:          1 :         if (c == EOF) {
    1172                 :          1 :             break;
    1173                 :            :         }
    1174                 :          0 :         ungetc(c, file);
    1175                 :          0 :     }
    1176                 :          1 :     fclose(file);
    1177                 :          1 :     return 0;
    1178                 :            : }
    1179                 :            : 
    1180                 :            : 
    1181                 :            : /* Sets 'file_name' as the name of a file containing one or more X509
    1182                 :            :  * certificates to send to the peer.  Typical use in OpenFlow is to send the CA
    1183                 :            :  * certificate to the peer, which enables a switch to pick up the controller's
    1184                 :            :  * CA certificate on its first connection. */
    1185                 :            : void
    1186                 :          1 : stream_ssl_set_peer_ca_cert_file(const char *file_name)
    1187                 :            : {
    1188                 :            :     X509 **certs;
    1189                 :            :     size_t n_certs;
    1190                 :            :     size_t i;
    1191                 :            : 
    1192         [ -  + ]:          1 :     if (ssl_init()) {
    1193                 :          0 :         return;
    1194                 :            :     }
    1195                 :            : 
    1196         [ +  - ]:          1 :     if (!read_cert_file(file_name, &certs, &n_certs)) {
    1197         [ +  + ]:          2 :         for (i = 0; i < n_certs; i++) {
    1198         [ -  + ]:          1 :             if (SSL_CTX_add_extra_chain_cert(ctx, certs[i]) != 1) {
    1199         [ #  # ]:          0 :                 VLOG_ERR("SSL_CTX_add_extra_chain_cert: %s",
    1200                 :            :                          ERR_error_string(ERR_get_error(), NULL));
    1201                 :            :             }
    1202                 :            :         }
    1203                 :          1 :         free(certs);
    1204                 :            :     }
    1205                 :            : }
    1206                 :            : 
    1207                 :            : /* Logs fingerprint of CA certificate 'cert' obtained from 'file_name'. */
    1208                 :            : static void
    1209                 :          2 : log_ca_cert(const char *file_name, X509 *cert)
    1210                 :            : {
    1211                 :            :     unsigned char digest[EVP_MAX_MD_SIZE];
    1212                 :            :     unsigned int n_bytes;
    1213                 :            :     struct ds fp;
    1214                 :            :     char *subject;
    1215                 :            : 
    1216                 :          2 :     ds_init(&fp);
    1217         [ -  + ]:          2 :     if (!X509_digest(cert, EVP_sha1(), digest, &n_bytes)) {
    1218                 :          0 :         ds_put_cstr(&fp, "<out of memory>");
    1219                 :            :     } else {
    1220                 :            :         unsigned int i;
    1221         [ +  + ]:         42 :         for (i = 0; i < n_bytes; i++) {
    1222         [ +  + ]:         40 :             if (i) {
    1223                 :         38 :                 ds_put_char(&fp, ':');
    1224                 :            :             }
    1225                 :         40 :             ds_put_format(&fp, "%02x", digest[i]);
    1226                 :            :         }
    1227                 :            :     }
    1228                 :          2 :     subject = X509_NAME_oneline(X509_get_subject_name(cert), NULL, 0);
    1229 [ +  - ][ +  - ]:          2 :     VLOG_INFO("Trusting CA cert from %s (%s) (fingerprint %s)", file_name,
    1230                 :            :               subject ? subject : "<out of memory>", ds_cstr(&fp));
    1231                 :          2 :     OPENSSL_free(subject);
    1232                 :          2 :     ds_destroy(&fp);
    1233                 :          2 : }
    1234                 :            : 
    1235                 :            : static void
    1236                 :      60388 : stream_ssl_set_ca_cert_file__(const char *file_name,
    1237                 :            :                               bool bootstrap, bool force)
    1238                 :            : {
    1239                 :            :     struct stat s;
    1240                 :            : 
    1241 [ +  + ][ +  - ]:      60388 :     if (!update_ssl_config(&ca_cert, file_name) && !force) {
    1242                 :      60241 :         return;
    1243                 :            :     }
    1244                 :            : 
    1245         [ -  + ]:        147 :     if (!strcmp(file_name, "none")) {
    1246                 :          0 :         verify_peer_cert = false;
    1247         [ #  # ]:          0 :         VLOG_WARN("Peer certificate validation disabled "
    1248                 :            :                   "(this is a security risk)");
    1249 [ +  + ][ +  + ]:        147 :     } else if (bootstrap && stat(file_name, &s) && errno == ENOENT) {
                 [ +  - ]
    1250                 :          2 :         bootstrap_ca_cert = true;
    1251                 :            :     } else {
    1252                 :        145 :         STACK_OF(X509_NAME) *cert_names = SSL_load_client_CA_file(file_name);
    1253         [ +  + ]:        145 :         if (cert_names) {
    1254                 :            :             /* Set up list of CAs that the server will accept from the
    1255                 :            :              * client. */
    1256                 :        144 :             SSL_CTX_set_client_CA_list(ctx, cert_names);
    1257                 :            : 
    1258                 :            :             /* Set up CAs for OpenSSL to trust in verifying the peer's
    1259                 :            :              * certificate. */
    1260                 :        144 :             SSL_CTX_set_cert_store(ctx, X509_STORE_new());
    1261         [ -  + ]:        144 :             if (SSL_CTX_load_verify_locations(ctx, file_name, NULL) != 1) {
    1262         [ #  # ]:          0 :                 VLOG_ERR("SSL_CTX_load_verify_locations: %s",
    1263                 :            :                          ERR_error_string(ERR_get_error(), NULL));
    1264                 :          0 :                 return;
    1265                 :            :             }
    1266                 :        144 :             bootstrap_ca_cert = false;
    1267                 :            :         } else {
    1268         [ +  - ]:          1 :             VLOG_ERR("failed to load client certificates from %s: %s",
    1269                 :            :                      file_name, ERR_error_string(ERR_get_error(), NULL));
    1270                 :            :         }
    1271                 :            :     }
    1272                 :        147 :     ca_cert.read = true;
    1273                 :            : }
    1274                 :            : 
    1275                 :            : /* Sets 'file_name' as the name of the file from which to read the CA
    1276                 :            :  * certificate used to verify the peer within SSL connections.  If 'bootstrap'
    1277                 :            :  * is false, the file must exist.  If 'bootstrap' is false, then the file is
    1278                 :            :  * read if it is exists; if it does not, then it will be created from the CA
    1279                 :            :  * certificate received from the peer on the first SSL connection. */
    1280                 :            : void
    1281                 :      60388 : stream_ssl_set_ca_cert_file(const char *file_name, bool bootstrap)
    1282                 :            : {
    1283                 :      60388 :     stream_ssl_set_ca_cert_file__(file_name, bootstrap, false);
    1284                 :      60388 : }
    1285                 :            : 
    1286                 :            : /* SSL protocol logging. */
    1287                 :            : 
    1288                 :            : static const char *
    1289                 :         12 : ssl_alert_level_to_string(uint8_t type)
    1290                 :            : {
    1291      [ +  -  - ]:         12 :     switch (type) {
    1292                 :         12 :     case 1: return "warning";
    1293                 :          0 :     case 2: return "fatal";
    1294                 :          0 :     default: return "<unknown>";
    1295                 :            :     }
    1296                 :            : }
    1297                 :            : 
    1298                 :            : static const char *
    1299                 :         12 : ssl_alert_description_to_string(uint8_t type)
    1300                 :            : {
    1301   [ +  -  -  -  :         12 :     switch (type) {
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
             -  -  -  -  
                      - ]
    1302                 :         12 :     case 0: return "close_notify";
    1303                 :          0 :     case 10: return "unexpected_message";
    1304                 :          0 :     case 20: return "bad_record_mac";
    1305                 :          0 :     case 21: return "decryption_failed";
    1306                 :          0 :     case 22: return "record_overflow";
    1307                 :          0 :     case 30: return "decompression_failure";
    1308                 :          0 :     case 40: return "handshake_failure";
    1309                 :          0 :     case 42: return "bad_certificate";
    1310                 :          0 :     case 43: return "unsupported_certificate";
    1311                 :          0 :     case 44: return "certificate_revoked";
    1312                 :          0 :     case 45: return "certificate_expired";
    1313                 :          0 :     case 46: return "certificate_unknown";
    1314                 :          0 :     case 47: return "illegal_parameter";
    1315                 :          0 :     case 48: return "unknown_ca";
    1316                 :          0 :     case 49: return "access_denied";
    1317                 :          0 :     case 50: return "decode_error";
    1318                 :          0 :     case 51: return "decrypt_error";
    1319                 :          0 :     case 60: return "export_restriction";
    1320                 :          0 :     case 70: return "protocol_version";
    1321                 :          0 :     case 71: return "insufficient_security";
    1322                 :          0 :     case 80: return "internal_error";
    1323                 :          0 :     case 90: return "user_canceled";
    1324                 :          0 :     case 100: return "no_renegotiation";
    1325                 :          0 :     default: return "<unknown>";
    1326                 :            :     }
    1327                 :            : }
    1328                 :            : 
    1329                 :            : static const char *
    1330                 :        128 : ssl_handshake_type_to_string(uint8_t type)
    1331                 :            : {
    1332   [ -  +  +  +  :        128 :     switch (type) {
          -  +  +  +  +  
                   +  + ]
    1333                 :          0 :     case 0: return "hello_request";
    1334                 :         14 :     case 1: return "client_hello";
    1335                 :         12 :     case 2: return "server_hello";
    1336                 :         24 :     case 11: return "certificate";
    1337                 :          0 :     case 12: return "server_key_exchange";
    1338                 :         12 :     case 13: return "certificate_request";
    1339                 :          6 :     case 14: return "server_hello_done";
    1340                 :         12 :     case 15: return "certificate_verify";
    1341                 :         12 :     case 16: return "client_key_exchange";
    1342                 :         24 :     case 20: return "finished";
    1343                 :         12 :     default: return "<unknown>";
    1344                 :            :     }
    1345                 :            : }
    1346                 :            : 
    1347                 :            : static void
    1348                 :        344 : ssl_protocol_cb(int write_p, int version OVS_UNUSED, int content_type,
    1349                 :            :                 const void *buf_, size_t len, SSL *ssl OVS_UNUSED, void *sslv_)
    1350                 :            : {
    1351                 :        344 :     const struct ssl_stream *sslv = sslv_;
    1352                 :        344 :     const uint8_t *buf = buf_;
    1353                 :            :     struct ds details;
    1354                 :            : 
    1355         [ -  + ]:        344 :     if (!VLOG_IS_DBG_ENABLED()) {
    1356                 :          0 :         return;
    1357                 :            :     }
    1358                 :            : 
    1359                 :        344 :     ds_init(&details);
    1360         [ +  + ]:        344 :     if (content_type == 20) {
    1361                 :         24 :         ds_put_cstr(&details, "change_cipher_spec");
    1362         [ +  + ]:        320 :     } else if (content_type == 21) {
    1363                 :         12 :         ds_put_format(&details, "alert: %s, %s",
    1364                 :         12 :                       ssl_alert_level_to_string(buf[0]),
    1365                 :         12 :                       ssl_alert_description_to_string(buf[1]));
    1366         [ +  + ]:        308 :     } else if (content_type == 22) {
    1367                 :        128 :         ds_put_format(&details, "handshake: %s",
    1368                 :        128 :                       ssl_handshake_type_to_string(buf[0]));
    1369                 :            :     } else {
    1370                 :        180 :         ds_put_format(&details, "type %d", content_type);
    1371                 :            :     }
    1372                 :            : 
    1373 [ +  - ][ +  + ]:        344 :     VLOG_DBG("%s%u%s%s %s (%"PRIuSIZE" bytes)",
                 [ +  + ]
    1374                 :            :              sslv->type == CLIENT ? "client" : "server",
    1375                 :            :              sslv->session_nr, write_p ? "-->" : "<--",
    1376                 :            :              stream_get_name(&sslv->stream), ds_cstr(&details), len);
    1377                 :            : 
    1378                 :        344 :     ds_destroy(&details);
    1379                 :            : }

Generated by: LCOV version 1.12