blob: 4925d19f96e2d6f0c64e4d1916be424371c68adb [file] [log] [blame]
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001/*
2 *
Craig Tiller6169d5f2016-03-31 07:46:18 -07003 * Copyright 2015, Google Inc.
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08004 * 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
Craig Tillerb29f1fe2017-03-28 15:49:23 -070034#include "src/core/tsi/fake_transport_security.h"
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080035
36#include <stdlib.h>
37#include <string.h>
38
Nicolas "Pixel" Nobleb29d8cf2016-04-08 01:38:29 +020039#include <grpc/support/alloc.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080040#include <grpc/support/log.h>
Craig Tillerbe5c6e52015-01-16 07:57:58 -080041#include <grpc/support/port_platform.h>
Nicolas "Pixel" Noble213ed912015-01-30 02:11:35 +010042#include <grpc/support/useful.h>
Craig Tillerb29f1fe2017-03-28 15:49:23 -070043#include "src/core/tsi/transport_security.h"
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080044
45/* --- Constants. ---*/
46#define TSI_FAKE_FRAME_HEADER_SIZE 4
47#define TSI_FAKE_FRAME_INITIAL_ALLOCATED_SIZE 64
48#define TSI_FAKE_DEFAULT_FRAME_SIZE 16384
49
50/* --- Structure definitions. ---*/
51
52/* a frame is encoded like this:
53 | size | data |
54 where the size field value is the size of the size field plus the size of
55 the data encoded in little endian on 4 bytes. */
Craig Tillera82950e2015-09-22 12:33:20 -070056typedef struct {
Craig Tiller45724b32015-09-22 10:42:19 -070057 unsigned char *data;
Craig Tillerbe5c6e52015-01-16 07:57:58 -080058 size_t size;
59 size_t allocated_size;
60 size_t offset;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080061 int needs_draining;
62} tsi_fake_frame;
63
Craig Tillera82950e2015-09-22 12:33:20 -070064typedef enum {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080065 TSI_FAKE_CLIENT_INIT = 0,
66 TSI_FAKE_SERVER_INIT = 1,
67 TSI_FAKE_CLIENT_FINISHED = 2,
68 TSI_FAKE_SERVER_FINISHED = 3,
69 TSI_FAKE_HANDSHAKE_MESSAGE_MAX = 4
70} tsi_fake_handshake_message;
71
Craig Tillera82950e2015-09-22 12:33:20 -070072typedef struct {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080073 tsi_handshaker base;
74 int is_client;
75 tsi_fake_handshake_message next_message_to_send;
76 int needs_incoming_message;
77 tsi_fake_frame incoming;
78 tsi_fake_frame outgoing;
79 tsi_result result;
80} tsi_fake_handshaker;
81
Craig Tillera82950e2015-09-22 12:33:20 -070082typedef struct {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080083 tsi_frame_protector base;
84 tsi_fake_frame protect_frame;
85 tsi_fake_frame unprotect_frame;
Craig Tillerbe5c6e52015-01-16 07:57:58 -080086 size_t max_frame_size;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080087} tsi_fake_frame_protector;
88
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080089/* --- Utils. ---*/
90
Craig Tiller45724b32015-09-22 10:42:19 -070091static const char *tsi_fake_handshake_message_strings[] = {
Craig Tillera82950e2015-09-22 12:33:20 -070092 "CLIENT_INIT", "SERVER_INIT", "CLIENT_FINISHED", "SERVER_FINISHED"};
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080093
Craig Tillera82950e2015-09-22 12:33:20 -070094static const char *tsi_fake_handshake_message_to_string(int msg) {
95 if (msg < 0 || msg >= TSI_FAKE_HANDSHAKE_MESSAGE_MAX) {
96 gpr_log(GPR_ERROR, "Invalid message %d", msg);
97 return "UNKNOWN";
98 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080099 return tsi_fake_handshake_message_strings[msg];
100}
101
Craig Tillera82950e2015-09-22 12:33:20 -0700102static tsi_result tsi_fake_handshake_message_from_string(
103 const char *msg_string, tsi_fake_handshake_message *msg) {
Craig Tillerf96dfc32015-09-10 14:43:18 -0700104 tsi_fake_handshake_message i;
Craig Tillera82950e2015-09-22 12:33:20 -0700105 for (i = 0; i < TSI_FAKE_HANDSHAKE_MESSAGE_MAX; i++) {
106 if (strncmp(msg_string, tsi_fake_handshake_message_strings[i],
107 strlen(tsi_fake_handshake_message_strings[i])) == 0) {
108 *msg = i;
109 return TSI_OK;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800110 }
Craig Tillera82950e2015-09-22 12:33:20 -0700111 }
112 gpr_log(GPR_ERROR, "Invalid handshake message.");
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800113 return TSI_DATA_CORRUPTED;
114}
115
Craig Tiller7536af02015-12-22 13:49:30 -0800116static uint32_t load32_little_endian(const unsigned char *buf) {
117 return ((uint32_t)(buf[0]) | (uint32_t)(buf[1] << 8) |
118 (uint32_t)(buf[2] << 16) | (uint32_t)(buf[3] << 24));
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800119}
120
Craig Tiller7536af02015-12-22 13:49:30 -0800121static void store32_little_endian(uint32_t value, unsigned char *buf) {
David Garcia Quintasd76cdac2015-10-03 15:57:09 -0700122 buf[3] = (unsigned char)((value >> 24) & 0xFF);
123 buf[2] = (unsigned char)((value >> 16) & 0xFF);
124 buf[1] = (unsigned char)((value >> 8) & 0xFF);
Craig Tiller1f41b6b2015-10-09 15:07:02 -0700125 buf[0] = (unsigned char)((value)&0xFF);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800126}
127
Craig Tillera82950e2015-09-22 12:33:20 -0700128static void tsi_fake_frame_reset(tsi_fake_frame *frame, int needs_draining) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800129 frame->offset = 0;
130 frame->needs_draining = needs_draining;
Craig Tillera82950e2015-09-22 12:33:20 -0700131 if (!needs_draining) frame->size = 0;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800132}
133
134/* Returns 1 if successful, 0 otherwise. */
Craig Tillera82950e2015-09-22 12:33:20 -0700135static int tsi_fake_frame_ensure_size(tsi_fake_frame *frame) {
136 if (frame->data == NULL) {
137 frame->allocated_size = frame->size;
Nicolas "Pixel" Noble7c9a1542016-03-26 01:33:34 +0100138 frame->data = gpr_malloc(frame->allocated_size);
Craig Tillera82950e2015-09-22 12:33:20 -0700139 if (frame->data == NULL) return 0;
140 } else if (frame->size > frame->allocated_size) {
Nicolas "Pixel" Nobleb29d8cf2016-04-08 01:38:29 +0200141 unsigned char *new_data = gpr_realloc(frame->data, frame->size);
Craig Tillera82950e2015-09-22 12:33:20 -0700142 if (new_data == NULL) {
Nicolas "Pixel" Noble7c9a1542016-03-26 01:33:34 +0100143 gpr_free(frame->data);
Craig Tillera82950e2015-09-22 12:33:20 -0700144 frame->data = NULL;
145 return 0;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800146 }
Craig Tillera82950e2015-09-22 12:33:20 -0700147 frame->data = new_data;
148 frame->allocated_size = frame->size;
149 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800150 return 1;
151}
152
153/* This method should not be called if frame->needs_framing is not 0. */
Craig Tillera82950e2015-09-22 12:33:20 -0700154static tsi_result fill_frame_from_bytes(const unsigned char *incoming_bytes,
155 size_t *incoming_bytes_size,
156 tsi_fake_frame *frame) {
Craig Tillerbe5c6e52015-01-16 07:57:58 -0800157 size_t available_size = *incoming_bytes_size;
158 size_t to_read_size = 0;
Craig Tiller45724b32015-09-22 10:42:19 -0700159 const unsigned char *bytes_cursor = incoming_bytes;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800160
Craig Tillera82950e2015-09-22 12:33:20 -0700161 if (frame->needs_draining) return TSI_INTERNAL_ERROR;
162 if (frame->data == NULL) {
163 frame->allocated_size = TSI_FAKE_FRAME_INITIAL_ALLOCATED_SIZE;
Nicolas "Pixel" Noble7c9a1542016-03-26 01:33:34 +0100164 frame->data = gpr_malloc(frame->allocated_size);
Craig Tillera82950e2015-09-22 12:33:20 -0700165 if (frame->data == NULL) return TSI_OUT_OF_RESOURCES;
166 }
Craig Tiller45724b32015-09-22 10:42:19 -0700167
Craig Tillera82950e2015-09-22 12:33:20 -0700168 if (frame->offset < TSI_FAKE_FRAME_HEADER_SIZE) {
169 to_read_size = TSI_FAKE_FRAME_HEADER_SIZE - frame->offset;
170 if (to_read_size > available_size) {
171 /* Just fill what we can and exit. */
172 memcpy(frame->data + frame->offset, bytes_cursor, available_size);
Craig Tiller45724b32015-09-22 10:42:19 -0700173 bytes_cursor += available_size;
Craig Tillera82950e2015-09-22 12:33:20 -0700174 frame->offset += available_size;
175 *incoming_bytes_size = (size_t)(bytes_cursor - incoming_bytes);
Craig Tiller45724b32015-09-22 10:42:19 -0700176 return TSI_INCOMPLETE_DATA;
177 }
Craig Tillera82950e2015-09-22 12:33:20 -0700178 memcpy(frame->data + frame->offset, bytes_cursor, to_read_size);
179 bytes_cursor += to_read_size;
180 frame->offset += to_read_size;
181 available_size -= to_read_size;
182 frame->size = load32_little_endian(frame->data);
183 if (!tsi_fake_frame_ensure_size(frame)) return TSI_OUT_OF_RESOURCES;
184 }
185
186 to_read_size = frame->size - frame->offset;
187 if (to_read_size > available_size) {
188 memcpy(frame->data + frame->offset, bytes_cursor, available_size);
189 frame->offset += available_size;
190 bytes_cursor += available_size;
191 *incoming_bytes_size = (size_t)(bytes_cursor - incoming_bytes);
192 return TSI_INCOMPLETE_DATA;
193 }
194 memcpy(frame->data + frame->offset, bytes_cursor, to_read_size);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800195 bytes_cursor += to_read_size;
Craig Tillera82950e2015-09-22 12:33:20 -0700196 *incoming_bytes_size = (size_t)(bytes_cursor - incoming_bytes);
197 tsi_fake_frame_reset(frame, 1 /* needs_draining */);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800198 return TSI_OK;
199}
200
201/* This method should not be called if frame->needs_framing is 0. */
Craig Tillera82950e2015-09-22 12:33:20 -0700202static tsi_result drain_frame_to_bytes(unsigned char *outgoing_bytes,
203 size_t *outgoing_bytes_size,
204 tsi_fake_frame *frame) {
Craig Tillerbe5c6e52015-01-16 07:57:58 -0800205 size_t to_write_size = frame->size - frame->offset;
Craig Tillera82950e2015-09-22 12:33:20 -0700206 if (!frame->needs_draining) return TSI_INTERNAL_ERROR;
207 if (*outgoing_bytes_size < to_write_size) {
208 memcpy(outgoing_bytes, frame->data + frame->offset, *outgoing_bytes_size);
209 frame->offset += *outgoing_bytes_size;
210 return TSI_INCOMPLETE_DATA;
211 }
212 memcpy(outgoing_bytes, frame->data + frame->offset, to_write_size);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800213 *outgoing_bytes_size = to_write_size;
Craig Tillera82950e2015-09-22 12:33:20 -0700214 tsi_fake_frame_reset(frame, 0 /* needs_draining */);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800215 return TSI_OK;
216}
217
Craig Tillera82950e2015-09-22 12:33:20 -0700218static tsi_result bytes_to_frame(unsigned char *bytes, size_t bytes_size,
219 tsi_fake_frame *frame) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800220 frame->offset = 0;
221 frame->size = bytes_size + TSI_FAKE_FRAME_HEADER_SIZE;
Craig Tillera82950e2015-09-22 12:33:20 -0700222 if (!tsi_fake_frame_ensure_size(frame)) return TSI_OUT_OF_RESOURCES;
Craig Tiller7536af02015-12-22 13:49:30 -0800223 store32_little_endian((uint32_t)frame->size, frame->data);
Craig Tillera82950e2015-09-22 12:33:20 -0700224 memcpy(frame->data + TSI_FAKE_FRAME_HEADER_SIZE, bytes, bytes_size);
225 tsi_fake_frame_reset(frame, 1 /* needs draining */);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800226 return TSI_OK;
227}
228
Craig Tillera82950e2015-09-22 12:33:20 -0700229static void tsi_fake_frame_destruct(tsi_fake_frame *frame) {
Nicolas "Pixel" Noble7c9a1542016-03-26 01:33:34 +0100230 if (frame->data != NULL) gpr_free(frame->data);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800231}
232
233/* --- tsi_frame_protector methods implementation. ---*/
234
Craig Tillera82950e2015-09-22 12:33:20 -0700235static tsi_result fake_protector_protect(tsi_frame_protector *self,
236 const unsigned char *unprotected_bytes,
237 size_t *unprotected_bytes_size,
238 unsigned char *protected_output_frames,
239 size_t *protected_output_frames_size) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800240 tsi_result result = TSI_OK;
Craig Tillera82950e2015-09-22 12:33:20 -0700241 tsi_fake_frame_protector *impl = (tsi_fake_frame_protector *)self;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800242 unsigned char frame_header[TSI_FAKE_FRAME_HEADER_SIZE];
Craig Tiller45724b32015-09-22 10:42:19 -0700243 tsi_fake_frame *frame = &impl->protect_frame;
Craig Tillerbe5c6e52015-01-16 07:57:58 -0800244 size_t saved_output_size = *protected_output_frames_size;
245 size_t drained_size = 0;
Craig Tiller45724b32015-09-22 10:42:19 -0700246 size_t *num_bytes_written = protected_output_frames_size;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800247 *num_bytes_written = 0;
248
249 /* Try to drain first. */
Craig Tillera82950e2015-09-22 12:33:20 -0700250 if (frame->needs_draining) {
251 drained_size = saved_output_size - *num_bytes_written;
252 result =
253 drain_frame_to_bytes(protected_output_frames, &drained_size, frame);
254 *num_bytes_written += drained_size;
255 protected_output_frames += drained_size;
256 if (result != TSI_OK) {
257 if (result == TSI_INCOMPLETE_DATA) {
258 *unprotected_bytes_size = 0;
259 result = TSI_OK;
260 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800261 return result;
262 }
Craig Tillera82950e2015-09-22 12:33:20 -0700263 }
264
265 /* Now process the unprotected_bytes. */
266 if (frame->needs_draining) return TSI_INTERNAL_ERROR;
267 if (frame->size == 0) {
268 /* New frame, create a header. */
269 size_t written_in_frame_size = 0;
Craig Tiller7536af02015-12-22 13:49:30 -0800270 store32_little_endian((uint32_t)impl->max_frame_size, frame_header);
Craig Tillera82950e2015-09-22 12:33:20 -0700271 written_in_frame_size = TSI_FAKE_FRAME_HEADER_SIZE;
272 result = fill_frame_from_bytes(frame_header, &written_in_frame_size, frame);
273 if (result != TSI_INCOMPLETE_DATA) {
274 gpr_log(GPR_ERROR, "fill_frame_from_bytes returned %s",
275 tsi_result_to_string(result));
276 return result;
277 }
278 }
279 result =
280 fill_frame_from_bytes(unprotected_bytes, unprotected_bytes_size, frame);
281 if (result != TSI_OK) {
282 if (result == TSI_INCOMPLETE_DATA) result = TSI_OK;
283 return result;
284 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800285
286 /* Try to drain again. */
Craig Tillera82950e2015-09-22 12:33:20 -0700287 if (!frame->needs_draining) return TSI_INTERNAL_ERROR;
288 if (frame->offset != 0) return TSI_INTERNAL_ERROR;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800289 drained_size = saved_output_size - *num_bytes_written;
Craig Tillera82950e2015-09-22 12:33:20 -0700290 result = drain_frame_to_bytes(protected_output_frames, &drained_size, frame);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800291 *num_bytes_written += drained_size;
Craig Tillera82950e2015-09-22 12:33:20 -0700292 if (result == TSI_INCOMPLETE_DATA) result = TSI_OK;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800293 return result;
294}
295
Craig Tillera82950e2015-09-22 12:33:20 -0700296static tsi_result fake_protector_protect_flush(
297 tsi_frame_protector *self, unsigned char *protected_output_frames,
298 size_t *protected_output_frames_size, size_t *still_pending_size) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800299 tsi_result result = TSI_OK;
Craig Tillera82950e2015-09-22 12:33:20 -0700300 tsi_fake_frame_protector *impl = (tsi_fake_frame_protector *)self;
Craig Tiller45724b32015-09-22 10:42:19 -0700301 tsi_fake_frame *frame = &impl->protect_frame;
Craig Tillera82950e2015-09-22 12:33:20 -0700302 if (!frame->needs_draining) {
303 /* Create a short frame. */
304 frame->size = frame->offset;
305 frame->offset = 0;
306 frame->needs_draining = 1;
Craig Tiller7536af02015-12-22 13:49:30 -0800307 store32_little_endian((uint32_t)frame->size,
Craig Tillera82950e2015-09-22 12:33:20 -0700308 frame->data); /* Overwrite header. */
309 }
310 result = drain_frame_to_bytes(protected_output_frames,
311 protected_output_frames_size, frame);
312 if (result == TSI_INCOMPLETE_DATA) result = TSI_OK;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800313 *still_pending_size = frame->size - frame->offset;
314 return result;
315}
316
Craig Tillera82950e2015-09-22 12:33:20 -0700317static tsi_result fake_protector_unprotect(
318 tsi_frame_protector *self, const unsigned char *protected_frames_bytes,
319 size_t *protected_frames_bytes_size, unsigned char *unprotected_bytes,
320 size_t *unprotected_bytes_size) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800321 tsi_result result = TSI_OK;
Craig Tillera82950e2015-09-22 12:33:20 -0700322 tsi_fake_frame_protector *impl = (tsi_fake_frame_protector *)self;
Craig Tiller45724b32015-09-22 10:42:19 -0700323 tsi_fake_frame *frame = &impl->unprotect_frame;
Craig Tillerbe5c6e52015-01-16 07:57:58 -0800324 size_t saved_output_size = *unprotected_bytes_size;
325 size_t drained_size = 0;
Craig Tiller45724b32015-09-22 10:42:19 -0700326 size_t *num_bytes_written = unprotected_bytes_size;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800327 *num_bytes_written = 0;
328
329 /* Try to drain first. */
Craig Tillera82950e2015-09-22 12:33:20 -0700330 if (frame->needs_draining) {
331 /* Go past the header if needed. */
332 if (frame->offset == 0) frame->offset = TSI_FAKE_FRAME_HEADER_SIZE;
333 drained_size = saved_output_size - *num_bytes_written;
334 result = drain_frame_to_bytes(unprotected_bytes, &drained_size, frame);
335 unprotected_bytes += drained_size;
336 *num_bytes_written += drained_size;
337 if (result != TSI_OK) {
338 if (result == TSI_INCOMPLETE_DATA) {
339 *protected_frames_bytes_size = 0;
340 result = TSI_OK;
341 }
Craig Tiller45724b32015-09-22 10:42:19 -0700342 return result;
343 }
Craig Tillera82950e2015-09-22 12:33:20 -0700344 }
345
346 /* Now process the protected_bytes. */
347 if (frame->needs_draining) return TSI_INTERNAL_ERROR;
348 result = fill_frame_from_bytes(protected_frames_bytes,
349 protected_frames_bytes_size, frame);
350 if (result != TSI_OK) {
351 if (result == TSI_INCOMPLETE_DATA) result = TSI_OK;
352 return result;
353 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800354
355 /* Try to drain again. */
Craig Tillera82950e2015-09-22 12:33:20 -0700356 if (!frame->needs_draining) return TSI_INTERNAL_ERROR;
357 if (frame->offset != 0) return TSI_INTERNAL_ERROR;
358 frame->offset = TSI_FAKE_FRAME_HEADER_SIZE; /* Go past the header. */
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800359 drained_size = saved_output_size - *num_bytes_written;
Craig Tillera82950e2015-09-22 12:33:20 -0700360 result = drain_frame_to_bytes(unprotected_bytes, &drained_size, frame);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800361 *num_bytes_written += drained_size;
Craig Tillera82950e2015-09-22 12:33:20 -0700362 if (result == TSI_INCOMPLETE_DATA) result = TSI_OK;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800363 return result;
364}
365
Craig Tillera82950e2015-09-22 12:33:20 -0700366static void fake_protector_destroy(tsi_frame_protector *self) {
367 tsi_fake_frame_protector *impl = (tsi_fake_frame_protector *)self;
368 tsi_fake_frame_destruct(&impl->protect_frame);
369 tsi_fake_frame_destruct(&impl->unprotect_frame);
Nicolas "Pixel" Noble7c9a1542016-03-26 01:33:34 +0100370 gpr_free(self);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800371}
372
373static const tsi_frame_protector_vtable frame_protector_vtable = {
Craig Tillera82950e2015-09-22 12:33:20 -0700374 fake_protector_protect, fake_protector_protect_flush,
375 fake_protector_unprotect, fake_protector_destroy,
Craig Tillerd6c98df2015-08-18 09:33:44 -0700376};
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800377
378/* --- tsi_handshaker methods implementation. ---*/
379
Craig Tillera82950e2015-09-22 12:33:20 -0700380static tsi_result fake_handshaker_get_bytes_to_send_to_peer(
381 tsi_handshaker *self, unsigned char *bytes, size_t *bytes_size) {
382 tsi_fake_handshaker *impl = (tsi_fake_handshaker *)self;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800383 tsi_result result = TSI_OK;
Craig Tillera82950e2015-09-22 12:33:20 -0700384 if (impl->needs_incoming_message || impl->result == TSI_OK) {
385 *bytes_size = 0;
386 return TSI_OK;
387 }
388 if (!impl->outgoing.needs_draining) {
389 tsi_fake_handshake_message next_message_to_send =
390 impl->next_message_to_send + 2;
391 const char *msg_string =
392 tsi_fake_handshake_message_to_string(impl->next_message_to_send);
393 result = bytes_to_frame((unsigned char *)msg_string, strlen(msg_string),
394 &impl->outgoing);
395 if (result != TSI_OK) return result;
396 if (next_message_to_send > TSI_FAKE_HANDSHAKE_MESSAGE_MAX) {
397 next_message_to_send = TSI_FAKE_HANDSHAKE_MESSAGE_MAX;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800398 }
Craig Tiller84f75d42017-05-03 13:06:35 -0700399 if (GRPC_TRACER_ON(tsi_tracing_enabled)) {
Craig Tillera82950e2015-09-22 12:33:20 -0700400 gpr_log(GPR_INFO, "%s prepared %s.",
401 impl->is_client ? "Client" : "Server",
402 tsi_fake_handshake_message_to_string(impl->next_message_to_send));
Julien Boeuf980f6002015-02-26 16:41:41 -0800403 }
Craig Tillera82950e2015-09-22 12:33:20 -0700404 impl->next_message_to_send = next_message_to_send;
405 }
406 result = drain_frame_to_bytes(bytes, bytes_size, &impl->outgoing);
407 if (result != TSI_OK) return result;
408 if (!impl->is_client &&
409 impl->next_message_to_send == TSI_FAKE_HANDSHAKE_MESSAGE_MAX) {
410 /* We're done. */
Craig Tiller84f75d42017-05-03 13:06:35 -0700411 if (GRPC_TRACER_ON(tsi_tracing_enabled)) {
Craig Tillera82950e2015-09-22 12:33:20 -0700412 gpr_log(GPR_INFO, "Server is done.");
Julien Boeuf980f6002015-02-26 16:41:41 -0800413 }
Craig Tillera82950e2015-09-22 12:33:20 -0700414 impl->result = TSI_OK;
415 } else {
416 impl->needs_incoming_message = 1;
417 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800418 return TSI_OK;
419}
420
Craig Tillera82950e2015-09-22 12:33:20 -0700421static tsi_result fake_handshaker_process_bytes_from_peer(
422 tsi_handshaker *self, const unsigned char *bytes, size_t *bytes_size) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800423 tsi_result result = TSI_OK;
Craig Tillera82950e2015-09-22 12:33:20 -0700424 tsi_fake_handshaker *impl = (tsi_fake_handshaker *)self;
Nicolas "Pixel" Noble213ed912015-01-30 02:11:35 +0100425 tsi_fake_handshake_message expected_msg = impl->next_message_to_send - 1;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800426 tsi_fake_handshake_message received_msg;
427
Craig Tillera82950e2015-09-22 12:33:20 -0700428 if (!impl->needs_incoming_message || impl->result == TSI_OK) {
429 *bytes_size = 0;
430 return TSI_OK;
431 }
432 result = fill_frame_from_bytes(bytes, bytes_size, &impl->incoming);
433 if (result != TSI_OK) return result;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800434
435 /* We now have a complete frame. */
Craig Tillera82950e2015-09-22 12:33:20 -0700436 result = tsi_fake_handshake_message_from_string(
437 (const char *)impl->incoming.data + TSI_FAKE_FRAME_HEADER_SIZE,
438 &received_msg);
439 if (result != TSI_OK) {
440 impl->result = result;
441 return result;
442 }
443 if (received_msg != expected_msg) {
444 gpr_log(GPR_ERROR, "Invalid received message (%s instead of %s)",
445 tsi_fake_handshake_message_to_string(received_msg),
446 tsi_fake_handshake_message_to_string(expected_msg));
447 }
Craig Tiller84f75d42017-05-03 13:06:35 -0700448 if (GRPC_TRACER_ON(tsi_tracing_enabled)) {
Craig Tillera82950e2015-09-22 12:33:20 -0700449 gpr_log(GPR_INFO, "%s received %s.", impl->is_client ? "Client" : "Server",
450 tsi_fake_handshake_message_to_string(received_msg));
451 }
452 tsi_fake_frame_reset(&impl->incoming, 0 /* needs_draining */);
Craig Tiller45724b32015-09-22 10:42:19 -0700453 impl->needs_incoming_message = 0;
Craig Tillera82950e2015-09-22 12:33:20 -0700454 if (impl->next_message_to_send == TSI_FAKE_HANDSHAKE_MESSAGE_MAX) {
455 /* We're done. */
Craig Tiller84f75d42017-05-03 13:06:35 -0700456 if (GRPC_TRACER_ON(tsi_tracing_enabled)) {
Craig Tillera82950e2015-09-22 12:33:20 -0700457 gpr_log(GPR_INFO, "%s is done.", impl->is_client ? "Client" : "Server");
Craig Tiller45724b32015-09-22 10:42:19 -0700458 }
Craig Tillera82950e2015-09-22 12:33:20 -0700459 impl->result = TSI_OK;
460 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800461 return TSI_OK;
462}
463
Craig Tillera82950e2015-09-22 12:33:20 -0700464static tsi_result fake_handshaker_get_result(tsi_handshaker *self) {
465 tsi_fake_handshaker *impl = (tsi_fake_handshaker *)self;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800466 return impl->result;
467}
468
Craig Tillera82950e2015-09-22 12:33:20 -0700469static tsi_result fake_handshaker_extract_peer(tsi_handshaker *self,
470 tsi_peer *peer) {
471 tsi_result result = tsi_construct_peer(1, peer);
472 if (result != TSI_OK) return result;
473 result = tsi_construct_string_peer_property_from_cstring(
474 TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_FAKE_CERTIFICATE_TYPE,
475 &peer->properties[0]);
476 if (result != TSI_OK) tsi_peer_destruct(peer);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800477 return result;
478}
479
Craig Tillera82950e2015-09-22 12:33:20 -0700480static tsi_result fake_handshaker_create_frame_protector(
481 tsi_handshaker *self, size_t *max_protected_frame_size,
482 tsi_frame_protector **protector) {
483 *protector = tsi_create_fake_protector(max_protected_frame_size);
484 if (*protector == NULL) return TSI_OUT_OF_RESOURCES;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800485 return TSI_OK;
486}
487
Craig Tillera82950e2015-09-22 12:33:20 -0700488static void fake_handshaker_destroy(tsi_handshaker *self) {
489 tsi_fake_handshaker *impl = (tsi_fake_handshaker *)self;
490 tsi_fake_frame_destruct(&impl->incoming);
491 tsi_fake_frame_destruct(&impl->outgoing);
Nicolas "Pixel" Noble7c9a1542016-03-26 01:33:34 +0100492 gpr_free(self);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800493}
494
495static const tsi_handshaker_vtable handshaker_vtable = {
Craig Tillera82950e2015-09-22 12:33:20 -0700496 fake_handshaker_get_bytes_to_send_to_peer,
Craig Tillerf40df232016-03-25 13:38:14 -0700497 fake_handshaker_process_bytes_from_peer,
498 fake_handshaker_get_result,
499 fake_handshaker_extract_peer,
500 fake_handshaker_create_frame_protector,
Craig Tillera82950e2015-09-22 12:33:20 -0700501 fake_handshaker_destroy,
jiangtaoli201620b9f942017-04-07 12:50:33 -0700502 NULL,
Craig Tillerd6c98df2015-08-18 09:33:44 -0700503};
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800504
Craig Tillera82950e2015-09-22 12:33:20 -0700505tsi_handshaker *tsi_create_fake_handshaker(int is_client) {
Craig Tiller6f417882017-02-16 14:09:39 -0800506 tsi_fake_handshaker *impl = gpr_zalloc(sizeof(*impl));
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800507 impl->base.vtable = &handshaker_vtable;
508 impl->is_client = is_client;
509 impl->result = TSI_HANDSHAKE_IN_PROGRESS;
Craig Tillera82950e2015-09-22 12:33:20 -0700510 if (is_client) {
511 impl->needs_incoming_message = 0;
512 impl->next_message_to_send = TSI_FAKE_CLIENT_INIT;
513 } else {
514 impl->needs_incoming_message = 1;
515 impl->next_message_to_send = TSI_FAKE_SERVER_INIT;
516 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800517 return &impl->base;
518}
519
Craig Tillera82950e2015-09-22 12:33:20 -0700520tsi_frame_protector *tsi_create_fake_protector(
521 size_t *max_protected_frame_size) {
Craig Tiller6f417882017-02-16 14:09:39 -0800522 tsi_fake_frame_protector *impl = gpr_zalloc(sizeof(*impl));
Craig Tillera82950e2015-09-22 12:33:20 -0700523 impl->max_frame_size = (max_protected_frame_size == NULL)
524 ? TSI_FAKE_DEFAULT_FRAME_SIZE
525 : *max_protected_frame_size;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800526 impl->base.vtable = &frame_protector_vtable;
527 return &impl->base;
Craig Tiller190d3602015-02-18 09:23:38 -0800528}