fake_transport_security.cc
Go to the documentation of this file.
1 /*
2  *
3  * Copyright 2015 gRPC authors.
4  *
5  * 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
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * 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.
16  *
17  */
18 
20 
22 
23 #include <stdlib.h>
24 #include <string.h>
25 
26 #include <grpc/support/alloc.h>
27 #include <grpc/support/log.h>
28 
33 
34 /* --- Constants. ---*/
35 #define TSI_FAKE_FRAME_HEADER_SIZE 4
36 #define TSI_FAKE_FRAME_INITIAL_ALLOCATED_SIZE 64
37 #define TSI_FAKE_DEFAULT_FRAME_SIZE 16384
38 #define TSI_FAKE_HANDSHAKER_OUTGOING_BUFFER_INITIAL_SIZE 256
39 
40 /* --- Structure definitions. ---*/
41 
42 /* a frame is encoded like this:
43  | size | data |
44  where the size field value is the size of the size field plus the size of
45  the data encoded in little endian on 4 bytes. */
47  unsigned char* data;
48  size_t size;
50  size_t offset;
52 };
53 typedef enum {
60 
63  int is_client;
68  unsigned char* outgoing_bytes_buffer;
71 };
77 };
84 };
85 /* --- Utils. ---*/
86 
87 static const char* tsi_fake_handshake_message_strings[] = {
88  "CLIENT_INIT", "SERVER_INIT", "CLIENT_FINISHED", "SERVER_FINISHED"};
89 
90 static const char* tsi_fake_handshake_message_to_string(int msg) {
91  if (msg < 0 || msg >= TSI_FAKE_HANDSHAKE_MESSAGE_MAX) {
92  gpr_log(GPR_ERROR, "Invalid message %d", msg);
93  return "UNKNOWN";
94  }
96 }
97 
99  const char* msg_string, tsi_fake_handshake_message* msg) {
100  for (int i = 0; i < TSI_FAKE_HANDSHAKE_MESSAGE_MAX; i++) {
101  if (strncmp(msg_string, tsi_fake_handshake_message_strings[i],
102  strlen(tsi_fake_handshake_message_strings[i])) == 0) {
103  *msg = static_cast<tsi_fake_handshake_message>(i);
104  return TSI_OK;
105  }
106  }
107  gpr_log(GPR_ERROR, "Invalid handshake message.");
108  return TSI_DATA_CORRUPTED;
109 }
110 
111 static uint32_t load32_little_endian(const unsigned char* buf) {
112  return (static_cast<uint32_t>(buf[0]) | static_cast<uint32_t>(buf[1] << 8) |
113  static_cast<uint32_t>(buf[2] << 16) |
114  static_cast<uint32_t>(buf[3] << 24));
115 }
116 
117 static void store32_little_endian(uint32_t value, unsigned char* buf) {
118  buf[3] = static_cast<unsigned char>((value >> 24) & 0xFF);
119  buf[2] = static_cast<unsigned char>((value >> 16) & 0xFF);
120  buf[1] = static_cast<unsigned char>((value >> 8) & 0xFF);
121  buf[0] = static_cast<unsigned char>((value)&0xFF);
122 }
123 
125  GPR_ASSERT(sb != nullptr && sb->length >= TSI_FAKE_FRAME_HEADER_SIZE);
126  uint8_t frame_size_buffer[TSI_FAKE_FRAME_HEADER_SIZE];
127  uint8_t* buf = frame_size_buffer;
128  /* Copies the first 4 bytes to a temporary buffer. */
129  size_t remaining = TSI_FAKE_FRAME_HEADER_SIZE;
130  for (size_t i = 0; i < sb->count; i++) {
131  size_t slice_length = GRPC_SLICE_LENGTH(sb->slices[i]);
132  if (remaining <= slice_length) {
133  memcpy(buf, GRPC_SLICE_START_PTR(sb->slices[i]), remaining);
134  remaining = 0;
135  break;
136  } else {
137  memcpy(buf, GRPC_SLICE_START_PTR(sb->slices[i]), slice_length);
138  buf += slice_length;
139  remaining -= slice_length;
140  }
141  }
142  GPR_ASSERT(remaining == 0);
143  return load32_little_endian(frame_size_buffer);
144 }
145 
147  const grpc_slice_buffer* protected_slices) {
148  return read_frame_size(protected_slices);
149 }
150 
151 static void tsi_fake_frame_reset(tsi_fake_frame* frame, int needs_draining) {
152  frame->offset = 0;
153  frame->needs_draining = needs_draining;
154  if (!needs_draining) frame->size = 0;
155 }
156 
157 /* Checks if the frame's allocated size is at least frame->size, and reallocs
158  * more memory if necessary. */
160  if (frame->data == nullptr) {
161  frame->allocated_size = frame->size;
162  frame->data =
163  static_cast<unsigned char*>(gpr_malloc(frame->allocated_size));
164  } else if (frame->size > frame->allocated_size) {
165  unsigned char* new_data =
166  static_cast<unsigned char*>(gpr_realloc(frame->data, frame->size));
167  frame->data = new_data;
168  frame->allocated_size = frame->size;
169  }
170 }
171 
172 /* Decodes the serialized fake frame contained in incoming_bytes, and fills
173  * frame with the contents of the decoded frame.
174  * This method should not be called if frame->needs_framing is not 0. */
175 static tsi_result tsi_fake_frame_decode(const unsigned char* incoming_bytes,
176  size_t* incoming_bytes_size,
178  size_t available_size = *incoming_bytes_size;
179  size_t to_read_size = 0;
180  const unsigned char* bytes_cursor = incoming_bytes;
181 
182  if (frame->needs_draining) return TSI_INTERNAL_ERROR;
183  if (frame->data == nullptr) {
185  frame->data =
186  static_cast<unsigned char*>(gpr_malloc(frame->allocated_size));
187  }
188 
189  if (frame->offset < TSI_FAKE_FRAME_HEADER_SIZE) {
190  to_read_size = TSI_FAKE_FRAME_HEADER_SIZE - frame->offset;
191  if (to_read_size > available_size) {
192  /* Just fill what we can and exit. */
193  memcpy(frame->data + frame->offset, bytes_cursor, available_size);
194  bytes_cursor += available_size;
195  frame->offset += available_size;
196  *incoming_bytes_size = static_cast<size_t>(bytes_cursor - incoming_bytes);
197  return TSI_INCOMPLETE_DATA;
198  }
199  memcpy(frame->data + frame->offset, bytes_cursor, to_read_size);
200  bytes_cursor += to_read_size;
201  frame->offset += to_read_size;
202  available_size -= to_read_size;
203  frame->size = load32_little_endian(frame->data);
205  }
206 
207  to_read_size = frame->size - frame->offset;
208  if (to_read_size > available_size) {
209  memcpy(frame->data + frame->offset, bytes_cursor, available_size);
210  frame->offset += available_size;
211  bytes_cursor += available_size;
212  *incoming_bytes_size = static_cast<size_t>(bytes_cursor - incoming_bytes);
213  return TSI_INCOMPLETE_DATA;
214  }
215  memcpy(frame->data + frame->offset, bytes_cursor, to_read_size);
216  bytes_cursor += to_read_size;
217  *incoming_bytes_size = static_cast<size_t>(bytes_cursor - incoming_bytes);
218  tsi_fake_frame_reset(frame, 1 /* needs_draining */);
219  return TSI_OK;
220 }
221 
222 /* Encodes a fake frame into its wire format and places the result in
223  * outgoing_bytes. outgoing_bytes_size indicates the size of the encoded frame.
224  * This method should not be called if frame->needs_framing is 0. */
225 static tsi_result tsi_fake_frame_encode(unsigned char* outgoing_bytes,
226  size_t* outgoing_bytes_size,
228  size_t to_write_size = frame->size - frame->offset;
229  if (!frame->needs_draining) return TSI_INTERNAL_ERROR;
230  if (*outgoing_bytes_size < to_write_size) {
231  memcpy(outgoing_bytes, frame->data + frame->offset, *outgoing_bytes_size);
232  frame->offset += *outgoing_bytes_size;
233  return TSI_INCOMPLETE_DATA;
234  }
235  memcpy(outgoing_bytes, frame->data + frame->offset, to_write_size);
236  *outgoing_bytes_size = to_write_size;
237  tsi_fake_frame_reset(frame, 0 /* needs_draining */);
238  return TSI_OK;
239 }
240 
241 /* Sets the payload of a fake frame to contain the given data blob, where
242  * data_size indicates the size of data. */
243 static tsi_result tsi_fake_frame_set_data(unsigned char* data, size_t data_size,
245  frame->offset = 0;
246  frame->size = data_size + TSI_FAKE_FRAME_HEADER_SIZE;
248  store32_little_endian(static_cast<uint32_t>(frame->size), frame->data);
249  memcpy(frame->data + TSI_FAKE_FRAME_HEADER_SIZE, data, data_size);
250  tsi_fake_frame_reset(frame, 1 /* needs draining */);
251  return TSI_OK;
252 }
253 
254 /* Destroys the contents of a fake frame. */
256  if (frame->data != nullptr) gpr_free(frame->data);
257 }
258 
259 /* --- tsi_frame_protector methods implementation. ---*/
260 
262  const unsigned char* unprotected_bytes,
263  size_t* unprotected_bytes_size,
264  unsigned char* protected_output_frames,
265  size_t* protected_output_frames_size) {
268  reinterpret_cast<tsi_fake_frame_protector*>(self);
269  unsigned char frame_header[TSI_FAKE_FRAME_HEADER_SIZE];
271  size_t saved_output_size = *protected_output_frames_size;
272  size_t drained_size = 0;
273  size_t* num_bytes_written = protected_output_frames_size;
274  *num_bytes_written = 0;
275 
276  /* Try to drain first. */
277  if (frame->needs_draining) {
278  drained_size = saved_output_size - *num_bytes_written;
279  result =
280  tsi_fake_frame_encode(protected_output_frames, &drained_size, frame);
281  *num_bytes_written += drained_size;
282  protected_output_frames += drained_size;
283  if (result != TSI_OK) {
284  if (result == TSI_INCOMPLETE_DATA) {
285  *unprotected_bytes_size = 0;
286  result = TSI_OK;
287  }
288  return result;
289  }
290  }
291 
292  /* Now process the unprotected_bytes. */
293  if (frame->needs_draining) return TSI_INTERNAL_ERROR;
294  if (frame->size == 0) {
295  /* New frame, create a header. */
296  size_t written_in_frame_size = 0;
297  store32_little_endian(static_cast<uint32_t>(impl->max_frame_size),
298  frame_header);
299  written_in_frame_size = TSI_FAKE_FRAME_HEADER_SIZE;
300  result = tsi_fake_frame_decode(frame_header, &written_in_frame_size, frame);
301  if (result != TSI_INCOMPLETE_DATA) {
302  gpr_log(GPR_ERROR, "tsi_fake_frame_decode returned %s",
304  return result;
305  }
306  }
307  result =
308  tsi_fake_frame_decode(unprotected_bytes, unprotected_bytes_size, frame);
309  if (result != TSI_OK) {
311  return result;
312  }
313 
314  /* Try to drain again. */
315  if (!frame->needs_draining) return TSI_INTERNAL_ERROR;
316  if (frame->offset != 0) return TSI_INTERNAL_ERROR;
317  drained_size = saved_output_size - *num_bytes_written;
318  result = tsi_fake_frame_encode(protected_output_frames, &drained_size, frame);
319  *num_bytes_written += drained_size;
321  return result;
322 }
323 
325  tsi_frame_protector* self, unsigned char* protected_output_frames,
326  size_t* protected_output_frames_size, size_t* still_pending_size) {
329  reinterpret_cast<tsi_fake_frame_protector*>(self);
331  if (!frame->needs_draining) {
332  /* Create a short frame. */
333  frame->size = frame->offset;
334  frame->offset = 0;
335  frame->needs_draining = 1;
336  store32_little_endian(static_cast<uint32_t>(frame->size),
337  frame->data); /* Overwrite header. */
338  }
339  result = tsi_fake_frame_encode(protected_output_frames,
340  protected_output_frames_size, frame);
342  *still_pending_size = frame->size - frame->offset;
343  return result;
344 }
345 
347  tsi_frame_protector* self, const unsigned char* protected_frames_bytes,
348  size_t* protected_frames_bytes_size, unsigned char* unprotected_bytes,
349  size_t* unprotected_bytes_size) {
352  reinterpret_cast<tsi_fake_frame_protector*>(self);
354  size_t saved_output_size = *unprotected_bytes_size;
355  size_t drained_size = 0;
356  size_t* num_bytes_written = unprotected_bytes_size;
357  *num_bytes_written = 0;
358 
359  /* Try to drain first. */
360  if (frame->needs_draining) {
361  /* Go past the header if needed. */
362  if (frame->offset == 0) frame->offset = TSI_FAKE_FRAME_HEADER_SIZE;
363  drained_size = saved_output_size - *num_bytes_written;
364  result = tsi_fake_frame_encode(unprotected_bytes, &drained_size, frame);
365  unprotected_bytes += drained_size;
366  *num_bytes_written += drained_size;
367  if (result != TSI_OK) {
368  if (result == TSI_INCOMPLETE_DATA) {
369  *protected_frames_bytes_size = 0;
370  result = TSI_OK;
371  }
372  return result;
373  }
374  }
375 
376  /* Now process the protected_bytes. */
377  if (frame->needs_draining) return TSI_INTERNAL_ERROR;
378  result = tsi_fake_frame_decode(protected_frames_bytes,
379  protected_frames_bytes_size, frame);
380  if (result != TSI_OK) {
382  return result;
383  }
384 
385  /* Try to drain again. */
386  if (!frame->needs_draining) return TSI_INTERNAL_ERROR;
387  if (frame->offset != 0) return TSI_INTERNAL_ERROR;
388  frame->offset = TSI_FAKE_FRAME_HEADER_SIZE; /* Go past the header. */
389  drained_size = saved_output_size - *num_bytes_written;
390  result = tsi_fake_frame_encode(unprotected_bytes, &drained_size, frame);
391  *num_bytes_written += drained_size;
393  return result;
394 }
395 
398  reinterpret_cast<tsi_fake_frame_protector*>(self);
401  gpr_free(self);
402 }
403 
409 };
410 
411 /* --- tsi_zero_copy_grpc_protector methods implementation. ---*/
412 
414  tsi_zero_copy_grpc_protector* self, grpc_slice_buffer* unprotected_slices,
415  grpc_slice_buffer* protected_slices) {
416  if (self == nullptr || unprotected_slices == nullptr ||
417  protected_slices == nullptr) {
418  return TSI_INVALID_ARGUMENT;
419  }
421  reinterpret_cast<tsi_fake_zero_copy_grpc_protector*>(self);
422  /* Protects each frame. */
423  while (unprotected_slices->length > 0) {
424  size_t frame_length =
425  std::min(impl->max_frame_size,
426  unprotected_slices->length + TSI_FAKE_FRAME_HEADER_SIZE);
430  grpc_slice_buffer_add(protected_slices, slice);
431  size_t data_length = frame_length - TSI_FAKE_FRAME_HEADER_SIZE;
432  grpc_slice_buffer_move_first(unprotected_slices, data_length,
433  protected_slices);
434  }
435  return TSI_OK;
436 }
437 
439  tsi_zero_copy_grpc_protector* self, grpc_slice_buffer* protected_slices,
440  grpc_slice_buffer* unprotected_slices, int* min_progress_size) {
441  if (self == nullptr || unprotected_slices == nullptr ||
442  protected_slices == nullptr) {
443  return TSI_INVALID_ARGUMENT;
444  }
446  reinterpret_cast<tsi_fake_zero_copy_grpc_protector*>(self);
447  grpc_slice_buffer_move_into(protected_slices, &impl->protected_sb);
448  /* Unprotect each frame, if we get a full frame. */
450  if (impl->parsed_frame_size == 0) {
452  if (impl->parsed_frame_size <= 4) {
453  gpr_log(GPR_ERROR, "Invalid frame size.");
454  return TSI_DATA_CORRUPTED;
455  }
456  }
457  /* If we do not have a full frame, return with OK status. */
458  if (impl->protected_sb.length < impl->parsed_frame_size) break;
459  /* Strips header bytes. */
462  /* Moves data to unprotected slices. */
464  &impl->protected_sb,
466  unprotected_slices);
467  impl->parsed_frame_size = 0;
469  }
470  if (min_progress_size != nullptr) {
472  *min_progress_size = impl->parsed_frame_size - impl->protected_sb.length;
473  } else {
474  *min_progress_size = 1;
475  }
476  }
477  return TSI_OK;
478 }
479 
482  if (self == nullptr) return;
484  reinterpret_cast<tsi_fake_zero_copy_grpc_protector*>(self);
487  gpr_free(impl);
488 }
489 
491  tsi_zero_copy_grpc_protector* self, size_t* max_frame_size) {
492  if (self == nullptr || max_frame_size == nullptr) return TSI_INVALID_ARGUMENT;
494  reinterpret_cast<tsi_fake_zero_copy_grpc_protector*>(self);
495  *max_frame_size = impl->max_frame_size;
496  return TSI_OK;
497 }
498 
505 };
506 
507 /* --- tsi_handshaker_result methods implementation. ---*/
508 
511  unsigned char* unused_bytes;
513 };
514 
516  const tsi_handshaker_result* /*self*/, tsi_peer* peer) {
517  /* Construct a tsi_peer with 1 property: certificate type, security_level. */
519  if (result != TSI_OK) return result;
522  &peer->properties[0]);
523  if (result != TSI_OK) tsi_peer_destruct(peer);
527  if (result != TSI_OK) tsi_peer_destruct(peer);
528  return result;
529 }
530 
532  const tsi_handshaker_result* /*self*/,
533  tsi_frame_protector_type* frame_protector_type) {
534  *frame_protector_type = TSI_FRAME_PROTECTOR_NORMAL_OR_ZERO_COPY;
535  return TSI_OK;
536 }
537 
539  const tsi_handshaker_result* /*self*/,
540  size_t* max_output_protected_frame_size,
541  tsi_zero_copy_grpc_protector** protector) {
542  *protector =
543  tsi_create_fake_zero_copy_grpc_protector(max_output_protected_frame_size);
544  return TSI_OK;
545 }
546 
548  const tsi_handshaker_result* /*self*/,
549  size_t* max_output_protected_frame_size, tsi_frame_protector** protector) {
550  *protector = tsi_create_fake_frame_protector(max_output_protected_frame_size);
551  return TSI_OK;
552 }
553 
555  const tsi_handshaker_result* self, const unsigned char** bytes,
556  size_t* bytes_size) {
558  const_cast<tsi_handshaker_result*>(self));
559  *bytes_size = result->unused_bytes_size;
560  *bytes = result->unused_bytes;
561  return TSI_OK;
562 }
563 
566  reinterpret_cast<fake_handshaker_result*>(self);
567  gpr_free(result->unused_bytes);
568  gpr_free(self);
569 }
570 
578 };
579 
581  const unsigned char* unused_bytes, size_t unused_bytes_size,
582  tsi_handshaker_result** handshaker_result) {
583  if ((unused_bytes_size > 0 && unused_bytes == nullptr) ||
584  handshaker_result == nullptr) {
585  return TSI_INVALID_ARGUMENT;
586  }
587  fake_handshaker_result* result = grpc_core::Zalloc<fake_handshaker_result>();
588  result->base.vtable = &handshaker_result_vtable;
589  if (unused_bytes_size > 0) {
590  result->unused_bytes =
591  static_cast<unsigned char*>(gpr_malloc(unused_bytes_size));
592  memcpy(result->unused_bytes, unused_bytes, unused_bytes_size);
593  }
594  result->unused_bytes_size = unused_bytes_size;
595  *handshaker_result = &result->base;
596  return TSI_OK;
597 }
598 
599 /* --- tsi_handshaker methods implementation. ---*/
600 
602  tsi_handshaker* self, unsigned char* bytes, size_t* bytes_size) {
603  tsi_fake_handshaker* impl = reinterpret_cast<tsi_fake_handshaker*>(self);
605  if (impl->needs_incoming_message || impl->result == TSI_OK) {
606  *bytes_size = 0;
607  return TSI_OK;
608  }
609  if (!impl->outgoing_frame.needs_draining) {
610  tsi_fake_handshake_message next_message_to_send =
611  // NOLINTNEXTLINE(bugprone-misplaced-widening-cast)
612  static_cast<tsi_fake_handshake_message>(impl->next_message_to_send + 2);
613  const char* msg_string =
616  reinterpret_cast<unsigned char*>(const_cast<char*>(msg_string)),
617  strlen(msg_string), &impl->outgoing_frame);
618  if (result != TSI_OK) return result;
619  if (next_message_to_send > TSI_FAKE_HANDSHAKE_MESSAGE_MAX) {
620  next_message_to_send = TSI_FAKE_HANDSHAKE_MESSAGE_MAX;
621  }
623  gpr_log(GPR_INFO, "%s prepared %s.",
624  impl->is_client ? "Client" : "Server",
626  }
627  impl->next_message_to_send = next_message_to_send;
628  }
629  result = tsi_fake_frame_encode(bytes, bytes_size, &impl->outgoing_frame);
630  if (result != TSI_OK) return result;
631  if (!impl->is_client &&
633  /* We're done. */
635  gpr_log(GPR_INFO, "Server is done.");
636  }
637  impl->result = TSI_OK;
638  } else {
639  impl->needs_incoming_message = 1;
640  }
641  return TSI_OK;
642 }
643 
645  tsi_handshaker* self, const unsigned char* bytes, size_t* bytes_size) {
647  tsi_fake_handshaker* impl = reinterpret_cast<tsi_fake_handshaker*>(self);
648  tsi_fake_handshake_message expected_msg =
649  static_cast<tsi_fake_handshake_message>(impl->next_message_to_send - 1);
650  tsi_fake_handshake_message received_msg;
651 
652  if (!impl->needs_incoming_message || impl->result == TSI_OK) {
653  *bytes_size = 0;
654  return TSI_OK;
655  }
656  result = tsi_fake_frame_decode(bytes, bytes_size, &impl->incoming_frame);
657  if (result != TSI_OK) return result;
658 
659  /* We now have a complete frame. */
661  reinterpret_cast<const char*>(impl->incoming_frame.data) +
663  &received_msg);
664  if (result != TSI_OK) {
665  impl->result = result;
666  return result;
667  }
668  if (received_msg != expected_msg) {
669  gpr_log(GPR_ERROR, "Invalid received message (%s instead of %s)",
672  }
674  gpr_log(GPR_INFO, "%s received %s.", impl->is_client ? "Client" : "Server",
676  }
677  tsi_fake_frame_reset(&impl->incoming_frame, 0 /* needs_draining */);
678  impl->needs_incoming_message = 0;
680  /* We're done. */
682  gpr_log(GPR_INFO, "%s is done.", impl->is_client ? "Client" : "Server");
683  }
684  impl->result = TSI_OK;
685  }
686  return TSI_OK;
687 }
688 
690  tsi_fake_handshaker* impl = reinterpret_cast<tsi_fake_handshaker*>(self);
691  return impl->result;
692 }
693 
695  tsi_fake_handshaker* impl = reinterpret_cast<tsi_fake_handshaker*>(self);
699  gpr_free(self);
700 }
701 
703  tsi_handshaker* self, const unsigned char* received_bytes,
704  size_t received_bytes_size, const unsigned char** bytes_to_send,
705  size_t* bytes_to_send_size, tsi_handshaker_result** handshaker_result,
706  tsi_handshaker_on_next_done_cb /*cb*/, void* /*user_data*/) {
707  /* Sanity check the arguments. */
708  if ((received_bytes_size > 0 && received_bytes == nullptr) ||
709  bytes_to_send == nullptr || bytes_to_send_size == nullptr ||
710  handshaker_result == nullptr) {
711  return TSI_INVALID_ARGUMENT;
712  }
713  tsi_fake_handshaker* handshaker =
714  reinterpret_cast<tsi_fake_handshaker*>(self);
716 
717  /* Decode and process a handshake frame from the peer. */
718  size_t consumed_bytes_size = received_bytes_size;
719  if (received_bytes_size > 0) {
720  result = fake_handshaker_process_bytes_from_peer(self, received_bytes,
721  &consumed_bytes_size);
722  if (result != TSI_OK) return result;
723  }
724 
725  /* Create a handshake message to send to the peer and encode it as a fake
726  * frame. */
727  size_t offset = 0;
728  do {
729  size_t sent_bytes_size = handshaker->outgoing_bytes_buffer_size - offset;
731  self, handshaker->outgoing_bytes_buffer + offset, &sent_bytes_size);
732  offset += sent_bytes_size;
733  if (result == TSI_INCOMPLETE_DATA) {
734  handshaker->outgoing_bytes_buffer_size *= 2;
735  handshaker->outgoing_bytes_buffer = static_cast<unsigned char*>(
737  handshaker->outgoing_bytes_buffer_size));
738  }
739  } while (result == TSI_INCOMPLETE_DATA);
740  if (result != TSI_OK) return result;
741  *bytes_to_send = handshaker->outgoing_bytes_buffer;
742  *bytes_to_send_size = offset;
743 
744  /* Check if the handshake was completed. */
746  *handshaker_result = nullptr;
747  } else {
748  /* Calculate the unused bytes. */
749  const unsigned char* unused_bytes = nullptr;
750  size_t unused_bytes_size = received_bytes_size - consumed_bytes_size;
751  if (unused_bytes_size > 0) {
752  unused_bytes = received_bytes + consumed_bytes_size;
753  }
754 
755  /* Create a handshaker_result containing the unused bytes. */
756  result = fake_handshaker_result_create(unused_bytes, unused_bytes_size,
757  handshaker_result);
758  if (result == TSI_OK) {
759  /* Indicate that the handshake has completed and that a handshaker_result
760  * has been created. */
761  self->handshaker_result_created = true;
762  }
763  }
764  return result;
765 }
766 
768  nullptr, /* get_bytes_to_send_to_peer -- deprecated */
769  nullptr, /* process_bytes_from_peer -- deprecated */
770  nullptr, /* get_result -- deprecated */
771  nullptr, /* extract_peer -- deprecated */
772  nullptr, /* create_frame_protector -- deprecated */
775  nullptr, /* shutdown */
776 };
777 
779  tsi_fake_handshaker* impl = grpc_core::Zalloc<tsi_fake_handshaker>();
780  impl->base.vtable = &handshaker_vtable;
781  impl->is_client = is_client;
785  impl->outgoing_bytes_buffer =
786  static_cast<unsigned char*>(gpr_malloc(impl->outgoing_bytes_buffer_size));
787  if (is_client) {
788  impl->needs_incoming_message = 0;
790  } else {
791  impl->needs_incoming_message = 1;
793  }
794  return &impl->base;
795 }
796 
798  size_t* max_protected_frame_size) {
800  grpc_core::Zalloc<tsi_fake_frame_protector>();
801  impl->max_frame_size = (max_protected_frame_size == nullptr)
803  : *max_protected_frame_size;
805  return &impl->base;
806 }
807 
809  size_t* max_protected_frame_size) {
811  static_cast<tsi_fake_zero_copy_grpc_protector*>(
812  gpr_zalloc(sizeof(*impl)));
815  impl->max_frame_size = (max_protected_frame_size == nullptr)
817  : *max_protected_frame_size;
818  impl->parsed_frame_size = 0;
820  return &impl->base;
821 }
fake_handshaker_process_bytes_from_peer
static tsi_result fake_handshaker_process_bytes_from_peer(tsi_handshaker *self, const unsigned char *bytes, size_t *bytes_size)
Definition: fake_transport_security.cc:644
tsi_security_level_to_string
const char * tsi_security_level_to_string(tsi_security_level security_level)
Definition: transport_security.cc:70
TSI_FAKE_FRAME_HEADER_SIZE
#define TSI_FAKE_FRAME_HEADER_SIZE
Definition: fake_transport_security.cc:35
_gevent_test_main.result
result
Definition: _gevent_test_main.py:96
GPR_INFO
#define GPR_INFO
Definition: include/grpc/impl/codegen/log.h:56
handshaker_result_vtable
static const tsi_handshaker_result_vtable handshaker_result_vtable
Definition: fake_transport_security.cc:571
tsi_handshaker::vtable
const tsi_handshaker_vtable * vtable
Definition: transport_security.h:85
grpc_slice_buffer_move_into
GPRAPI void grpc_slice_buffer_move_into(grpc_slice_buffer *src, grpc_slice_buffer *dst)
Definition: slice/slice_buffer.cc:291
fake_zero_copy_grpc_protector_protect
static tsi_result fake_zero_copy_grpc_protector_protect(tsi_zero_copy_grpc_protector *self, grpc_slice_buffer *unprotected_slices, grpc_slice_buffer *protected_slices)
Definition: fake_transport_security.cc:413
fake_protector_unprotect
static tsi_result fake_protector_unprotect(tsi_frame_protector *self, const unsigned char *protected_frames_bytes, size_t *protected_frames_bytes_size, unsigned char *unprotected_bytes, size_t *unprotected_bytes_size)
Definition: fake_transport_security.cc:346
fake_handshaker_result::base
tsi_handshaker_result base
Definition: fake_transport_security.cc:510
log.h
tsi_peer::properties
tsi_peer_property * properties
Definition: transport_security_interface.h:239
tsi_fake_frame_ensure_size
static void tsi_fake_frame_ensure_size(tsi_fake_frame *frame)
Definition: fake_transport_security.cc:159
fake_handshaker_next
static tsi_result fake_handshaker_next(tsi_handshaker *self, const unsigned char *received_bytes, size_t received_bytes_size, const unsigned char **bytes_to_send, size_t *bytes_to_send_size, tsi_handshaker_result **handshaker_result, tsi_handshaker_on_next_done_cb, void *)
Definition: fake_transport_security.cc:702
tsi_fake_handshaker::outgoing_bytes_buffer_size
size_t outgoing_bytes_buffer_size
Definition: fake_transport_security.cc:69
tsi_handshaker_vtable
Definition: transport_security.h:57
tsi_fake_zero_copy_grpc_protector::parsed_frame_size
size_t parsed_frame_size
Definition: fake_transport_security.cc:83
tsi_tracing_enabled
grpc_core::TraceFlag tsi_tracing_enabled(false, "tsi")
tsi_fake_handshaker::base
tsi_handshaker base
Definition: fake_transport_security.cc:62
fake_handshaker_result_destroy
static void fake_handshaker_result_destroy(tsi_handshaker_result *self)
Definition: fake_transport_security.cc:564
tsi_handshaker
Definition: transport_security.h:84
tsi_fake_handshaker::incoming_frame
tsi_fake_frame incoming_frame
Definition: fake_transport_security.cc:66
TSI_FAKE_CLIENT_FINISHED
@ TSI_FAKE_CLIENT_FINISHED
Definition: fake_transport_security.cc:56
TSI_FAKE_HANDSHAKE_MESSAGE_MAX
@ TSI_FAKE_HANDSHAKE_MESSAGE_MAX
Definition: fake_transport_security.cc:58
TSI_INTERNAL_ERROR
@ TSI_INTERNAL_ERROR
Definition: transport_security_interface.h:39
tsi_zero_copy_grpc_protector::vtable
const tsi_zero_copy_grpc_protector_vtable * vtable
Definition: transport_security_grpc.h:80
fake_handshaker_result_create_zero_copy_grpc_protector
static tsi_result fake_handshaker_result_create_zero_copy_grpc_protector(const tsi_handshaker_result *, size_t *max_output_protected_frame_size, tsi_zero_copy_grpc_protector **protector)
Definition: fake_transport_security.cc:538
TSI_SECURITY_LEVEL_PEER_PROPERTY
#define TSI_SECURITY_LEVEL_PEER_PROPERTY
Definition: transport_security_interface.h:226
string.h
buf
voidpf void * buf
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
grpc_slice_buffer::slices
grpc_slice * slices
Definition: include/grpc/impl/codegen/slice.h:89
gpr_free
GPRAPI void gpr_free(void *ptr)
Definition: alloc.cc:51
useful.h
GRPC_SLICE_MALLOC
#define GRPC_SLICE_MALLOC(len)
Definition: include/grpc/slice.h:70
fake_handshaker_result_get_unused_bytes
static tsi_result fake_handshaker_result_get_unused_bytes(const tsi_handshaker_result *self, const unsigned char **bytes, size_t *bytes_size)
Definition: fake_transport_security.cc:554
tsi_fake_frame::allocated_size
size_t allocated_size
Definition: fake_transport_security.cc:49
gpr_malloc
GPRAPI void * gpr_malloc(size_t size)
Definition: alloc.cc:29
tsi_fake_frame::size
size_t size
Definition: fake_transport_security.cc:48
TSI_FAKE_FRAME_INITIAL_ALLOCATED_SIZE
#define TSI_FAKE_FRAME_INITIAL_ALLOCATED_SIZE
Definition: fake_transport_security.cc:36
tsi_create_fake_handshaker
tsi_handshaker * tsi_create_fake_handshaker(int is_client)
Definition: fake_transport_security.cc:778
tsi_fake_handshaker::next_message_to_send
tsi_fake_handshake_message next_message_to_send
Definition: fake_transport_security.cc:64
tsi_fake_handshaker::outgoing_frame
tsi_fake_frame outgoing_frame
Definition: fake_transport_security.cc:67
fake_handshaker_result_create_frame_protector
static tsi_result fake_handshaker_result_create_frame_protector(const tsi_handshaker_result *, size_t *max_output_protected_frame_size, tsi_frame_protector **protector)
Definition: fake_transport_security.cc:547
uint8_t
unsigned char uint8_t
Definition: stdint-msvc2008.h:78
GRPC_TRACE_FLAG_ENABLED
#define GRPC_TRACE_FLAG_ENABLED(f)
Definition: debug/trace.h:114
tsi_fake_handshake_message_strings
static const char * tsi_fake_handshake_message_strings[]
Definition: fake_transport_security.cc:87
tsi_fake_frame::offset
size_t offset
Definition: fake_transport_security.cc:50
handshaker_vtable
static const tsi_handshaker_vtable handshaker_vtable
Definition: fake_transport_security.cc:767
store32_little_endian
static void store32_little_endian(uint32_t value, unsigned char *buf)
Definition: fake_transport_security.cc:117
tsi_fake_zero_copy_grpc_protector::header_sb
grpc_slice_buffer header_sb
Definition: fake_transport_security.cc:80
TSI_FAKE_HANDSHAKER_OUTGOING_BUFFER_INITIAL_SIZE
#define TSI_FAKE_HANDSHAKER_OUTGOING_BUFFER_INITIAL_SIZE
Definition: fake_transport_security.cc:38
gpr_zalloc
GPRAPI void * gpr_zalloc(size_t size)
Definition: alloc.cc:40
TSI_FAKE_CERTIFICATE_TYPE
#define TSI_FAKE_CERTIFICATE_TYPE
Definition: fake_transport_security.h:28
memory.h
uint32_t
unsigned int uint32_t
Definition: stdint-msvc2008.h:80
frame_length
static size_t frame_length(size_t payload_length)
Definition: frame_handler_test.cc:42
TSI_OK
@ TSI_OK
Definition: transport_security_interface.h:32
read_frame_size
static uint32_t read_frame_size(const grpc_slice_buffer *sb)
Definition: fake_transport_security.cc:124
zero_copy_grpc_protector_vtable
static const tsi_zero_copy_grpc_protector_vtable zero_copy_grpc_protector_vtable
Definition: fake_transport_security.cc:500
memcpy
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
tsi_fake_handshaker::result
tsi_result result
Definition: fake_transport_security.cc:70
fake_zero_copy_grpc_protector_unprotect
static tsi_result fake_zero_copy_grpc_protector_unprotect(tsi_zero_copy_grpc_protector *self, grpc_slice_buffer *protected_slices, grpc_slice_buffer *unprotected_slices, int *min_progress_size)
Definition: fake_transport_security.cc:438
tsi_frame_protector_type
tsi_frame_protector_type
Definition: transport_security_interface.h:69
GPR_ASSERT
#define GPR_ASSERT(x)
Definition: include/grpc/impl/codegen/log.h:94
gpr_realloc
GPRAPI void * gpr_realloc(void *p, size_t size)
Definition: alloc.cc:56
tsi_fake_handshake_message_to_string
static const char * tsi_fake_handshake_message_to_string(int msg)
Definition: fake_transport_security.cc:90
grpc_slice_buffer::count
size_t count
Definition: include/grpc/impl/codegen/slice.h:91
slice
grpc_slice slice
Definition: src/core/lib/surface/server.cc:467
tsi_fake_zero_copy_grpc_protector::base
tsi_zero_copy_grpc_protector base
Definition: fake_transport_security.cc:79
gpr_log
GPRAPI void gpr_log(const char *file, int line, gpr_log_severity severity, const char *format,...) GPR_PRINT_FORMAT_CHECK(4
fake_handshaker_result::unused_bytes_size
size_t unused_bytes_size
Definition: fake_transport_security.cc:512
TSI_FAKE_DEFAULT_FRAME_SIZE
#define TSI_FAKE_DEFAULT_FRAME_SIZE
Definition: fake_transport_security.cc:37
tsi_handshaker_on_next_done_cb
void(* tsi_handshaker_on_next_done_cb)(tsi_result status, void *user_data, const unsigned char *bytes_to_send, size_t bytes_to_send_size, tsi_handshaker_result *handshaker_result)
Definition: transport_security_interface.h:462
tsi_fake_handshaker::outgoing_bytes_buffer
unsigned char * outgoing_bytes_buffer
Definition: fake_transport_security.cc:68
tsi_result
tsi_result
Definition: transport_security_interface.h:31
grpc_slice_buffer::length
size_t length
Definition: include/grpc/impl/codegen/slice.h:96
tsi_fake_frame_reset
static void tsi_fake_frame_reset(tsi_fake_frame *frame, int needs_draining)
Definition: fake_transport_security.cc:151
GRPC_SLICE_START_PTR
#define GRPC_SLICE_START_PTR(slice)
Definition: include/grpc/impl/codegen/slice.h:101
fake_handshaker_get_result
static tsi_result fake_handshaker_get_result(tsi_handshaker *self)
Definition: fake_transport_security.cc:689
tsi_fake_frame_decode
static tsi_result tsi_fake_frame_decode(const unsigned char *incoming_bytes, size_t *incoming_bytes_size, tsi_fake_frame *frame)
Definition: fake_transport_security.cc:175
grpc_slice
Definition: include/grpc/impl/codegen/slice.h:65
fake_protector_protect_flush
static tsi_result fake_protector_protect_flush(tsi_frame_protector *self, unsigned char *protected_output_frames, size_t *protected_output_frames_size, size_t *still_pending_size)
Definition: fake_transport_security.cc:324
tsi_fake_frame_protector::unprotect_frame
tsi_fake_frame unprotect_frame
Definition: fake_transport_security.cc:75
data
char data[kBufferLength]
Definition: abseil-cpp/absl/strings/internal/str_format/float_conversion.cc:1006
tsi_fake_frame_encode
static tsi_result tsi_fake_frame_encode(unsigned char *outgoing_bytes, size_t *outgoing_bytes_size, tsi_fake_frame *frame)
Definition: fake_transport_security.cc:225
slice_internal.h
GPR_ERROR
#define GPR_ERROR
Definition: include/grpc/impl/codegen/log.h:57
min
#define min(a, b)
Definition: qsort.h:83
TSI_SECURITY_NONE
@ TSI_SECURITY_NONE
Definition: transport_security_interface.h:54
fake_zero_copy_grpc_protector_destroy
static void fake_zero_copy_grpc_protector_destroy(tsi_zero_copy_grpc_protector *self)
Definition: fake_transport_security.cc:480
tsi_fake_frame_protector::protect_frame
tsi_fake_frame protect_frame
Definition: fake_transport_security.cc:74
tsi_fake_handshake_message_from_string
static tsi_result tsi_fake_handshake_message_from_string(const char *msg_string, tsi_fake_handshake_message *msg)
Definition: fake_transport_security.cc:98
grpc_slice_buffer_init
GPRAPI void grpc_slice_buffer_init(grpc_slice_buffer *sb)
Definition: slice/slice_buffer.cc:116
msg
std::string msg
Definition: client_interceptors_end2end_test.cc:372
tsi_fake_zero_copy_grpc_protector
Definition: fake_transport_security.cc:78
load32_little_endian
static uint32_t load32_little_endian(const unsigned char *buf)
Definition: fake_transport_security.cc:111
GRPC_SLICE_LENGTH
#define GRPC_SLICE_LENGTH(slice)
Definition: include/grpc/impl/codegen/slice.h:104
tsi_fake_frame_destruct
static void tsi_fake_frame_destruct(tsi_fake_frame *frame)
Definition: fake_transport_security.cc:255
value
const char * value
Definition: hpack_parser_table.cc:165
tsi_fake_frame::needs_draining
int needs_draining
Definition: fake_transport_security.cc:51
tsi_fake_zero_copy_grpc_protector::max_frame_size
size_t max_frame_size
Definition: fake_transport_security.cc:82
TSI_DATA_CORRUPTED
@ TSI_DATA_CORRUPTED
Definition: transport_security_interface.h:40
TSI_FAKE_CLIENT_INIT
@ TSI_FAKE_CLIENT_INIT
Definition: fake_transport_security.cc:54
tsi_peer
Definition: transport_security_interface.h:238
grpc_slice_buffer_add
GPRAPI void grpc_slice_buffer_add(grpc_slice_buffer *sb, grpc_slice slice)
Definition: slice/slice_buffer.cc:170
tsi_frame_protector_vtable
Definition: transport_security.h:34
TSI_INCOMPLETE_DATA
@ TSI_INCOMPLETE_DATA
Definition: transport_security_interface.h:36
bytes
uint8 bytes[10]
Definition: bloaty/third_party/protobuf/src/google/protobuf/io/coded_stream_unittest.cc:153
tsi_create_fake_zero_copy_grpc_protector
tsi_zero_copy_grpc_protector * tsi_create_fake_zero_copy_grpc_protector(size_t *max_protected_frame_size)
Definition: fake_transport_security.cc:808
tsi_fake_handshaker
Definition: fake_transport_security.cc:61
tsi_result_to_string
const char * tsi_result_to_string(tsi_result result)
Definition: transport_security.cc:35
fake_zero_copy_grpc_protector_max_frame_size
static tsi_result fake_zero_copy_grpc_protector_max_frame_size(tsi_zero_copy_grpc_protector *self, size_t *max_frame_size)
Definition: fake_transport_security.cc:490
fake_handshaker_get_bytes_to_send_to_peer
static tsi_result fake_handshaker_get_bytes_to_send_to_peer(tsi_handshaker *self, unsigned char *bytes, size_t *bytes_size)
Definition: fake_transport_security.cc:601
alloc.h
tsi_fake_zero_copy_grpc_protector::protected_sb
grpc_slice_buffer protected_sb
Definition: fake_transport_security.cc:81
TSI_INVALID_ARGUMENT
@ TSI_INVALID_ARGUMENT
Definition: transport_security_interface.h:34
tsi_frame_protector::vtable
const tsi_frame_protector_vtable * vtable
Definition: transport_security.h:52
fake_handshaker_result_get_frame_protector_type
static tsi_result fake_handshaker_result_get_frame_protector_type(const tsi_handshaker_result *, tsi_frame_protector_type *frame_protector_type)
Definition: fake_transport_security.cc:531
tsi_fake_handshaker::is_client
int is_client
Definition: fake_transport_security.cc:63
frame
static void frame(frame_handler *handler, unsigned char *payload, size_t payload_length, size_t write_length)
Definition: frame_handler_test.cc:65
tsi_create_fake_frame_protector
tsi_frame_protector * tsi_create_fake_frame_protector(size_t *max_protected_frame_size)
Definition: fake_transport_security.cc:797
grpc_slice_buffer_move_first
GPRAPI void grpc_slice_buffer_move_first(grpc_slice_buffer *src, size_t n, grpc_slice_buffer *dst)
Definition: slice/slice_buffer.cc:348
tsi_zero_copy_grpc_protector_vtable
Definition: transport_security_grpc.h:67
tsi_fake_frame
Definition: fake_transport_security.cc:46
tsi_fake_handshaker::needs_incoming_message
int needs_incoming_message
Definition: fake_transport_security.cc:65
tsi_fake_zero_copy_grpc_protector_next_frame_size
uint32_t tsi_fake_zero_copy_grpc_protector_next_frame_size(const grpc_slice_buffer *protected_slices)
Definition: fake_transport_security.cc:146
fake_protector_protect
static tsi_result fake_protector_protect(tsi_frame_protector *self, const unsigned char *unprotected_bytes, size_t *unprotected_bytes_size, unsigned char *protected_output_frames, size_t *protected_output_frames_size)
Definition: fake_transport_security.cc:261
tsi_handshaker_result
Definition: transport_security.h:121
grpc_slice_buffer_destroy_internal
void grpc_slice_buffer_destroy_internal(grpc_slice_buffer *sb)
Definition: slice/slice_buffer.cc:123
tsi_fake_frame_set_data
static tsi_result tsi_fake_frame_set_data(unsigned char *data, size_t data_size, tsi_fake_frame *frame)
Definition: fake_transport_security.cc:243
fake_handshaker_result
Definition: fake_transport_security.cc:509
tsi_fake_frame::data
unsigned char * data
Definition: fake_transport_security.cc:47
TSI_FRAME_PROTECTOR_NORMAL_OR_ZERO_COPY
@ TSI_FRAME_PROTECTOR_NORMAL_OR_ZERO_COPY
Definition: transport_security_interface.h:83
tsi_fake_frame_protector::max_frame_size
size_t max_frame_size
Definition: fake_transport_security.cc:76
grpc_slice_buffer
Definition: include/grpc/impl/codegen/slice.h:83
tsi_frame_protector
Definition: transport_security.h:51
tsi_zero_copy_grpc_protector
Definition: transport_security_grpc.h:79
fake_protector_destroy
static void fake_protector_destroy(tsi_frame_protector *self)
Definition: fake_transport_security.cc:396
TSI_CERTIFICATE_TYPE_PEER_PROPERTY
#define TSI_CERTIFICATE_TYPE_PEER_PROPERTY
Definition: transport_security_interface.h:223
tsi_fake_frame_protector::base
tsi_frame_protector base
Definition: fake_transport_security.cc:73
tsi_handshaker_result_vtable
Definition: transport_security.h:100
fake_handshaker_result_create
static tsi_result fake_handshaker_result_create(const unsigned char *unused_bytes, size_t unused_bytes_size, tsi_handshaker_result **handshaker_result)
Definition: fake_transport_security.cc:580
TSI_FAKE_SERVER_INIT
@ TSI_FAKE_SERVER_INIT
Definition: fake_transport_security.cc:55
tsi_fake_frame_protector
Definition: fake_transport_security.cc:72
fake_handshaker_result::unused_bytes
unsigned char * unused_bytes
Definition: fake_transport_security.cc:511
fake_transport_security.h
frame_protector_vtable
static const tsi_frame_protector_vtable frame_protector_vtable
Definition: fake_transport_security.cc:404
tsi_peer_destruct
void tsi_peer_destruct(tsi_peer *self)
Definition: transport_security.cc:320
grpc_slice_buffer_reset_and_unref_internal
void grpc_slice_buffer_reset_and_unref_internal(grpc_slice_buffer *sb)
Definition: slice/slice_buffer.cc:238
fake_handshaker_result_extract_peer
static tsi_result fake_handshaker_result_extract_peer(const tsi_handshaker_result *, tsi_peer *peer)
Definition: fake_transport_security.cc:515
TSI_FAKE_SERVER_FINISHED
@ TSI_FAKE_SERVER_FINISHED
Definition: fake_transport_security.cc:57
tsi_fake_handshake_message
tsi_fake_handshake_message
Definition: fake_transport_security.cc:53
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
fake_handshaker_destroy
static void fake_handshaker_destroy(tsi_handshaker *self)
Definition: fake_transport_security.cc:694
tsi_construct_string_peer_property_from_cstring
tsi_result tsi_construct_string_peer_property_from_cstring(const char *name, const char *value, tsi_peer_property *property)
Definition: transport_security.cc:340
offset
voidpf uLong offset
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:142
tsi_construct_peer
tsi_result tsi_construct_peer(size_t property_count, tsi_peer *peer)
Definition: transport_security.cc:359
transport_security_grpc.h
TSI_HANDSHAKE_IN_PROGRESS
@ TSI_HANDSHAKE_IN_PROGRESS
Definition: transport_security_interface.h:43
port_platform.h


grpc
Author(s):
autogenerated on Fri May 16 2025 02:58:22