LCOV - code coverage report
Current view: top level - src/core/tsi - fake_transport_security.c (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 257 277 92.8 %
Date: 2015-10-10 Functions: 22 22 100.0 %

          Line data    Source code
       1             : /*
       2             :  *
       3             :  * Copyright 2015, Google Inc.
       4             :  * All rights reserved.
       5             :  *
       6             :  * Redistribution and use in source and binary forms, with or without
       7             :  * modification, are permitted provided that the following conditions are
       8             :  * met:
       9             :  *
      10             :  *     * Redistributions of source code must retain the above copyright
      11             :  * notice, this list of conditions and the following disclaimer.
      12             :  *     * Redistributions in binary form must reproduce the above
      13             :  * copyright notice, this list of conditions and the following disclaimer
      14             :  * in the documentation and/or other materials provided with the
      15             :  * distribution.
      16             :  *     * Neither the name of Google Inc. nor the names of its
      17             :  * contributors may be used to endorse or promote products derived from
      18             :  * this software without specific prior written permission.
      19             :  *
      20             :  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      21             :  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
      22             :  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
      23             :  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
      24             :  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      25             :  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
      26             :  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      27             :  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      28             :  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      29             :  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
      30             :  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      31             :  *
      32             :  */
      33             : 
      34             : #include "src/core/tsi/fake_transport_security.h"
      35             : 
      36             : #include <stdlib.h>
      37             : #include <string.h>
      38             : 
      39             : #include <grpc/support/log.h>
      40             : #include <grpc/support/port_platform.h>
      41             : #include <grpc/support/useful.h>
      42             : #include "src/core/tsi/transport_security.h"
      43             : 
      44             : /* --- Constants. ---*/
      45             : #define TSI_FAKE_FRAME_HEADER_SIZE 4
      46             : #define TSI_FAKE_FRAME_INITIAL_ALLOCATED_SIZE 64
      47             : #define TSI_FAKE_DEFAULT_FRAME_SIZE 16384
      48             : 
      49             : /* --- Structure definitions. ---*/
      50             : 
      51             : /* a frame is encoded like this:
      52             :    | size |     data    |
      53             :    where the size field value is the size of the size field plus the size of
      54             :    the data encoded in little endian on 4 bytes.  */
      55             : typedef struct {
      56             :   unsigned char *data;
      57             :   size_t size;
      58             :   size_t allocated_size;
      59             :   size_t offset;
      60             :   int needs_draining;
      61             : } tsi_fake_frame;
      62             : 
      63             : typedef enum {
      64             :   TSI_FAKE_CLIENT_INIT = 0,
      65             :   TSI_FAKE_SERVER_INIT = 1,
      66             :   TSI_FAKE_CLIENT_FINISHED = 2,
      67             :   TSI_FAKE_SERVER_FINISHED = 3,
      68             :   TSI_FAKE_HANDSHAKE_MESSAGE_MAX = 4
      69             : } tsi_fake_handshake_message;
      70             : 
      71             : typedef struct {
      72             :   tsi_handshaker base;
      73             :   int is_client;
      74             :   tsi_fake_handshake_message next_message_to_send;
      75             :   int needs_incoming_message;
      76             :   tsi_fake_frame incoming;
      77             :   tsi_fake_frame outgoing;
      78             :   tsi_result result;
      79             : } tsi_fake_handshaker;
      80             : 
      81             : typedef struct {
      82             :   tsi_frame_protector base;
      83             :   tsi_fake_frame protect_frame;
      84             :   tsi_fake_frame unprotect_frame;
      85             :   size_t max_frame_size;
      86             : } tsi_fake_frame_protector;
      87             : 
      88             : /* --- Utils. ---*/
      89             : 
      90             : static const char *tsi_fake_handshake_message_strings[] = {
      91             :     "CLIENT_INIT", "SERVER_INIT", "CLIENT_FINISHED", "SERVER_FINISHED"};
      92             : 
      93         292 : static const char *tsi_fake_handshake_message_to_string(int msg) {
      94         292 :   if (msg < 0 || msg >= TSI_FAKE_HANDSHAKE_MESSAGE_MAX) {
      95           0 :     gpr_log(GPR_ERROR, "Invalid message %d", msg);
      96           0 :     return "UNKNOWN";
      97             :   }
      98         292 :   return tsi_fake_handshake_message_strings[msg];
      99             : }
     100             : 
     101         292 : static tsi_result tsi_fake_handshake_message_from_string(
     102             :     const char *msg_string, tsi_fake_handshake_message *msg) {
     103             :   tsi_fake_handshake_message i;
     104         730 :   for (i = 0; i < TSI_FAKE_HANDSHAKE_MESSAGE_MAX; i++) {
     105         730 :     if (strncmp(msg_string, tsi_fake_handshake_message_strings[i],
     106             :                 strlen(tsi_fake_handshake_message_strings[i])) == 0) {
     107         292 :       *msg = i;
     108         292 :       return TSI_OK;
     109             :     }
     110             :   }
     111           0 :   gpr_log(GPR_ERROR, "Invalid handshake message.");
     112           0 :   return TSI_DATA_CORRUPTED;
     113             : }
     114             : 
     115      266350 : static gpr_uint32 load32_little_endian(const unsigned char *buf) {
     116      799050 :   return ((gpr_uint32)(buf[0]) | (gpr_uint32)(buf[1] << 8) |
     117      532700 :           (gpr_uint32)(buf[2] << 16) | (gpr_uint32)(buf[3] << 24));
     118             : }
     119             : 
     120      265642 : static void store32_little_endian(gpr_uint32 value, unsigned char *buf) {
     121      265642 :   buf[3] = (unsigned char)((value >> 24) & 0xFF);
     122      265642 :   buf[2] = (unsigned char)((value >> 16) & 0xFF);
     123      265642 :   buf[1] = (unsigned char)((value >> 8) & 0xFF);
     124      265642 :   buf[0] = (unsigned char)((value) & 0xFF);
     125      265642 : }
     126             : 
     127      401011 : static void tsi_fake_frame_reset(tsi_fake_frame *frame, int needs_draining) {
     128      401011 :   frame->offset = 0;
     129      401011 :   frame->needs_draining = needs_draining;
     130      401011 :   if (!needs_draining) frame->size = 0;
     131      401011 : }
     132             : 
     133             : /* Returns 1 if successful, 0 otherwise. */
     134      266642 : static int tsi_fake_frame_ensure_size(tsi_fake_frame *frame) {
     135      266642 :   if (frame->data == NULL) {
     136         146 :     frame->allocated_size = frame->size;
     137         146 :     frame->data = malloc(frame->allocated_size);
     138         146 :     if (frame->data == NULL) return 0;
     139      266496 :   } else if (frame->size > frame->allocated_size) {
     140         549 :     unsigned char *new_data = realloc(frame->data, frame->size);
     141         549 :     if (new_data == NULL) {
     142           0 :       free(frame->data);
     143           0 :       frame->data = NULL;
     144           0 :       return 0;
     145             :     }
     146         549 :     frame->data = new_data;
     147         549 :     frame->allocated_size = frame->size;
     148             :   }
     149      266642 :   return 1;
     150             : }
     151             : 
     152             : /* This method should not be called if frame->needs_framing is not 0.  */
     153     1789407 : static tsi_result fill_frame_from_bytes(const unsigned char *incoming_bytes,
     154             :                                         size_t *incoming_bytes_size,
     155             :                                         tsi_fake_frame *frame) {
     156     1789407 :   size_t available_size = *incoming_bytes_size;
     157     1789407 :   size_t to_read_size = 0;
     158     1789407 :   const unsigned char *bytes_cursor = incoming_bytes;
     159             : 
     160     1789407 :   if (frame->needs_draining) return TSI_INTERNAL_ERROR;
     161     1789407 :   if (frame->data == NULL) {
     162         504 :     frame->allocated_size = TSI_FAKE_FRAME_INITIAL_ALLOCATED_SIZE;
     163         504 :     frame->data = malloc(frame->allocated_size);
     164         504 :     if (frame->data == NULL) return TSI_OUT_OF_RESOURCES;
     165             :   }
     166             : 
     167     1789407 :   if (frame->offset < TSI_FAKE_FRAME_HEADER_SIZE) {
     168      518606 :     to_read_size = TSI_FAKE_FRAME_HEADER_SIZE - frame->offset;
     169      518606 :     if (to_read_size > available_size) {
     170             :       /* Just fill what we can and exit. */
     171      252256 :       memcpy(frame->data + frame->offset, bytes_cursor, available_size);
     172      252256 :       bytes_cursor += available_size;
     173      252256 :       frame->offset += available_size;
     174      252256 :       *incoming_bytes_size = (size_t)(bytes_cursor - incoming_bytes);
     175      252256 :       return TSI_INCOMPLETE_DATA;
     176             :     }
     177      266350 :     memcpy(frame->data + frame->offset, bytes_cursor, to_read_size);
     178      266350 :     bytes_cursor += to_read_size;
     179      266350 :     frame->offset += to_read_size;
     180      266350 :     available_size -= to_read_size;
     181      266350 :     frame->size = load32_little_endian(frame->data);
     182      266350 :     if (!tsi_fake_frame_ensure_size(frame)) return TSI_OUT_OF_RESOURCES;
     183             :   }
     184             : 
     185     1537151 :   to_read_size = frame->size - frame->offset;
     186     1537151 :   if (to_read_size > available_size) {
     187     1403074 :     memcpy(frame->data + frame->offset, bytes_cursor, available_size);
     188     1403074 :     frame->offset += available_size;
     189     1403074 :     bytes_cursor += available_size;
     190     1403074 :     *incoming_bytes_size = (size_t)(bytes_cursor - incoming_bytes);
     191     1403074 :     return TSI_INCOMPLETE_DATA;
     192             :   }
     193      134077 :   memcpy(frame->data + frame->offset, bytes_cursor, to_read_size);
     194      134077 :   bytes_cursor += to_read_size;
     195      134077 :   *incoming_bytes_size = (size_t)(bytes_cursor - incoming_bytes);
     196      134077 :   tsi_fake_frame_reset(frame, 1 /* needs_draining */);
     197      134077 :   return TSI_OK;
     198             : }
     199             : 
     200             : /* This method should not be called if frame->needs_framing is 0.  */
     201      269826 : static tsi_result drain_frame_to_bytes(unsigned char *outgoing_bytes,
     202             :                                        size_t *outgoing_bytes_size,
     203             :                                        tsi_fake_frame *frame) {
     204      269826 :   size_t to_write_size = frame->size - frame->offset;
     205      269826 :   if (!frame->needs_draining) return TSI_INTERNAL_ERROR;
     206      269826 :   if (*outgoing_bytes_size < to_write_size) {
     207        3476 :     memcpy(outgoing_bytes, frame->data + frame->offset, *outgoing_bytes_size);
     208        3476 :     frame->offset += *outgoing_bytes_size;
     209        3476 :     return TSI_INCOMPLETE_DATA;
     210             :   }
     211      266350 :   memcpy(outgoing_bytes, frame->data + frame->offset, to_write_size);
     212      266350 :   *outgoing_bytes_size = to_write_size;
     213      266350 :   tsi_fake_frame_reset(frame, 0 /* needs_draining */);
     214      266350 :   return TSI_OK;
     215             : }
     216             : 
     217         292 : static tsi_result bytes_to_frame(unsigned char *bytes, size_t bytes_size,
     218             :                                  tsi_fake_frame *frame) {
     219         292 :   frame->offset = 0;
     220         292 :   frame->size = bytes_size + TSI_FAKE_FRAME_HEADER_SIZE;
     221         292 :   if (!tsi_fake_frame_ensure_size(frame)) return TSI_OUT_OF_RESOURCES;
     222         292 :   store32_little_endian((gpr_uint32)frame->size, frame->data);
     223         292 :   memcpy(frame->data + TSI_FAKE_FRAME_HEADER_SIZE, bytes, bytes_size);
     224         292 :   tsi_fake_frame_reset(frame, 1 /* needs draining */);
     225         292 :   return TSI_OK;
     226             : }
     227             : 
     228         722 : static void tsi_fake_frame_destruct(tsi_fake_frame *frame) {
     229         722 :   if (frame->data != NULL) free(frame->data);
     230         722 : }
     231             : 
     232             : /* --- tsi_frame_protector methods implementation. ---*/
     233             : 
     234      138022 : static tsi_result fake_protector_protect(tsi_frame_protector *self,
     235             :                                          const unsigned char *unprotected_bytes,
     236             :                                          size_t *unprotected_bytes_size,
     237             :                                          unsigned char *protected_output_frames,
     238             :                                          size_t *protected_output_frames_size) {
     239      138022 :   tsi_result result = TSI_OK;
     240      138022 :   tsi_fake_frame_protector *impl = (tsi_fake_frame_protector *)self;
     241             :   unsigned char frame_header[TSI_FAKE_FRAME_HEADER_SIZE];
     242      138022 :   tsi_fake_frame *frame = &impl->protect_frame;
     243      138022 :   size_t saved_output_size = *protected_output_frames_size;
     244      138022 :   size_t drained_size = 0;
     245      138022 :   size_t *num_bytes_written = protected_output_frames_size;
     246      138022 :   *num_bytes_written = 0;
     247             : 
     248             :   /* Try to drain first. */
     249      138022 :   if (frame->needs_draining) {
     250        1590 :     drained_size = saved_output_size - *num_bytes_written;
     251        1590 :     result =
     252             :         drain_frame_to_bytes(protected_output_frames, &drained_size, frame);
     253        1590 :     *num_bytes_written += drained_size;
     254        1590 :     protected_output_frames += drained_size;
     255        1590 :     if (result != TSI_OK) {
     256         786 :       if (result == TSI_INCOMPLETE_DATA) {
     257         786 :         *unprotected_bytes_size = 0;
     258         786 :         result = TSI_OK;
     259             :       }
     260         786 :       return result;
     261             :     }
     262             :   }
     263             : 
     264             :   /* Now process the unprotected_bytes. */
     265      137236 :   if (frame->needs_draining) return TSI_INTERNAL_ERROR;
     266      137236 :   if (frame->size == 0) {
     267             :     /* New frame, create a header. */
     268      133077 :     size_t written_in_frame_size = 0;
     269      133077 :     store32_little_endian((gpr_uint32)impl->max_frame_size, frame_header);
     270      133077 :     written_in_frame_size = TSI_FAKE_FRAME_HEADER_SIZE;
     271      133077 :     result = fill_frame_from_bytes(frame_header, &written_in_frame_size, frame);
     272      133077 :     if (result != TSI_INCOMPLETE_DATA) {
     273           0 :       gpr_log(GPR_ERROR, "fill_frame_from_bytes returned %s",
     274             :               tsi_result_to_string(result));
     275           0 :       return result;
     276             :     }
     277             :   }
     278      137236 :   result =
     279             :       fill_frame_from_bytes(unprotected_bytes, unprotected_bytes_size, frame);
     280      137236 :   if (result != TSI_OK) {
     281      136432 :     if (result == TSI_INCOMPLETE_DATA) result = TSI_OK;
     282      136432 :     return result;
     283             :   }
     284             : 
     285             :   /* Try to drain again. */
     286         804 :   if (!frame->needs_draining) return TSI_INTERNAL_ERROR;
     287         804 :   if (frame->offset != 0) return TSI_INTERNAL_ERROR;
     288         804 :   drained_size = saved_output_size - *num_bytes_written;
     289         804 :   result = drain_frame_to_bytes(protected_output_frames, &drained_size, frame);
     290         804 :   *num_bytes_written += drained_size;
     291         804 :   if (result == TSI_INCOMPLETE_DATA) result = TSI_OK;
     292         804 :   return result;
     293             : }
     294             : 
     295      132464 : static tsi_result fake_protector_protect_flush(
     296             :     tsi_frame_protector *self, unsigned char *protected_output_frames,
     297             :     size_t *protected_output_frames_size, size_t *still_pending_size) {
     298      132464 :   tsi_result result = TSI_OK;
     299      132464 :   tsi_fake_frame_protector *impl = (tsi_fake_frame_protector *)self;
     300      132464 :   tsi_fake_frame *frame = &impl->protect_frame;
     301      132464 :   if (!frame->needs_draining) {
     302             :     /* Create a short frame. */
     303      132273 :     frame->size = frame->offset;
     304      132273 :     frame->offset = 0;
     305      132273 :     frame->needs_draining = 1;
     306      132273 :     store32_little_endian((gpr_uint32)frame->size,
     307             :                           frame->data); /* Overwrite header. */
     308             :   }
     309      132464 :   result = drain_frame_to_bytes(protected_output_frames,
     310             :                                 protected_output_frames_size, frame);
     311      132464 :   if (result == TSI_INCOMPLETE_DATA) result = TSI_OK;
     312      132464 :   *still_pending_size = frame->size - frame->offset;
     313      132464 :   return result;
     314             : }
     315             : 
     316     1519586 : static tsi_result fake_protector_unprotect(
     317             :     tsi_frame_protector *self, const unsigned char *protected_frames_bytes,
     318             :     size_t *protected_frames_bytes_size, unsigned char *unprotected_bytes,
     319             :     size_t *unprotected_bytes_size) {
     320     1519586 :   tsi_result result = TSI_OK;
     321     1519586 :   tsi_fake_frame_protector *impl = (tsi_fake_frame_protector *)self;
     322     1519586 :   tsi_fake_frame *frame = &impl->unprotect_frame;
     323     1519586 :   size_t saved_output_size = *unprotected_bytes_size;
     324     1519586 :   size_t drained_size = 0;
     325     1519586 :   size_t *num_bytes_written = unprotected_bytes_size;
     326     1519586 :   *num_bytes_written = 0;
     327             : 
     328             :   /* Try to drain first. */
     329     1519586 :   if (frame->needs_draining) {
     330             :     /* Go past the header if needed. */
     331        1695 :     if (frame->offset == 0) frame->offset = TSI_FAKE_FRAME_HEADER_SIZE;
     332        1695 :     drained_size = saved_output_size - *num_bytes_written;
     333        1695 :     result = drain_frame_to_bytes(unprotected_bytes, &drained_size, frame);
     334        1695 :     unprotected_bytes += drained_size;
     335        1695 :     *num_bytes_written += drained_size;
     336        1695 :     if (result != TSI_OK) {
     337         784 :       if (result == TSI_INCOMPLETE_DATA) {
     338         784 :         *protected_frames_bytes_size = 0;
     339         784 :         result = TSI_OK;
     340             :       }
     341         784 :       return result;
     342             :     }
     343             :   }
     344             : 
     345             :   /* Now process the protected_bytes. */
     346     1518802 :   if (frame->needs_draining) return TSI_INTERNAL_ERROR;
     347     1518802 :   result = fill_frame_from_bytes(protected_frames_bytes,
     348             :                                  protected_frames_bytes_size, frame);
     349     1518802 :   if (result != TSI_OK) {
     350     1385821 :     if (result == TSI_INCOMPLETE_DATA) result = TSI_OK;
     351     1385821 :     return result;
     352             :   }
     353             : 
     354             :   /* Try to drain again. */
     355      132981 :   if (!frame->needs_draining) return TSI_INTERNAL_ERROR;
     356      132981 :   if (frame->offset != 0) return TSI_INTERNAL_ERROR;
     357      132981 :   frame->offset = TSI_FAKE_FRAME_HEADER_SIZE; /* Go past the header. */
     358      132981 :   drained_size = saved_output_size - *num_bytes_written;
     359      132981 :   result = drain_frame_to_bytes(unprotected_bytes, &drained_size, frame);
     360      132981 :   *num_bytes_written += drained_size;
     361      132981 :   if (result == TSI_INCOMPLETE_DATA) result = TSI_OK;
     362      132981 :   return result;
     363             : }
     364             : 
     365         214 : static void fake_protector_destroy(tsi_frame_protector *self) {
     366         214 :   tsi_fake_frame_protector *impl = (tsi_fake_frame_protector *)self;
     367         214 :   tsi_fake_frame_destruct(&impl->protect_frame);
     368         214 :   tsi_fake_frame_destruct(&impl->unprotect_frame);
     369         214 :   free(self);
     370         214 : }
     371             : 
     372             : static const tsi_frame_protector_vtable frame_protector_vtable = {
     373             :     fake_protector_protect, fake_protector_protect_flush,
     374             :     fake_protector_unprotect, fake_protector_destroy,
     375             : };
     376             : 
     377             : /* --- tsi_handshaker methods implementation. ---*/
     378             : 
     379         366 : static tsi_result fake_handshaker_get_bytes_to_send_to_peer(
     380             :     tsi_handshaker *self, unsigned char *bytes, size_t *bytes_size) {
     381         366 :   tsi_fake_handshaker *impl = (tsi_fake_handshaker *)self;
     382         366 :   tsi_result result = TSI_OK;
     383         366 :   if (impl->needs_incoming_message || impl->result == TSI_OK) {
     384          74 :     *bytes_size = 0;
     385          74 :     return TSI_OK;
     386             :   }
     387         292 :   if (!impl->outgoing.needs_draining) {
     388         292 :     tsi_fake_handshake_message next_message_to_send =
     389         292 :         impl->next_message_to_send + 2;
     390         292 :     const char *msg_string =
     391         292 :         tsi_fake_handshake_message_to_string(impl->next_message_to_send);
     392         292 :     result = bytes_to_frame((unsigned char *)msg_string, strlen(msg_string),
     393             :                             &impl->outgoing);
     394         292 :     if (result != TSI_OK) return result;
     395         292 :     if (next_message_to_send > TSI_FAKE_HANDSHAKE_MESSAGE_MAX) {
     396          73 :       next_message_to_send = TSI_FAKE_HANDSHAKE_MESSAGE_MAX;
     397             :     }
     398         292 :     if (tsi_tracing_enabled) {
     399           0 :       gpr_log(GPR_INFO, "%s prepared %s.",
     400           0 :               impl->is_client ? "Client" : "Server",
     401           0 :               tsi_fake_handshake_message_to_string(impl->next_message_to_send));
     402             :     }
     403         292 :     impl->next_message_to_send = next_message_to_send;
     404             :   }
     405         292 :   result = drain_frame_to_bytes(bytes, bytes_size, &impl->outgoing);
     406         292 :   if (result != TSI_OK) return result;
     407         438 :   if (!impl->is_client &&
     408         146 :       impl->next_message_to_send == TSI_FAKE_HANDSHAKE_MESSAGE_MAX) {
     409             :     /* We're done. */
     410          73 :     if (tsi_tracing_enabled) {
     411           0 :       gpr_log(GPR_INFO, "Server is done.");
     412             :     }
     413          73 :     impl->result = TSI_OK;
     414             :   } else {
     415         219 :     impl->needs_incoming_message = 1;
     416             :   }
     417         292 :   return TSI_OK;
     418             : }
     419             : 
     420         292 : static tsi_result fake_handshaker_process_bytes_from_peer(
     421             :     tsi_handshaker *self, const unsigned char *bytes, size_t *bytes_size) {
     422         292 :   tsi_result result = TSI_OK;
     423         292 :   tsi_fake_handshaker *impl = (tsi_fake_handshaker *)self;
     424         292 :   tsi_fake_handshake_message expected_msg = impl->next_message_to_send - 1;
     425             :   tsi_fake_handshake_message received_msg;
     426             : 
     427         292 :   if (!impl->needs_incoming_message || impl->result == TSI_OK) {
     428           0 :     *bytes_size = 0;
     429           0 :     return TSI_OK;
     430             :   }
     431         292 :   result = fill_frame_from_bytes(bytes, bytes_size, &impl->incoming);
     432         292 :   if (result != TSI_OK) return result;
     433             : 
     434             :   /* We now have a complete frame. */
     435         292 :   result = tsi_fake_handshake_message_from_string(
     436         292 :       (const char *)impl->incoming.data + TSI_FAKE_FRAME_HEADER_SIZE,
     437             :       &received_msg);
     438         292 :   if (result != TSI_OK) {
     439           0 :     impl->result = result;
     440           0 :     return result;
     441             :   }
     442         292 :   if (received_msg != expected_msg) {
     443           0 :     gpr_log(GPR_ERROR, "Invalid received message (%s instead of %s)",
     444             :             tsi_fake_handshake_message_to_string(received_msg),
     445             :             tsi_fake_handshake_message_to_string(expected_msg));
     446             :   }
     447         292 :   if (tsi_tracing_enabled) {
     448           0 :     gpr_log(GPR_INFO, "%s received %s.", impl->is_client ? "Client" : "Server",
     449             :             tsi_fake_handshake_message_to_string(received_msg));
     450             :   }
     451         292 :   tsi_fake_frame_reset(&impl->incoming, 0 /* needs_draining */);
     452         292 :   impl->needs_incoming_message = 0;
     453         292 :   if (impl->next_message_to_send == TSI_FAKE_HANDSHAKE_MESSAGE_MAX) {
     454             :     /* We're done. */
     455          73 :     if (tsi_tracing_enabled) {
     456           0 :       gpr_log(GPR_INFO, "%s is done.", impl->is_client ? "Client" : "Server");
     457             :     }
     458          73 :     impl->result = TSI_OK;
     459             :   }
     460         292 :   return TSI_OK;
     461             : }
     462             : 
     463        1242 : static tsi_result fake_handshaker_get_result(tsi_handshaker *self) {
     464        1242 :   tsi_fake_handshaker *impl = (tsi_fake_handshaker *)self;
     465        1242 :   return impl->result;
     466             : }
     467             : 
     468         146 : static tsi_result fake_handshaker_extract_peer(tsi_handshaker *self,
     469             :                                                tsi_peer *peer) {
     470         146 :   tsi_result result = tsi_construct_peer(1, peer);
     471         146 :   if (result != TSI_OK) return result;
     472         146 :   result = tsi_construct_string_peer_property_from_cstring(
     473             :       TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_FAKE_CERTIFICATE_TYPE,
     474             :       &peer->properties[0]);
     475         146 :   if (result != TSI_OK) tsi_peer_destruct(peer);
     476         146 :   return result;
     477             : }
     478             : 
     479         146 : static tsi_result fake_handshaker_create_frame_protector(
     480             :     tsi_handshaker *self, size_t *max_protected_frame_size,
     481             :     tsi_frame_protector **protector) {
     482         146 :   *protector = tsi_create_fake_protector(max_protected_frame_size);
     483         146 :   if (*protector == NULL) return TSI_OUT_OF_RESOURCES;
     484         146 :   return TSI_OK;
     485             : }
     486             : 
     487         147 : static void fake_handshaker_destroy(tsi_handshaker *self) {
     488         147 :   tsi_fake_handshaker *impl = (tsi_fake_handshaker *)self;
     489         147 :   tsi_fake_frame_destruct(&impl->incoming);
     490         147 :   tsi_fake_frame_destruct(&impl->outgoing);
     491         147 :   free(self);
     492         147 : }
     493             : 
     494             : static const tsi_handshaker_vtable handshaker_vtable = {
     495             :     fake_handshaker_get_bytes_to_send_to_peer,
     496             :     fake_handshaker_process_bytes_from_peer, fake_handshaker_get_result,
     497             :     fake_handshaker_extract_peer, fake_handshaker_create_frame_protector,
     498             :     fake_handshaker_destroy,
     499             : };
     500             : 
     501         147 : tsi_handshaker *tsi_create_fake_handshaker(int is_client) {
     502         147 :   tsi_fake_handshaker *impl = calloc(1, sizeof(tsi_fake_handshaker));
     503         147 :   impl->base.vtable = &handshaker_vtable;
     504         147 :   impl->is_client = is_client;
     505         147 :   impl->result = TSI_HANDSHAKE_IN_PROGRESS;
     506         147 :   if (is_client) {
     507          73 :     impl->needs_incoming_message = 0;
     508          73 :     impl->next_message_to_send = TSI_FAKE_CLIENT_INIT;
     509             :   } else {
     510          74 :     impl->needs_incoming_message = 1;
     511          74 :     impl->next_message_to_send = TSI_FAKE_SERVER_INIT;
     512             :   }
     513         147 :   return &impl->base;
     514             : }
     515             : 
     516         214 : tsi_frame_protector *tsi_create_fake_protector(
     517             :     size_t *max_protected_frame_size) {
     518         214 :   tsi_fake_frame_protector *impl = calloc(1, sizeof(tsi_fake_frame_protector));
     519         214 :   if (impl == NULL) return NULL;
     520         214 :   impl->max_frame_size = (max_protected_frame_size == NULL)
     521             :                              ? TSI_FAKE_DEFAULT_FRAME_SIZE
     522         214 :                              : *max_protected_frame_size;
     523         214 :   impl->base.vtable = &frame_protector_vtable;
     524         214 :   return &impl->base;
     525             : }

Generated by: LCOV version 1.10