blob: a2232bfab1073cb51d030a96dffa146f18854087 [file] [log] [blame]
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001/*
2 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +02003 * Copyright 2015 gRPC authors.
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08004 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +02005 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08008 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +02009 * http://www.apache.org/licenses/LICENSE-2.0
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080010 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +020011 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080016 *
17 */
18
Craig Tillerb29f1fe2017-03-28 15:49:23 -070019#include "src/core/tsi/transport_security.h"
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080020
Nicolas "Pixel" Nobleb29d8cf2016-04-08 01:38:29 +020021#include <grpc/support/alloc.h>
22#include <grpc/support/string_util.h>
23
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080024#include <stdlib.h>
25#include <string.h>
26
Julien Boeuf980f6002015-02-26 16:41:41 -080027/* --- Tracing. --- */
28
ncteisen06bce6e2017-07-10 07:58:49 -070029grpc_tracer_flag tsi_tracing_enabled = GRPC_TRACER_INITIALIZER(false, "tsi");
Julien Boeuf980f6002015-02-26 16:41:41 -080030
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080031/* --- tsi_result common implementation. --- */
32
Craig Tillerbaa14a92017-11-03 09:09:36 -070033const char* tsi_result_to_string(tsi_result result) {
Craig Tillera82950e2015-09-22 12:33:20 -070034 switch (result) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080035 case TSI_OK:
36 return "TSI_OK";
37 case TSI_UNKNOWN_ERROR:
38 return "TSI_UNKNOWN_ERROR";
39 case TSI_INVALID_ARGUMENT:
40 return "TSI_INVALID_ARGUMENT";
41 case TSI_PERMISSION_DENIED:
42 return "TSI_PERMISSION_DENIED";
43 case TSI_INCOMPLETE_DATA:
44 return "TSI_INCOMPLETE_DATA";
45 case TSI_FAILED_PRECONDITION:
46 return "TSI_FAILED_PRECONDITION";
47 case TSI_UNIMPLEMENTED:
48 return "TSI_UNIMPLEMENTED";
49 case TSI_INTERNAL_ERROR:
50 return "TSI_INTERNAL_ERROR";
51 case TSI_DATA_CORRUPTED:
52 return "TSI_DATA_CORRUPTED";
53 case TSI_NOT_FOUND:
54 return "TSI_NOT_FOUND";
55 case TSI_PROTOCOL_FAILURE:
56 return "TSI_PROTOCOL_FAILURE";
57 case TSI_HANDSHAKE_IN_PROGRESS:
58 return "TSI_HANDSHAKE_IN_PROGRESS";
59 case TSI_OUT_OF_RESOURCES:
60 return "TSI_OUT_OF_RESOURCES";
jiangtaoli201620b9f942017-04-07 12:50:33 -070061 case TSI_ASYNC:
62 return "TSI_ASYNC";
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080063 default:
64 return "UNKNOWN";
Craig Tillera82950e2015-09-22 12:33:20 -070065 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080066}
67
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080068/* --- tsi_frame_protector common implementation. ---
69
70 Calls specific implementation after state/input validation. */
71
Craig Tillerbaa14a92017-11-03 09:09:36 -070072tsi_result tsi_frame_protector_protect(tsi_frame_protector* self,
73 const unsigned char* unprotected_bytes,
74 size_t* unprotected_bytes_size,
75 unsigned char* protected_output_frames,
76 size_t* protected_output_frames_size) {
Craig Tillerbe98d242017-11-10 15:26:57 -080077 if (self == nullptr || self->vtable == nullptr ||
78 unprotected_bytes == nullptr || unprotected_bytes_size == nullptr ||
79 protected_output_frames == nullptr ||
Craig Tiller4782d922017-11-10 09:53:21 -080080 protected_output_frames_size == nullptr) {
Craig Tillera82950e2015-09-22 12:33:20 -070081 return TSI_INVALID_ARGUMENT;
82 }
Craig Tiller4782d922017-11-10 09:53:21 -080083 if (self->vtable->protect == nullptr) return TSI_UNIMPLEMENTED;
Craig Tillera82950e2015-09-22 12:33:20 -070084 return self->vtable->protect(self, unprotected_bytes, unprotected_bytes_size,
85 protected_output_frames,
86 protected_output_frames_size);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080087}
88
Craig Tillera82950e2015-09-22 12:33:20 -070089tsi_result tsi_frame_protector_protect_flush(
Craig Tillerbaa14a92017-11-03 09:09:36 -070090 tsi_frame_protector* self, unsigned char* protected_output_frames,
91 size_t* protected_output_frames_size, size_t* still_pending_size) {
Craig Tillerbe98d242017-11-10 15:26:57 -080092 if (self == nullptr || self->vtable == nullptr ||
93 protected_output_frames == nullptr ||
94 protected_output_frames_size == nullptr ||
95 still_pending_size == nullptr) {
Craig Tillera82950e2015-09-22 12:33:20 -070096 return TSI_INVALID_ARGUMENT;
97 }
Craig Tiller4782d922017-11-10 09:53:21 -080098 if (self->vtable->protect_flush == nullptr) return TSI_UNIMPLEMENTED;
Craig Tillera82950e2015-09-22 12:33:20 -070099 return self->vtable->protect_flush(self, protected_output_frames,
100 protected_output_frames_size,
101 still_pending_size);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800102}
103
Craig Tillera82950e2015-09-22 12:33:20 -0700104tsi_result tsi_frame_protector_unprotect(
Craig Tillerbaa14a92017-11-03 09:09:36 -0700105 tsi_frame_protector* self, const unsigned char* protected_frames_bytes,
106 size_t* protected_frames_bytes_size, unsigned char* unprotected_bytes,
107 size_t* unprotected_bytes_size) {
Craig Tillerbe98d242017-11-10 15:26:57 -0800108 if (self == nullptr || self->vtable == nullptr ||
109 protected_frames_bytes == nullptr ||
Craig Tiller4782d922017-11-10 09:53:21 -0800110 protected_frames_bytes_size == nullptr || unprotected_bytes == nullptr ||
111 unprotected_bytes_size == nullptr) {
Craig Tillera82950e2015-09-22 12:33:20 -0700112 return TSI_INVALID_ARGUMENT;
113 }
Craig Tiller4782d922017-11-10 09:53:21 -0800114 if (self->vtable->unprotect == nullptr) return TSI_UNIMPLEMENTED;
Craig Tillera82950e2015-09-22 12:33:20 -0700115 return self->vtable->unprotect(self, protected_frames_bytes,
116 protected_frames_bytes_size, unprotected_bytes,
117 unprotected_bytes_size);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800118}
119
Craig Tillerbaa14a92017-11-03 09:09:36 -0700120void tsi_frame_protector_destroy(tsi_frame_protector* self) {
Craig Tiller4782d922017-11-10 09:53:21 -0800121 if (self == nullptr) return;
Craig Tillera82950e2015-09-22 12:33:20 -0700122 self->vtable->destroy(self);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800123}
124
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800125/* --- tsi_handshaker common implementation. ---
126
127 Calls specific implementation after state/input validation. */
128
Craig Tillerbaa14a92017-11-03 09:09:36 -0700129tsi_result tsi_handshaker_get_bytes_to_send_to_peer(tsi_handshaker* self,
130 unsigned char* bytes,
131 size_t* bytes_size) {
Craig Tiller4782d922017-11-10 09:53:21 -0800132 if (self == nullptr || self->vtable == nullptr || bytes == nullptr ||
133 bytes_size == nullptr) {
Julien Boeuf4c8e8182015-12-07 11:34:12 -0800134 return TSI_INVALID_ARGUMENT;
135 }
Craig Tillera82950e2015-09-22 12:33:20 -0700136 if (self->frame_protector_created) return TSI_FAILED_PRECONDITION;
Craig Tillerbe98d242017-11-10 15:26:57 -0800137 if (self->vtable->get_bytes_to_send_to_peer == nullptr)
138 return TSI_UNIMPLEMENTED;
Craig Tillera82950e2015-09-22 12:33:20 -0700139 return self->vtable->get_bytes_to_send_to_peer(self, bytes, bytes_size);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800140}
141
Craig Tillerbaa14a92017-11-03 09:09:36 -0700142tsi_result tsi_handshaker_process_bytes_from_peer(tsi_handshaker* self,
143 const unsigned char* bytes,
144 size_t* bytes_size) {
Craig Tiller4782d922017-11-10 09:53:21 -0800145 if (self == nullptr || self->vtable == nullptr || bytes == nullptr ||
146 bytes_size == nullptr) {
Julien Boeuf4c8e8182015-12-07 11:34:12 -0800147 return TSI_INVALID_ARGUMENT;
148 }
Craig Tillera82950e2015-09-22 12:33:20 -0700149 if (self->frame_protector_created) return TSI_FAILED_PRECONDITION;
Craig Tillerbe98d242017-11-10 15:26:57 -0800150 if (self->vtable->process_bytes_from_peer == nullptr)
151 return TSI_UNIMPLEMENTED;
Craig Tillera82950e2015-09-22 12:33:20 -0700152 return self->vtable->process_bytes_from_peer(self, bytes, bytes_size);
Craig Tiller45724b32015-09-22 10:42:19 -0700153}
154
Craig Tillerbaa14a92017-11-03 09:09:36 -0700155tsi_result tsi_handshaker_get_result(tsi_handshaker* self) {
Craig Tiller4782d922017-11-10 09:53:21 -0800156 if (self == nullptr || self->vtable == nullptr) return TSI_INVALID_ARGUMENT;
Craig Tillera82950e2015-09-22 12:33:20 -0700157 if (self->frame_protector_created) return TSI_FAILED_PRECONDITION;
Craig Tiller4782d922017-11-10 09:53:21 -0800158 if (self->vtable->get_result == nullptr) return TSI_UNIMPLEMENTED;
Craig Tillera82950e2015-09-22 12:33:20 -0700159 return self->vtable->get_result(self);
Craig Tiller45724b32015-09-22 10:42:19 -0700160}
161
Craig Tillerbaa14a92017-11-03 09:09:36 -0700162tsi_result tsi_handshaker_extract_peer(tsi_handshaker* self, tsi_peer* peer) {
Craig Tiller4782d922017-11-10 09:53:21 -0800163 if (self == nullptr || self->vtable == nullptr || peer == nullptr) {
Jiangtao Li0211cfb2017-08-07 11:24:07 -0700164 return TSI_INVALID_ARGUMENT;
165 }
Craig Tillera82950e2015-09-22 12:33:20 -0700166 memset(peer, 0, sizeof(tsi_peer));
167 if (self->frame_protector_created) return TSI_FAILED_PRECONDITION;
168 if (tsi_handshaker_get_result(self) != TSI_OK) {
Craig Tiller45724b32015-09-22 10:42:19 -0700169 return TSI_FAILED_PRECONDITION;
Craig Tillera82950e2015-09-22 12:33:20 -0700170 }
Craig Tiller4782d922017-11-10 09:53:21 -0800171 if (self->vtable->extract_peer == nullptr) return TSI_UNIMPLEMENTED;
Craig Tillera82950e2015-09-22 12:33:20 -0700172 return self->vtable->extract_peer(self, peer);
Craig Tiller45724b32015-09-22 10:42:19 -0700173}
174
Craig Tillera82950e2015-09-22 12:33:20 -0700175tsi_result tsi_handshaker_create_frame_protector(
Craig Tillerbaa14a92017-11-03 09:09:36 -0700176 tsi_handshaker* self, size_t* max_protected_frame_size,
177 tsi_frame_protector** protector) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800178 tsi_result result;
Craig Tiller4782d922017-11-10 09:53:21 -0800179 if (self == nullptr || self->vtable == nullptr || protector == nullptr) {
Jiangtao Li0211cfb2017-08-07 11:24:07 -0700180 return TSI_INVALID_ARGUMENT;
181 }
Craig Tillera82950e2015-09-22 12:33:20 -0700182 if (self->frame_protector_created) return TSI_FAILED_PRECONDITION;
Jiangtao Li0211cfb2017-08-07 11:24:07 -0700183 if (tsi_handshaker_get_result(self) != TSI_OK) return TSI_FAILED_PRECONDITION;
Craig Tiller4782d922017-11-10 09:53:21 -0800184 if (self->vtable->create_frame_protector == nullptr) return TSI_UNIMPLEMENTED;
Craig Tillera82950e2015-09-22 12:33:20 -0700185 result = self->vtable->create_frame_protector(self, max_protected_frame_size,
186 protector);
187 if (result == TSI_OK) {
jiangtaoli2016e69881d2017-04-10 14:29:43 -0700188 self->frame_protector_created = true;
Craig Tillera82950e2015-09-22 12:33:20 -0700189 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800190 return result;
191}
192
jiangtaoli201620b9f942017-04-07 12:50:33 -0700193tsi_result tsi_handshaker_next(
Craig Tillerbaa14a92017-11-03 09:09:36 -0700194 tsi_handshaker* self, const unsigned char* received_bytes,
195 size_t received_bytes_size, const unsigned char** bytes_to_send,
196 size_t* bytes_to_send_size, tsi_handshaker_result** handshaker_result,
197 tsi_handshaker_on_next_done_cb cb, void* user_data) {
Craig Tiller4782d922017-11-10 09:53:21 -0800198 if (self == nullptr || self->vtable == nullptr) return TSI_INVALID_ARGUMENT;
jiangtaoli201620b9f942017-04-07 12:50:33 -0700199 if (self->handshaker_result_created) return TSI_FAILED_PRECONDITION;
Craig Tiller4782d922017-11-10 09:53:21 -0800200 if (self->vtable->next == nullptr) return TSI_UNIMPLEMENTED;
jiangtaoli201620b9f942017-04-07 12:50:33 -0700201 return self->vtable->next(self, received_bytes, received_bytes_size,
202 bytes_to_send, bytes_to_send_size,
203 handshaker_result, cb, user_data);
204}
205
Craig Tillerbaa14a92017-11-03 09:09:36 -0700206void tsi_handshaker_destroy(tsi_handshaker* self) {
Craig Tiller4782d922017-11-10 09:53:21 -0800207 if (self == nullptr) return;
Craig Tillera82950e2015-09-22 12:33:20 -0700208 self->vtable->destroy(self);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800209}
210
jiangtaoli201620b9f942017-04-07 12:50:33 -0700211/* --- tsi_handshaker_result implementation. --- */
212
Craig Tillerbaa14a92017-11-03 09:09:36 -0700213tsi_result tsi_handshaker_result_extract_peer(const tsi_handshaker_result* self,
214 tsi_peer* peer) {
Craig Tiller4782d922017-11-10 09:53:21 -0800215 if (self == nullptr || self->vtable == nullptr || peer == nullptr) {
Jiangtao Li0211cfb2017-08-07 11:24:07 -0700216 return TSI_INVALID_ARGUMENT;
Jiangtao Lif5504a32017-08-07 10:48:46 -0700217 }
Jiangtao Li0211cfb2017-08-07 11:24:07 -0700218 memset(peer, 0, sizeof(tsi_peer));
Craig Tiller4782d922017-11-10 09:53:21 -0800219 if (self->vtable->extract_peer == nullptr) return TSI_UNIMPLEMENTED;
jiangtaoli201620b9f942017-04-07 12:50:33 -0700220 return self->vtable->extract_peer(self, peer);
221}
222
223tsi_result tsi_handshaker_result_create_frame_protector(
Craig Tillerbaa14a92017-11-03 09:09:36 -0700224 const tsi_handshaker_result* self, size_t* max_protected_frame_size,
225 tsi_frame_protector** protector) {
Craig Tiller4782d922017-11-10 09:53:21 -0800226 if (self == nullptr || self->vtable == nullptr || protector == nullptr) {
Jiangtao Li0211cfb2017-08-07 11:24:07 -0700227 return TSI_INVALID_ARGUMENT;
jiangtaoli2016c1955022017-04-11 09:36:19 -0700228 }
Craig Tiller4782d922017-11-10 09:53:21 -0800229 if (self->vtable->create_frame_protector == nullptr) return TSI_UNIMPLEMENTED;
jiangtaoli201620b9f942017-04-07 12:50:33 -0700230 return self->vtable->create_frame_protector(self, max_protected_frame_size,
231 protector);
232}
233
234tsi_result tsi_handshaker_result_get_unused_bytes(
Craig Tillerbaa14a92017-11-03 09:09:36 -0700235 const tsi_handshaker_result* self, const unsigned char** bytes,
236 size_t* bytes_size) {
Craig Tiller4782d922017-11-10 09:53:21 -0800237 if (self == nullptr || self->vtable == nullptr || bytes == nullptr ||
238 bytes_size == nullptr) {
jiangtaoli201620b9f942017-04-07 12:50:33 -0700239 return TSI_INVALID_ARGUMENT;
240 }
Craig Tiller4782d922017-11-10 09:53:21 -0800241 if (self->vtable->get_unused_bytes == nullptr) return TSI_UNIMPLEMENTED;
jiangtaoli201620b9f942017-04-07 12:50:33 -0700242 return self->vtable->get_unused_bytes(self, bytes, bytes_size);
243}
244
Craig Tillerbaa14a92017-11-03 09:09:36 -0700245void tsi_handshaker_result_destroy(tsi_handshaker_result* self) {
Craig Tiller4782d922017-11-10 09:53:21 -0800246 if (self == nullptr) return;
jiangtaoli201620b9f942017-04-07 12:50:33 -0700247 self->vtable->destroy(self);
248}
249
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800250/* --- tsi_peer implementation. --- */
251
Craig Tillera82950e2015-09-22 12:33:20 -0700252tsi_peer_property tsi_init_peer_property(void) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800253 tsi_peer_property property;
Craig Tillera82950e2015-09-22 12:33:20 -0700254 memset(&property, 0, sizeof(tsi_peer_property));
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800255 return property;
256}
257
Craig Tillerbaa14a92017-11-03 09:09:36 -0700258static void tsi_peer_destroy_list_property(tsi_peer_property* children,
Craig Tillera82950e2015-09-22 12:33:20 -0700259 size_t child_count) {
Julien Boeufb222b4d2015-01-15 17:01:39 -0800260 size_t i;
Craig Tillera82950e2015-09-22 12:33:20 -0700261 for (i = 0; i < child_count; i++) {
262 tsi_peer_property_destruct(&children[i]);
263 }
Nicolas "Pixel" Nobleb29d8cf2016-04-08 01:38:29 +0200264 gpr_free(children);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800265}
266
Craig Tillerbaa14a92017-11-03 09:09:36 -0700267void tsi_peer_property_destruct(tsi_peer_property* property) {
Craig Tiller4782d922017-11-10 09:53:21 -0800268 if (property->name != nullptr) {
Nicolas "Pixel" Nobleb29d8cf2016-04-08 01:38:29 +0200269 gpr_free(property->name);
Craig Tillera82950e2015-09-22 12:33:20 -0700270 }
Craig Tiller4782d922017-11-10 09:53:21 -0800271 if (property->value.data != nullptr) {
Nicolas "Pixel" Nobleb29d8cf2016-04-08 01:38:29 +0200272 gpr_free(property->value.data);
Craig Tillera82950e2015-09-22 12:33:20 -0700273 }
274 *property = tsi_init_peer_property(); /* Reset everything to 0. */
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800275}
276
Craig Tillerbaa14a92017-11-03 09:09:36 -0700277void tsi_peer_destruct(tsi_peer* self) {
Craig Tiller4782d922017-11-10 09:53:21 -0800278 if (self == nullptr) return;
279 if (self->properties != nullptr) {
Craig Tillera82950e2015-09-22 12:33:20 -0700280 tsi_peer_destroy_list_property(self->properties, self->property_count);
Craig Tiller4782d922017-11-10 09:53:21 -0800281 self->properties = nullptr;
Craig Tillera82950e2015-09-22 12:33:20 -0700282 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800283 self->property_count = 0;
284}
285
Craig Tillera82950e2015-09-22 12:33:20 -0700286tsi_result tsi_construct_allocated_string_peer_property(
Craig Tillerbaa14a92017-11-03 09:09:36 -0700287 const char* name, size_t value_length, tsi_peer_property* property) {
Craig Tillera82950e2015-09-22 12:33:20 -0700288 *property = tsi_init_peer_property();
Craig Tiller4782d922017-11-10 09:53:21 -0800289 if (name != nullptr) property->name = gpr_strdup(name);
Craig Tillera82950e2015-09-22 12:33:20 -0700290 if (value_length > 0) {
Craig Tillerbaa14a92017-11-03 09:09:36 -0700291 property->value.data = (char*)gpr_zalloc(value_length);
Craig Tillera82950e2015-09-22 12:33:20 -0700292 property->value.length = value_length;
293 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800294 return TSI_OK;
295}
296
Craig Tillera82950e2015-09-22 12:33:20 -0700297tsi_result tsi_construct_string_peer_property_from_cstring(
Craig Tillerbaa14a92017-11-03 09:09:36 -0700298 const char* name, const char* value, tsi_peer_property* property) {
Craig Tillera82950e2015-09-22 12:33:20 -0700299 return tsi_construct_string_peer_property(name, value, strlen(value),
300 property);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800301}
302
Craig Tillerbaa14a92017-11-03 09:09:36 -0700303tsi_result tsi_construct_string_peer_property(const char* name,
304 const char* value,
Craig Tillera82950e2015-09-22 12:33:20 -0700305 size_t value_length,
Craig Tillerbaa14a92017-11-03 09:09:36 -0700306 tsi_peer_property* property) {
Craig Tillera82950e2015-09-22 12:33:20 -0700307 tsi_result result = tsi_construct_allocated_string_peer_property(
308 name, value_length, property);
309 if (result != TSI_OK) return result;
310 if (value_length > 0) {
311 memcpy(property->value.data, value, value_length);
312 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800313 return TSI_OK;
314}
315
Craig Tillerbaa14a92017-11-03 09:09:36 -0700316tsi_result tsi_construct_peer(size_t property_count, tsi_peer* peer) {
Craig Tillera82950e2015-09-22 12:33:20 -0700317 memset(peer, 0, sizeof(tsi_peer));
318 if (property_count > 0) {
Craig Tillerbaa14a92017-11-03 09:09:36 -0700319 peer->properties = (tsi_peer_property*)gpr_zalloc(
Yash Tibrewalacd46e52017-09-20 11:28:25 -0700320 property_count * sizeof(tsi_peer_property));
Craig Tillera82950e2015-09-22 12:33:20 -0700321 peer->property_count = property_count;
322 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800323 return TSI_OK;
Craig Tiller190d3602015-02-18 09:23:38 -0800324}