LCOV - code coverage report
Current view: top level - core/tsi - transport_security.c (source / functions) Hit Total Coverage
Test: tmp.CaZ6RjdVn2 Lines: 120 122 98.4 %
Date: 2015-12-10 22:15:08 Functions: 20 20 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/transport_security.h"
      35             : 
      36             : #include <stdlib.h>
      37             : #include <string.h>
      38             : 
      39             : /* --- Tracing. --- */
      40             : 
      41             : int tsi_tracing_enabled = 0;
      42             : 
      43             : /* --- Utils. --- */
      44             : 
      45        5991 : char *tsi_strdup(const char *src) {
      46             :   char *dst;
      47             :   size_t len;
      48        5991 :   if (!src) return NULL;
      49        5991 :   len = strlen(src) + 1;
      50        5991 :   dst = malloc(len);
      51        5991 :   if (!dst) return NULL;
      52        5991 :   memcpy(dst, src, len);
      53        5991 :   return dst;
      54             : }
      55             : 
      56             : /* --- tsi_result common implementation. --- */
      57             : 
      58          14 : const char *tsi_result_to_string(tsi_result result) {
      59          14 :   switch (result) {
      60             :     case TSI_OK:
      61           1 :       return "TSI_OK";
      62             :     case TSI_UNKNOWN_ERROR:
      63           1 :       return "TSI_UNKNOWN_ERROR";
      64             :     case TSI_INVALID_ARGUMENT:
      65           1 :       return "TSI_INVALID_ARGUMENT";
      66             :     case TSI_PERMISSION_DENIED:
      67           1 :       return "TSI_PERMISSION_DENIED";
      68             :     case TSI_INCOMPLETE_DATA:
      69           1 :       return "TSI_INCOMPLETE_DATA";
      70             :     case TSI_FAILED_PRECONDITION:
      71           1 :       return "TSI_FAILED_PRECONDITION";
      72             :     case TSI_UNIMPLEMENTED:
      73           1 :       return "TSI_UNIMPLEMENTED";
      74             :     case TSI_INTERNAL_ERROR:
      75           1 :       return "TSI_INTERNAL_ERROR";
      76             :     case TSI_DATA_CORRUPTED:
      77           1 :       return "TSI_DATA_CORRUPTED";
      78             :     case TSI_NOT_FOUND:
      79           1 :       return "TSI_NOT_FOUND";
      80             :     case TSI_PROTOCOL_FAILURE:
      81           1 :       return "TSI_PROTOCOL_FAILURE";
      82             :     case TSI_HANDSHAKE_IN_PROGRESS:
      83           1 :       return "TSI_HANDSHAKE_IN_PROGRESS";
      84             :     case TSI_OUT_OF_RESOURCES:
      85           1 :       return "TSI_OUT_OF_RESOURCES";
      86             :     default:
      87           1 :       return "UNKNOWN";
      88             :   }
      89             : }
      90             : 
      91             : /* --- tsi_frame_protector common implementation. ---
      92             : 
      93             :    Calls specific implementation after state/input validation. */
      94             : 
      95     3365760 : tsi_result tsi_frame_protector_protect(tsi_frame_protector *self,
      96             :                                        const unsigned char *unprotected_bytes,
      97             :                                        size_t *unprotected_bytes_size,
      98             :                                        unsigned char *protected_output_frames,
      99             :                                        size_t *protected_output_frames_size) {
     100     3365760 :   if (self == NULL || unprotected_bytes == NULL ||
     101     3365759 :       unprotected_bytes_size == NULL || protected_output_frames == NULL ||
     102             :       protected_output_frames_size == NULL) {
     103           1 :     return TSI_INVALID_ARGUMENT;
     104             :   }
     105     3365759 :   return self->vtable->protect(self, unprotected_bytes, unprotected_bytes_size,
     106             :                                protected_output_frames,
     107             :                                protected_output_frames_size);
     108             : }
     109             : 
     110      445157 : tsi_result tsi_frame_protector_protect_flush(
     111             :     tsi_frame_protector *self, unsigned char *protected_output_frames,
     112             :     size_t *protected_output_frames_size, size_t *still_pending_size) {
     113      445157 :   if (self == NULL || protected_output_frames == NULL ||
     114      445156 :       protected_output_frames == NULL || still_pending_size == NULL) {
     115           1 :     return TSI_INVALID_ARGUMENT;
     116             :   }
     117      445156 :   return self->vtable->protect_flush(self, protected_output_frames,
     118             :                                      protected_output_frames_size,
     119             :                                      still_pending_size);
     120             : }
     121             : 
     122     2144802 : tsi_result tsi_frame_protector_unprotect(
     123             :     tsi_frame_protector *self, const unsigned char *protected_frames_bytes,
     124             :     size_t *protected_frames_bytes_size, unsigned char *unprotected_bytes,
     125             :     size_t *unprotected_bytes_size) {
     126     2144802 :   if (self == NULL || protected_frames_bytes == NULL ||
     127     2144801 :       protected_frames_bytes_size == NULL || unprotected_bytes == NULL ||
     128             :       unprotected_bytes_size == NULL) {
     129           1 :     return TSI_INVALID_ARGUMENT;
     130             :   }
     131     2144801 :   return self->vtable->unprotect(self, protected_frames_bytes,
     132             :                                  protected_frames_bytes_size, unprotected_bytes,
     133             :                                  unprotected_bytes_size);
     134             : }
     135             : 
     136        1245 : void tsi_frame_protector_destroy(tsi_frame_protector *self) {
     137        2490 :   if (self == NULL) return;
     138        1245 :   self->vtable->destroy(self);
     139             : }
     140             : 
     141             : /* --- tsi_handshaker common implementation. ---
     142             : 
     143             :    Calls specific implementation after state/input validation. */
     144             : 
     145        3455 : tsi_result tsi_handshaker_get_bytes_to_send_to_peer(tsi_handshaker *self,
     146             :                                                     unsigned char *bytes,
     147             :                                                     size_t *bytes_size) {
     148        3455 :   if (self == NULL || bytes == NULL || bytes_size == NULL) {
     149           1 :     return TSI_INVALID_ARGUMENT;
     150             :   }
     151        3454 :   if (self->frame_protector_created) return TSI_FAILED_PRECONDITION;
     152        3454 :   return self->vtable->get_bytes_to_send_to_peer(self, bytes, bytes_size);
     153             : }
     154             : 
     155        2361 : tsi_result tsi_handshaker_process_bytes_from_peer(tsi_handshaker *self,
     156             :                                                   const unsigned char *bytes,
     157             :                                                   size_t *bytes_size) {
     158        2361 :   if (self == NULL || bytes == NULL || bytes_size == NULL) {
     159           1 :     return TSI_INVALID_ARGUMENT;
     160             :   }
     161        2360 :   if (self->frame_protector_created) return TSI_FAILED_PRECONDITION;
     162        2360 :   return self->vtable->process_bytes_from_peer(self, bytes, bytes_size);
     163             : }
     164             : 
     165       11489 : tsi_result tsi_handshaker_get_result(tsi_handshaker *self) {
     166       11489 :   if (self == NULL) return TSI_INVALID_ARGUMENT;
     167       11488 :   if (self->frame_protector_created) return TSI_FAILED_PRECONDITION;
     168       11488 :   return self->vtable->get_result(self);
     169             : }
     170             : 
     171        1179 : tsi_result tsi_handshaker_extract_peer(tsi_handshaker *self, tsi_peer *peer) {
     172        1179 :   if (self == NULL || peer == NULL) return TSI_INVALID_ARGUMENT;
     173        1178 :   memset(peer, 0, sizeof(tsi_peer));
     174        1178 :   if (self->frame_protector_created) return TSI_FAILED_PRECONDITION;
     175        1178 :   if (tsi_handshaker_get_result(self) != TSI_OK) {
     176           1 :     return TSI_FAILED_PRECONDITION;
     177             :   }
     178        1177 :   return self->vtable->extract_peer(self, peer);
     179             : }
     180             : 
     181        1179 : tsi_result tsi_handshaker_create_frame_protector(
     182             :     tsi_handshaker *self, size_t *max_protected_frame_size,
     183             :     tsi_frame_protector **protector) {
     184             :   tsi_result result;
     185        1179 :   if (self == NULL || protector == NULL) return TSI_INVALID_ARGUMENT;
     186        1178 :   if (self->frame_protector_created) return TSI_FAILED_PRECONDITION;
     187        1178 :   if (tsi_handshaker_get_result(self) != TSI_OK) {
     188           1 :     return TSI_FAILED_PRECONDITION;
     189             :   }
     190        1177 :   result = self->vtable->create_frame_protector(self, max_protected_frame_size,
     191             :                                                 protector);
     192        1177 :   if (result == TSI_OK) {
     193        1177 :     self->frame_protector_created = 1;
     194             :   }
     195        1177 :   return result;
     196             : }
     197             : 
     198        1191 : void tsi_handshaker_destroy(tsi_handshaker *self) {
     199        2382 :   if (self == NULL) return;
     200        1191 :   self->vtable->destroy(self);
     201             : }
     202             : 
     203             : /* --- tsi_peer implementation. --- */
     204             : 
     205       11858 : tsi_peer_property tsi_init_peer_property(void) {
     206             :   tsi_peer_property property;
     207       11858 :   memset(&property, 0, sizeof(tsi_peer_property));
     208       11858 :   return property;
     209             : }
     210             : 
     211        1799 : static void tsi_peer_destroy_list_property(tsi_peer_property *children,
     212             :                                            size_t child_count) {
     213             :   size_t i;
     214        7666 :   for (i = 0; i < child_count; i++) {
     215        5867 :     tsi_peer_property_destruct(&children[i]);
     216             :   }
     217        1799 :   free(children);
     218        1799 : }
     219             : 
     220        5867 : void tsi_peer_property_destruct(tsi_peer_property *property) {
     221        5867 :   if (property->name != NULL) {
     222        5867 :     free(property->name);
     223             :   }
     224        5867 :   if (property->value.data != NULL) {
     225        5862 :     free(property->value.data);
     226             :   }
     227        5867 :   *property = tsi_init_peer_property(); /* Reset everything to 0. */
     228        5867 : }
     229             : 
     230        2386 : void tsi_peer_destruct(tsi_peer *self) {
     231        4772 :   if (self == NULL) return;
     232        2386 :   if (self->properties != NULL) {
     233        1799 :     tsi_peer_destroy_list_property(self->properties, self->property_count);
     234        1799 :     self->properties = NULL;
     235             :   }
     236        2386 :   self->property_count = 0;
     237             : }
     238             : 
     239        5991 : tsi_result tsi_construct_allocated_string_peer_property(
     240             :     const char *name, size_t value_length, tsi_peer_property *property) {
     241        5991 :   *property = tsi_init_peer_property();
     242        5991 :   if (name != NULL) {
     243        5991 :     property->name = tsi_strdup(name);
     244        5991 :     if (property->name == NULL) return TSI_OUT_OF_RESOURCES;
     245             :   }
     246        5991 :   if (value_length > 0) {
     247        5986 :     property->value.data = calloc(1, value_length);
     248        5986 :     if (property->value.data == NULL) {
     249           0 :       tsi_peer_property_destruct(property);
     250           0 :       return TSI_OUT_OF_RESOURCES;
     251             :     }
     252        5986 :     property->value.length = value_length;
     253             :   }
     254        5860 :   return TSI_OK;
     255             : }
     256             : 
     257         774 : tsi_result tsi_construct_string_peer_property_from_cstring(
     258             :     const char *name, const char *value, tsi_peer_property *property) {
     259         774 :   return tsi_construct_string_peer_property(name, value, strlen(value),
     260             :                                             property);
     261             : }
     262             : 
     263        5991 : tsi_result tsi_construct_string_peer_property(const char *name,
     264             :                                               const char *value,
     265             :                                               size_t value_length,
     266             :                                               tsi_peer_property *property) {
     267        5991 :   tsi_result result = tsi_construct_allocated_string_peer_property(
     268             :       name, value_length, property);
     269        5991 :   if (result != TSI_OK) return result;
     270        5991 :   if (value_length > 0) {
     271        5986 :     memcpy(property->value.data, value, value_length);
     272             :   }
     273        5860 :   return TSI_OK;
     274             : }
     275             : 
     276        1338 : tsi_result tsi_construct_peer(size_t property_count, tsi_peer *peer) {
     277        1338 :   memset(peer, 0, sizeof(tsi_peer));
     278        1338 :   if (property_count > 0) {
     279        1338 :     peer->properties = calloc(property_count, sizeof(tsi_peer_property));
     280        1338 :     if (peer->properties == NULL) return TSI_OUT_OF_RESOURCES;
     281        1338 :     peer->property_count = property_count;
     282             :   }
     283        1318 :   return TSI_OK;
     284             : }

Generated by: LCOV version 1.11