Index: third_party/grpc/src/core/tsi/transport_security.c |
diff --git a/third_party/grpc/src/core/tsi/transport_security.c b/third_party/grpc/src/core/tsi/transport_security.c |
new file mode 100644 |
index 0000000000000000000000000000000000000000..db219a50a6798a0e0de2f08a76e70381bc088884 |
--- /dev/null |
+++ b/third_party/grpc/src/core/tsi/transport_security.c |
@@ -0,0 +1,284 @@ |
+/* |
+ * |
+ * Copyright 2015, Google Inc. |
+ * All rights reserved. |
+ * |
+ * Redistribution and use in source and binary forms, with or without |
+ * modification, are permitted provided that the following conditions are |
+ * met: |
+ * |
+ * * Redistributions of source code must retain the above copyright |
+ * notice, this list of conditions and the following disclaimer. |
+ * * Redistributions in binary form must reproduce the above |
+ * copyright notice, this list of conditions and the following disclaimer |
+ * in the documentation and/or other materials provided with the |
+ * distribution. |
+ * * Neither the name of Google Inc. nor the names of its |
+ * contributors may be used to endorse or promote products derived from |
+ * this software without specific prior written permission. |
+ * |
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
+ * |
+ */ |
+ |
+#include "src/core/tsi/transport_security.h" |
+ |
+#include <stdlib.h> |
+#include <string.h> |
+ |
+/* --- Tracing. --- */ |
+ |
+int tsi_tracing_enabled = 0; |
+ |
+/* --- Utils. --- */ |
+ |
+char *tsi_strdup(const char *src) { |
+ char *dst; |
+ size_t len; |
+ if (!src) return NULL; |
+ len = strlen(src) + 1; |
+ dst = malloc(len); |
+ if (!dst) return NULL; |
+ memcpy(dst, src, len); |
+ return dst; |
+} |
+ |
+/* --- tsi_result common implementation. --- */ |
+ |
+const char *tsi_result_to_string(tsi_result result) { |
+ switch (result) { |
+ case TSI_OK: |
+ return "TSI_OK"; |
+ case TSI_UNKNOWN_ERROR: |
+ return "TSI_UNKNOWN_ERROR"; |
+ case TSI_INVALID_ARGUMENT: |
+ return "TSI_INVALID_ARGUMENT"; |
+ case TSI_PERMISSION_DENIED: |
+ return "TSI_PERMISSION_DENIED"; |
+ case TSI_INCOMPLETE_DATA: |
+ return "TSI_INCOMPLETE_DATA"; |
+ case TSI_FAILED_PRECONDITION: |
+ return "TSI_FAILED_PRECONDITION"; |
+ case TSI_UNIMPLEMENTED: |
+ return "TSI_UNIMPLEMENTED"; |
+ case TSI_INTERNAL_ERROR: |
+ return "TSI_INTERNAL_ERROR"; |
+ case TSI_DATA_CORRUPTED: |
+ return "TSI_DATA_CORRUPTED"; |
+ case TSI_NOT_FOUND: |
+ return "TSI_NOT_FOUND"; |
+ case TSI_PROTOCOL_FAILURE: |
+ return "TSI_PROTOCOL_FAILURE"; |
+ case TSI_HANDSHAKE_IN_PROGRESS: |
+ return "TSI_HANDSHAKE_IN_PROGRESS"; |
+ case TSI_OUT_OF_RESOURCES: |
+ return "TSI_OUT_OF_RESOURCES"; |
+ default: |
+ return "UNKNOWN"; |
+ } |
+} |
+ |
+/* --- tsi_frame_protector common implementation. --- |
+ |
+ Calls specific implementation after state/input validation. */ |
+ |
+tsi_result tsi_frame_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) { |
+ if (self == NULL || unprotected_bytes == NULL || |
+ unprotected_bytes_size == NULL || protected_output_frames == NULL || |
+ protected_output_frames_size == NULL) { |
+ return TSI_INVALID_ARGUMENT; |
+ } |
+ return self->vtable->protect(self, unprotected_bytes, unprotected_bytes_size, |
+ protected_output_frames, |
+ protected_output_frames_size); |
+} |
+ |
+tsi_result tsi_frame_protector_protect_flush( |
+ tsi_frame_protector *self, unsigned char *protected_output_frames, |
+ size_t *protected_output_frames_size, size_t *still_pending_size) { |
+ if (self == NULL || protected_output_frames == NULL || |
+ protected_output_frames == NULL || still_pending_size == NULL) { |
+ return TSI_INVALID_ARGUMENT; |
+ } |
+ return self->vtable->protect_flush(self, protected_output_frames, |
+ protected_output_frames_size, |
+ still_pending_size); |
+} |
+ |
+tsi_result tsi_frame_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) { |
+ if (self == NULL || protected_frames_bytes == NULL || |
+ protected_frames_bytes_size == NULL || unprotected_bytes == NULL || |
+ unprotected_bytes_size == NULL) { |
+ return TSI_INVALID_ARGUMENT; |
+ } |
+ return self->vtable->unprotect(self, protected_frames_bytes, |
+ protected_frames_bytes_size, unprotected_bytes, |
+ unprotected_bytes_size); |
+} |
+ |
+void tsi_frame_protector_destroy(tsi_frame_protector *self) { |
+ if (self == NULL) return; |
+ self->vtable->destroy(self); |
+} |
+ |
+/* --- tsi_handshaker common implementation. --- |
+ |
+ Calls specific implementation after state/input validation. */ |
+ |
+tsi_result tsi_handshaker_get_bytes_to_send_to_peer(tsi_handshaker *self, |
+ unsigned char *bytes, |
+ size_t *bytes_size) { |
+ if (self == NULL || bytes == NULL || bytes_size == NULL) { |
+ return TSI_INVALID_ARGUMENT; |
+ } |
+ if (self->frame_protector_created) return TSI_FAILED_PRECONDITION; |
+ return self->vtable->get_bytes_to_send_to_peer(self, bytes, bytes_size); |
+} |
+ |
+tsi_result tsi_handshaker_process_bytes_from_peer(tsi_handshaker *self, |
+ const unsigned char *bytes, |
+ size_t *bytes_size) { |
+ if (self == NULL || bytes == NULL || bytes_size == NULL) { |
+ return TSI_INVALID_ARGUMENT; |
+ } |
+ if (self->frame_protector_created) return TSI_FAILED_PRECONDITION; |
+ return self->vtable->process_bytes_from_peer(self, bytes, bytes_size); |
+} |
+ |
+tsi_result tsi_handshaker_get_result(tsi_handshaker *self) { |
+ if (self == NULL) return TSI_INVALID_ARGUMENT; |
+ if (self->frame_protector_created) return TSI_FAILED_PRECONDITION; |
+ return self->vtable->get_result(self); |
+} |
+ |
+tsi_result tsi_handshaker_extract_peer(tsi_handshaker *self, tsi_peer *peer) { |
+ if (self == NULL || peer == NULL) return TSI_INVALID_ARGUMENT; |
+ memset(peer, 0, sizeof(tsi_peer)); |
+ if (self->frame_protector_created) return TSI_FAILED_PRECONDITION; |
+ if (tsi_handshaker_get_result(self) != TSI_OK) { |
+ return TSI_FAILED_PRECONDITION; |
+ } |
+ return self->vtable->extract_peer(self, peer); |
+} |
+ |
+tsi_result tsi_handshaker_create_frame_protector( |
+ tsi_handshaker *self, size_t *max_protected_frame_size, |
+ tsi_frame_protector **protector) { |
+ tsi_result result; |
+ if (self == NULL || protector == NULL) return TSI_INVALID_ARGUMENT; |
+ if (self->frame_protector_created) return TSI_FAILED_PRECONDITION; |
+ if (tsi_handshaker_get_result(self) != TSI_OK) { |
+ return TSI_FAILED_PRECONDITION; |
+ } |
+ result = self->vtable->create_frame_protector(self, max_protected_frame_size, |
+ protector); |
+ if (result == TSI_OK) { |
+ self->frame_protector_created = 1; |
+ } |
+ return result; |
+} |
+ |
+void tsi_handshaker_destroy(tsi_handshaker *self) { |
+ if (self == NULL) return; |
+ self->vtable->destroy(self); |
+} |
+ |
+/* --- tsi_peer implementation. --- */ |
+ |
+tsi_peer_property tsi_init_peer_property(void) { |
+ tsi_peer_property property; |
+ memset(&property, 0, sizeof(tsi_peer_property)); |
+ return property; |
+} |
+ |
+static void tsi_peer_destroy_list_property(tsi_peer_property *children, |
+ size_t child_count) { |
+ size_t i; |
+ for (i = 0; i < child_count; i++) { |
+ tsi_peer_property_destruct(&children[i]); |
+ } |
+ free(children); |
+} |
+ |
+void tsi_peer_property_destruct(tsi_peer_property *property) { |
+ if (property->name != NULL) { |
+ free(property->name); |
+ } |
+ if (property->value.data != NULL) { |
+ free(property->value.data); |
+ } |
+ *property = tsi_init_peer_property(); /* Reset everything to 0. */ |
+} |
+ |
+void tsi_peer_destruct(tsi_peer *self) { |
+ if (self == NULL) return; |
+ if (self->properties != NULL) { |
+ tsi_peer_destroy_list_property(self->properties, self->property_count); |
+ self->properties = NULL; |
+ } |
+ self->property_count = 0; |
+} |
+ |
+tsi_result tsi_construct_allocated_string_peer_property( |
+ const char *name, size_t value_length, tsi_peer_property *property) { |
+ *property = tsi_init_peer_property(); |
+ if (name != NULL) { |
+ property->name = tsi_strdup(name); |
+ if (property->name == NULL) return TSI_OUT_OF_RESOURCES; |
+ } |
+ if (value_length > 0) { |
+ property->value.data = calloc(1, value_length); |
+ if (property->value.data == NULL) { |
+ tsi_peer_property_destruct(property); |
+ return TSI_OUT_OF_RESOURCES; |
+ } |
+ property->value.length = value_length; |
+ } |
+ return TSI_OK; |
+} |
+ |
+tsi_result tsi_construct_string_peer_property_from_cstring( |
+ const char *name, const char *value, tsi_peer_property *property) { |
+ return tsi_construct_string_peer_property(name, value, strlen(value), |
+ property); |
+} |
+ |
+tsi_result tsi_construct_string_peer_property(const char *name, |
+ const char *value, |
+ size_t value_length, |
+ tsi_peer_property *property) { |
+ tsi_result result = tsi_construct_allocated_string_peer_property( |
+ name, value_length, property); |
+ if (result != TSI_OK) return result; |
+ if (value_length > 0) { |
+ memcpy(property->value.data, value, value_length); |
+ } |
+ return TSI_OK; |
+} |
+ |
+tsi_result tsi_construct_peer(size_t property_count, tsi_peer *peer) { |
+ memset(peer, 0, sizeof(tsi_peer)); |
+ if (property_count > 0) { |
+ peer->properties = calloc(property_count, sizeof(tsi_peer_property)); |
+ if (peer->properties == NULL) return TSI_OUT_OF_RESOURCES; |
+ peer->property_count = property_count; |
+ } |
+ return TSI_OK; |
+} |