diff options
Diffstat (limited to 'src/core/lib/tsi')
25 files changed, 0 insertions, 3468 deletions
diff --git a/src/core/lib/tsi/README.md b/src/core/lib/tsi/README.md deleted file mode 100644 index 3ca3c1ef38..0000000000 --- a/src/core/lib/tsi/README.md +++ /dev/null @@ -1,2 +0,0 @@ -# Transport Security Interface -An abstraction library over crypto and auth modules (typically OpenSSL) diff --git a/src/core/lib/tsi/fake_transport_security.c b/src/core/lib/tsi/fake_transport_security.c deleted file mode 100644 index bbe323df3b..0000000000 --- a/src/core/lib/tsi/fake_transport_security.c +++ /dev/null @@ -1,527 +0,0 @@ -/* - * - * 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/lib/tsi/fake_transport_security.h" - -#include <stdlib.h> -#include <string.h> - -#include <grpc/support/alloc.h> -#include <grpc/support/log.h> -#include <grpc/support/port_platform.h> -#include <grpc/support/useful.h> -#include "src/core/lib/tsi/transport_security.h" - -/* --- Constants. ---*/ -#define TSI_FAKE_FRAME_HEADER_SIZE 4 -#define TSI_FAKE_FRAME_INITIAL_ALLOCATED_SIZE 64 -#define TSI_FAKE_DEFAULT_FRAME_SIZE 16384 - -/* --- Structure definitions. ---*/ - -/* a frame is encoded like this: - | size | data | - where the size field value is the size of the size field plus the size of - the data encoded in little endian on 4 bytes. */ -typedef struct { - unsigned char *data; - size_t size; - size_t allocated_size; - size_t offset; - int needs_draining; -} tsi_fake_frame; - -typedef enum { - TSI_FAKE_CLIENT_INIT = 0, - TSI_FAKE_SERVER_INIT = 1, - TSI_FAKE_CLIENT_FINISHED = 2, - TSI_FAKE_SERVER_FINISHED = 3, - TSI_FAKE_HANDSHAKE_MESSAGE_MAX = 4 -} tsi_fake_handshake_message; - -typedef struct { - tsi_handshaker base; - int is_client; - tsi_fake_handshake_message next_message_to_send; - int needs_incoming_message; - tsi_fake_frame incoming; - tsi_fake_frame outgoing; - tsi_result result; -} tsi_fake_handshaker; - -typedef struct { - tsi_frame_protector base; - tsi_fake_frame protect_frame; - tsi_fake_frame unprotect_frame; - size_t max_frame_size; -} tsi_fake_frame_protector; - -/* --- Utils. ---*/ - -static const char *tsi_fake_handshake_message_strings[] = { - "CLIENT_INIT", "SERVER_INIT", "CLIENT_FINISHED", "SERVER_FINISHED"}; - -static const char *tsi_fake_handshake_message_to_string(int msg) { - if (msg < 0 || msg >= TSI_FAKE_HANDSHAKE_MESSAGE_MAX) { - gpr_log(GPR_ERROR, "Invalid message %d", msg); - return "UNKNOWN"; - } - return tsi_fake_handshake_message_strings[msg]; -} - -static tsi_result tsi_fake_handshake_message_from_string( - const char *msg_string, tsi_fake_handshake_message *msg) { - tsi_fake_handshake_message i; - for (i = 0; i < TSI_FAKE_HANDSHAKE_MESSAGE_MAX; i++) { - if (strncmp(msg_string, tsi_fake_handshake_message_strings[i], - strlen(tsi_fake_handshake_message_strings[i])) == 0) { - *msg = i; - return TSI_OK; - } - } - gpr_log(GPR_ERROR, "Invalid handshake message."); - return TSI_DATA_CORRUPTED; -} - -static uint32_t load32_little_endian(const unsigned char *buf) { - return ((uint32_t)(buf[0]) | (uint32_t)(buf[1] << 8) | - (uint32_t)(buf[2] << 16) | (uint32_t)(buf[3] << 24)); -} - -static void store32_little_endian(uint32_t value, unsigned char *buf) { - buf[3] = (unsigned char)((value >> 24) & 0xFF); - buf[2] = (unsigned char)((value >> 16) & 0xFF); - buf[1] = (unsigned char)((value >> 8) & 0xFF); - buf[0] = (unsigned char)((value)&0xFF); -} - -static void tsi_fake_frame_reset(tsi_fake_frame *frame, int needs_draining) { - frame->offset = 0; - frame->needs_draining = needs_draining; - if (!needs_draining) frame->size = 0; -} - -/* Returns 1 if successful, 0 otherwise. */ -static int tsi_fake_frame_ensure_size(tsi_fake_frame *frame) { - if (frame->data == NULL) { - frame->allocated_size = frame->size; - frame->data = gpr_malloc(frame->allocated_size); - if (frame->data == NULL) return 0; - } else if (frame->size > frame->allocated_size) { - unsigned char *new_data = gpr_realloc(frame->data, frame->size); - if (new_data == NULL) { - gpr_free(frame->data); - frame->data = NULL; - return 0; - } - frame->data = new_data; - frame->allocated_size = frame->size; - } - return 1; -} - -/* This method should not be called if frame->needs_framing is not 0. */ -static tsi_result fill_frame_from_bytes(const unsigned char *incoming_bytes, - size_t *incoming_bytes_size, - tsi_fake_frame *frame) { - size_t available_size = *incoming_bytes_size; - size_t to_read_size = 0; - const unsigned char *bytes_cursor = incoming_bytes; - - if (frame->needs_draining) return TSI_INTERNAL_ERROR; - if (frame->data == NULL) { - frame->allocated_size = TSI_FAKE_FRAME_INITIAL_ALLOCATED_SIZE; - frame->data = gpr_malloc(frame->allocated_size); - if (frame->data == NULL) return TSI_OUT_OF_RESOURCES; - } - - if (frame->offset < TSI_FAKE_FRAME_HEADER_SIZE) { - to_read_size = TSI_FAKE_FRAME_HEADER_SIZE - frame->offset; - if (to_read_size > available_size) { - /* Just fill what we can and exit. */ - memcpy(frame->data + frame->offset, bytes_cursor, available_size); - bytes_cursor += available_size; - frame->offset += available_size; - *incoming_bytes_size = (size_t)(bytes_cursor - incoming_bytes); - return TSI_INCOMPLETE_DATA; - } - memcpy(frame->data + frame->offset, bytes_cursor, to_read_size); - bytes_cursor += to_read_size; - frame->offset += to_read_size; - available_size -= to_read_size; - frame->size = load32_little_endian(frame->data); - if (!tsi_fake_frame_ensure_size(frame)) return TSI_OUT_OF_RESOURCES; - } - - to_read_size = frame->size - frame->offset; - if (to_read_size > available_size) { - memcpy(frame->data + frame->offset, bytes_cursor, available_size); - frame->offset += available_size; - bytes_cursor += available_size; - *incoming_bytes_size = (size_t)(bytes_cursor - incoming_bytes); - return TSI_INCOMPLETE_DATA; - } - memcpy(frame->data + frame->offset, bytes_cursor, to_read_size); - bytes_cursor += to_read_size; - *incoming_bytes_size = (size_t)(bytes_cursor - incoming_bytes); - tsi_fake_frame_reset(frame, 1 /* needs_draining */); - return TSI_OK; -} - -/* This method should not be called if frame->needs_framing is 0. */ -static tsi_result drain_frame_to_bytes(unsigned char *outgoing_bytes, - size_t *outgoing_bytes_size, - tsi_fake_frame *frame) { - size_t to_write_size = frame->size - frame->offset; - if (!frame->needs_draining) return TSI_INTERNAL_ERROR; - if (*outgoing_bytes_size < to_write_size) { - memcpy(outgoing_bytes, frame->data + frame->offset, *outgoing_bytes_size); - frame->offset += *outgoing_bytes_size; - return TSI_INCOMPLETE_DATA; - } - memcpy(outgoing_bytes, frame->data + frame->offset, to_write_size); - *outgoing_bytes_size = to_write_size; - tsi_fake_frame_reset(frame, 0 /* needs_draining */); - return TSI_OK; -} - -static tsi_result bytes_to_frame(unsigned char *bytes, size_t bytes_size, - tsi_fake_frame *frame) { - frame->offset = 0; - frame->size = bytes_size + TSI_FAKE_FRAME_HEADER_SIZE; - if (!tsi_fake_frame_ensure_size(frame)) return TSI_OUT_OF_RESOURCES; - store32_little_endian((uint32_t)frame->size, frame->data); - memcpy(frame->data + TSI_FAKE_FRAME_HEADER_SIZE, bytes, bytes_size); - tsi_fake_frame_reset(frame, 1 /* needs draining */); - return TSI_OK; -} - -static void tsi_fake_frame_destruct(tsi_fake_frame *frame) { - if (frame->data != NULL) gpr_free(frame->data); -} - -/* --- tsi_frame_protector methods implementation. ---*/ - -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) { - tsi_result result = TSI_OK; - tsi_fake_frame_protector *impl = (tsi_fake_frame_protector *)self; - unsigned char frame_header[TSI_FAKE_FRAME_HEADER_SIZE]; - tsi_fake_frame *frame = &impl->protect_frame; - size_t saved_output_size = *protected_output_frames_size; - size_t drained_size = 0; - size_t *num_bytes_written = protected_output_frames_size; - *num_bytes_written = 0; - - /* Try to drain first. */ - if (frame->needs_draining) { - drained_size = saved_output_size - *num_bytes_written; - result = - drain_frame_to_bytes(protected_output_frames, &drained_size, frame); - *num_bytes_written += drained_size; - protected_output_frames += drained_size; - if (result != TSI_OK) { - if (result == TSI_INCOMPLETE_DATA) { - *unprotected_bytes_size = 0; - result = TSI_OK; - } - return result; - } - } - - /* Now process the unprotected_bytes. */ - if (frame->needs_draining) return TSI_INTERNAL_ERROR; - if (frame->size == 0) { - /* New frame, create a header. */ - size_t written_in_frame_size = 0; - store32_little_endian((uint32_t)impl->max_frame_size, frame_header); - written_in_frame_size = TSI_FAKE_FRAME_HEADER_SIZE; - result = fill_frame_from_bytes(frame_header, &written_in_frame_size, frame); - if (result != TSI_INCOMPLETE_DATA) { - gpr_log(GPR_ERROR, "fill_frame_from_bytes returned %s", - tsi_result_to_string(result)); - return result; - } - } - result = - fill_frame_from_bytes(unprotected_bytes, unprotected_bytes_size, frame); - if (result != TSI_OK) { - if (result == TSI_INCOMPLETE_DATA) result = TSI_OK; - return result; - } - - /* Try to drain again. */ - if (!frame->needs_draining) return TSI_INTERNAL_ERROR; - if (frame->offset != 0) return TSI_INTERNAL_ERROR; - drained_size = saved_output_size - *num_bytes_written; - result = drain_frame_to_bytes(protected_output_frames, &drained_size, frame); - *num_bytes_written += drained_size; - if (result == TSI_INCOMPLETE_DATA) result = TSI_OK; - return result; -} - -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) { - tsi_result result = TSI_OK; - tsi_fake_frame_protector *impl = (tsi_fake_frame_protector *)self; - tsi_fake_frame *frame = &impl->protect_frame; - if (!frame->needs_draining) { - /* Create a short frame. */ - frame->size = frame->offset; - frame->offset = 0; - frame->needs_draining = 1; - store32_little_endian((uint32_t)frame->size, - frame->data); /* Overwrite header. */ - } - result = drain_frame_to_bytes(protected_output_frames, - protected_output_frames_size, frame); - if (result == TSI_INCOMPLETE_DATA) result = TSI_OK; - *still_pending_size = frame->size - frame->offset; - return result; -} - -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) { - tsi_result result = TSI_OK; - tsi_fake_frame_protector *impl = (tsi_fake_frame_protector *)self; - tsi_fake_frame *frame = &impl->unprotect_frame; - size_t saved_output_size = *unprotected_bytes_size; - size_t drained_size = 0; - size_t *num_bytes_written = unprotected_bytes_size; - *num_bytes_written = 0; - - /* Try to drain first. */ - if (frame->needs_draining) { - /* Go past the header if needed. */ - if (frame->offset == 0) frame->offset = TSI_FAKE_FRAME_HEADER_SIZE; - drained_size = saved_output_size - *num_bytes_written; - result = drain_frame_to_bytes(unprotected_bytes, &drained_size, frame); - unprotected_bytes += drained_size; - *num_bytes_written += drained_size; - if (result != TSI_OK) { - if (result == TSI_INCOMPLETE_DATA) { - *protected_frames_bytes_size = 0; - result = TSI_OK; - } - return result; - } - } - - /* Now process the protected_bytes. */ - if (frame->needs_draining) return TSI_INTERNAL_ERROR; - result = fill_frame_from_bytes(protected_frames_bytes, - protected_frames_bytes_size, frame); - if (result != TSI_OK) { - if (result == TSI_INCOMPLETE_DATA) result = TSI_OK; - return result; - } - - /* Try to drain again. */ - if (!frame->needs_draining) return TSI_INTERNAL_ERROR; - if (frame->offset != 0) return TSI_INTERNAL_ERROR; - frame->offset = TSI_FAKE_FRAME_HEADER_SIZE; /* Go past the header. */ - drained_size = saved_output_size - *num_bytes_written; - result = drain_frame_to_bytes(unprotected_bytes, &drained_size, frame); - *num_bytes_written += drained_size; - if (result == TSI_INCOMPLETE_DATA) result = TSI_OK; - return result; -} - -static void fake_protector_destroy(tsi_frame_protector *self) { - tsi_fake_frame_protector *impl = (tsi_fake_frame_protector *)self; - tsi_fake_frame_destruct(&impl->protect_frame); - tsi_fake_frame_destruct(&impl->unprotect_frame); - gpr_free(self); -} - -static const tsi_frame_protector_vtable frame_protector_vtable = { - fake_protector_protect, fake_protector_protect_flush, - fake_protector_unprotect, fake_protector_destroy, -}; - -/* --- tsi_handshaker methods implementation. ---*/ - -static tsi_result fake_handshaker_get_bytes_to_send_to_peer( - tsi_handshaker *self, unsigned char *bytes, size_t *bytes_size) { - tsi_fake_handshaker *impl = (tsi_fake_handshaker *)self; - tsi_result result = TSI_OK; - if (impl->needs_incoming_message || impl->result == TSI_OK) { - *bytes_size = 0; - return TSI_OK; - } - if (!impl->outgoing.needs_draining) { - tsi_fake_handshake_message next_message_to_send = - impl->next_message_to_send + 2; - const char *msg_string = - tsi_fake_handshake_message_to_string(impl->next_message_to_send); - result = bytes_to_frame((unsigned char *)msg_string, strlen(msg_string), - &impl->outgoing); - if (result != TSI_OK) return result; - if (next_message_to_send > TSI_FAKE_HANDSHAKE_MESSAGE_MAX) { - next_message_to_send = TSI_FAKE_HANDSHAKE_MESSAGE_MAX; - } - if (tsi_tracing_enabled) { - gpr_log(GPR_INFO, "%s prepared %s.", - impl->is_client ? "Client" : "Server", - tsi_fake_handshake_message_to_string(impl->next_message_to_send)); - } - impl->next_message_to_send = next_message_to_send; - } - result = drain_frame_to_bytes(bytes, bytes_size, &impl->outgoing); - if (result != TSI_OK) return result; - if (!impl->is_client && - impl->next_message_to_send == TSI_FAKE_HANDSHAKE_MESSAGE_MAX) { - /* We're done. */ - if (tsi_tracing_enabled) { - gpr_log(GPR_INFO, "Server is done."); - } - impl->result = TSI_OK; - } else { - impl->needs_incoming_message = 1; - } - return TSI_OK; -} - -static tsi_result fake_handshaker_process_bytes_from_peer( - tsi_handshaker *self, const unsigned char *bytes, size_t *bytes_size) { - tsi_result result = TSI_OK; - tsi_fake_handshaker *impl = (tsi_fake_handshaker *)self; - tsi_fake_handshake_message expected_msg = impl->next_message_to_send - 1; - tsi_fake_handshake_message received_msg; - - if (!impl->needs_incoming_message || impl->result == TSI_OK) { - *bytes_size = 0; - return TSI_OK; - } - result = fill_frame_from_bytes(bytes, bytes_size, &impl->incoming); - if (result != TSI_OK) return result; - - /* We now have a complete frame. */ - result = tsi_fake_handshake_message_from_string( - (const char *)impl->incoming.data + TSI_FAKE_FRAME_HEADER_SIZE, - &received_msg); - if (result != TSI_OK) { - impl->result = result; - return result; - } - if (received_msg != expected_msg) { - gpr_log(GPR_ERROR, "Invalid received message (%s instead of %s)", - tsi_fake_handshake_message_to_string(received_msg), - tsi_fake_handshake_message_to_string(expected_msg)); - } - if (tsi_tracing_enabled) { - gpr_log(GPR_INFO, "%s received %s.", impl->is_client ? "Client" : "Server", - tsi_fake_handshake_message_to_string(received_msg)); - } - tsi_fake_frame_reset(&impl->incoming, 0 /* needs_draining */); - impl->needs_incoming_message = 0; - if (impl->next_message_to_send == TSI_FAKE_HANDSHAKE_MESSAGE_MAX) { - /* We're done. */ - if (tsi_tracing_enabled) { - gpr_log(GPR_INFO, "%s is done.", impl->is_client ? "Client" : "Server"); - } - impl->result = TSI_OK; - } - return TSI_OK; -} - -static tsi_result fake_handshaker_get_result(tsi_handshaker *self) { - tsi_fake_handshaker *impl = (tsi_fake_handshaker *)self; - return impl->result; -} - -static tsi_result fake_handshaker_extract_peer(tsi_handshaker *self, - tsi_peer *peer) { - tsi_result result = tsi_construct_peer(1, peer); - if (result != TSI_OK) return result; - result = tsi_construct_string_peer_property_from_cstring( - TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_FAKE_CERTIFICATE_TYPE, - &peer->properties[0]); - if (result != TSI_OK) tsi_peer_destruct(peer); - return result; -} - -static tsi_result fake_handshaker_create_frame_protector( - tsi_handshaker *self, size_t *max_protected_frame_size, - tsi_frame_protector **protector) { - *protector = tsi_create_fake_protector(max_protected_frame_size); - if (*protector == NULL) return TSI_OUT_OF_RESOURCES; - return TSI_OK; -} - -static void fake_handshaker_destroy(tsi_handshaker *self) { - tsi_fake_handshaker *impl = (tsi_fake_handshaker *)self; - tsi_fake_frame_destruct(&impl->incoming); - tsi_fake_frame_destruct(&impl->outgoing); - gpr_free(self); -} - -static const tsi_handshaker_vtable handshaker_vtable = { - fake_handshaker_get_bytes_to_send_to_peer, - fake_handshaker_process_bytes_from_peer, - fake_handshaker_get_result, - fake_handshaker_extract_peer, - fake_handshaker_create_frame_protector, - fake_handshaker_destroy, -}; - -tsi_handshaker *tsi_create_fake_handshaker(int is_client) { - tsi_fake_handshaker *impl = gpr_zalloc(sizeof(*impl)); - impl->base.vtable = &handshaker_vtable; - impl->is_client = is_client; - impl->result = TSI_HANDSHAKE_IN_PROGRESS; - if (is_client) { - impl->needs_incoming_message = 0; - impl->next_message_to_send = TSI_FAKE_CLIENT_INIT; - } else { - impl->needs_incoming_message = 1; - impl->next_message_to_send = TSI_FAKE_SERVER_INIT; - } - return &impl->base; -} - -tsi_frame_protector *tsi_create_fake_protector( - size_t *max_protected_frame_size) { - tsi_fake_frame_protector *impl = gpr_zalloc(sizeof(*impl)); - impl->max_frame_size = (max_protected_frame_size == NULL) - ? TSI_FAKE_DEFAULT_FRAME_SIZE - : *max_protected_frame_size; - impl->base.vtable = &frame_protector_vtable; - return &impl->base; -} diff --git a/src/core/lib/tsi/fake_transport_security.h b/src/core/lib/tsi/fake_transport_security.h deleted file mode 100644 index 54a9469b58..0000000000 --- a/src/core/lib/tsi/fake_transport_security.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * - * 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. - * - */ - -#ifndef GRPC_CORE_LIB_TSI_FAKE_TRANSPORT_SECURITY_H -#define GRPC_CORE_LIB_TSI_FAKE_TRANSPORT_SECURITY_H - -#include "src/core/lib/tsi/transport_security_interface.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* Value for the TSI_CERTIFICATE_TYPE_PEER_PROPERTY property for FAKE certs. */ -#define TSI_FAKE_CERTIFICATE_TYPE "FAKE" - -/* Creates a fake handshaker that will create a fake frame protector. - - No cryptography is performed in these objects. They just simulate handshake - messages going back and forth for the handshaker and do some framing on - cleartext data for the protector. */ -tsi_handshaker *tsi_create_fake_handshaker(int is_client); - -/* Creates a protector directly without going through the handshake phase. */ -tsi_frame_protector *tsi_create_fake_protector( - size_t *max_protected_frame_size); - -#ifdef __cplusplus -} -#endif - -#endif /* GRPC_CORE_LIB_TSI_FAKE_TRANSPORT_SECURITY_H */ diff --git a/src/core/lib/tsi/ssl_transport_security.c b/src/core/lib/tsi/ssl_transport_security.c deleted file mode 100644 index 53aabdb926..0000000000 --- a/src/core/lib/tsi/ssl_transport_security.c +++ /dev/null @@ -1,1572 +0,0 @@ -/* - * - * 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/lib/tsi/ssl_transport_security.h" - -#include <grpc/support/port_platform.h> - -#include <limits.h> -#include <string.h> - -/* TODO(jboeuf): refactor inet_ntop into a portability header. */ -/* Note: for whomever reads this and tries to refactor this, this - can't be in grpc, it has to be in gpr. */ -#ifdef GPR_WINDOWS -#include <ws2tcpip.h> -#else -#include <arpa/inet.h> -#endif - -#include <grpc/support/alloc.h> -#include <grpc/support/log.h> -#include <grpc/support/sync.h> -#include <grpc/support/thd.h> -#include <grpc/support/useful.h> - -#include <openssl/bio.h> -#include <openssl/crypto.h> /* For OPENSSL_free */ -#include <openssl/err.h> -#include <openssl/ssl.h> -#include <openssl/x509.h> -#include <openssl/x509v3.h> - -#include "src/core/lib/tsi/ssl_types.h" -#include "src/core/lib/tsi/transport_security.h" - -/* --- Constants. ---*/ - -#define TSI_SSL_MAX_PROTECTED_FRAME_SIZE_UPPER_BOUND 16384 -#define TSI_SSL_MAX_PROTECTED_FRAME_SIZE_LOWER_BOUND 1024 - -/* Putting a macro like this and littering the source file with #if is really - bad practice. - TODO(jboeuf): refactor all the #if / #endif in a separate module. */ -#ifndef TSI_OPENSSL_ALPN_SUPPORT -#define TSI_OPENSSL_ALPN_SUPPORT 1 -#endif - -/* TODO(jboeuf): I have not found a way to get this number dynamically from the - SSL structure. This is what we would ultimately want though... */ -#define TSI_SSL_MAX_PROTECTION_OVERHEAD 100 - -/* --- Structure definitions. ---*/ - -struct tsi_ssl_handshaker_factory { - tsi_result (*create_handshaker)(tsi_ssl_handshaker_factory *self, - const char *server_name_indication, - tsi_handshaker **handshaker); - void (*destroy)(tsi_ssl_handshaker_factory *self); -}; - -typedef struct { - tsi_ssl_handshaker_factory base; - SSL_CTX *ssl_context; - unsigned char *alpn_protocol_list; - size_t alpn_protocol_list_length; -} tsi_ssl_client_handshaker_factory; - -typedef struct { - tsi_ssl_handshaker_factory base; - - /* Several contexts to support SNI. - The tsi_peer array contains the subject names of the server certificates - associated with the contexts at the same index. */ - SSL_CTX **ssl_contexts; - tsi_peer *ssl_context_x509_subject_names; - size_t ssl_context_count; - unsigned char *alpn_protocol_list; - size_t alpn_protocol_list_length; -} tsi_ssl_server_handshaker_factory; - -typedef struct { - tsi_handshaker base; - SSL *ssl; - BIO *into_ssl; - BIO *from_ssl; - tsi_result result; -} tsi_ssl_handshaker; - -typedef struct { - tsi_frame_protector base; - SSL *ssl; - BIO *into_ssl; - BIO *from_ssl; - unsigned char *buffer; - size_t buffer_size; - size_t buffer_offset; -} tsi_ssl_frame_protector; - -/* --- Library Initialization. ---*/ - -static gpr_once init_openssl_once = GPR_ONCE_INIT; -static gpr_mu *openssl_mutexes = NULL; - -static void openssl_locking_cb(int mode, int type, const char *file, int line) { - if (mode & CRYPTO_LOCK) { - gpr_mu_lock(&openssl_mutexes[type]); - } else { - gpr_mu_unlock(&openssl_mutexes[type]); - } -} - -static unsigned long openssl_thread_id_cb(void) { - return (unsigned long)gpr_thd_currentid(); -} - -static void init_openssl(void) { - int i; - int num_locks; - SSL_library_init(); - SSL_load_error_strings(); - OpenSSL_add_all_algorithms(); - num_locks = CRYPTO_num_locks(); - GPR_ASSERT(num_locks > 0); - openssl_mutexes = gpr_malloc((size_t)num_locks * sizeof(gpr_mu)); - for (i = 0; i < CRYPTO_num_locks(); i++) { - gpr_mu_init(&openssl_mutexes[i]); - } - CRYPTO_set_locking_callback(openssl_locking_cb); - CRYPTO_set_id_callback(openssl_thread_id_cb); -} - -/* --- Ssl utils. ---*/ - -static const char *ssl_error_string(int error) { - switch (error) { - case SSL_ERROR_NONE: - return "SSL_ERROR_NONE"; - case SSL_ERROR_ZERO_RETURN: - return "SSL_ERROR_ZERO_RETURN"; - case SSL_ERROR_WANT_READ: - return "SSL_ERROR_WANT_READ"; - case SSL_ERROR_WANT_WRITE: - return "SSL_ERROR_WANT_WRITE"; - case SSL_ERROR_WANT_CONNECT: - return "SSL_ERROR_WANT_CONNECT"; - case SSL_ERROR_WANT_ACCEPT: - return "SSL_ERROR_WANT_ACCEPT"; - case SSL_ERROR_WANT_X509_LOOKUP: - return "SSL_ERROR_WANT_X509_LOOKUP"; - case SSL_ERROR_SYSCALL: - return "SSL_ERROR_SYSCALL"; - case SSL_ERROR_SSL: - return "SSL_ERROR_SSL"; - default: - return "Unknown error"; - } -} - -/* TODO(jboeuf): Remove when we are past the debugging phase with this code. */ -static void ssl_log_where_info(const SSL *ssl, int where, int flag, - const char *msg) { - if ((where & flag) && tsi_tracing_enabled) { - gpr_log(GPR_INFO, "%20.20s - %30.30s - %5.10s", msg, - SSL_state_string_long(ssl), SSL_state_string(ssl)); - } -} - -/* Used for debugging. TODO(jboeuf): Remove when code is mature enough. */ -static void ssl_info_callback(const SSL *ssl, int where, int ret) { - if (ret == 0) { - gpr_log(GPR_ERROR, "ssl_info_callback: error occured.\n"); - return; - } - - ssl_log_where_info(ssl, where, SSL_CB_LOOP, "LOOP"); - ssl_log_where_info(ssl, where, SSL_CB_HANDSHAKE_START, "HANDSHAKE START"); - ssl_log_where_info(ssl, where, SSL_CB_HANDSHAKE_DONE, "HANDSHAKE DONE"); -} - -/* Returns 1 if name looks like an IP address, 0 otherwise. - This is a very rough heuristic, and only handles IPv6 in hexadecimal form. */ -static int looks_like_ip_address(const char *name) { - size_t i; - size_t dot_count = 0; - size_t num_size = 0; - for (i = 0; i < strlen(name); i++) { - if (name[i] == ':') { - /* IPv6 Address in hexadecimal form, : is not allowed in DNS names. */ - return 1; - } - if (name[i] >= '0' && name[i] <= '9') { - if (num_size > 3) return 0; - num_size++; - } else if (name[i] == '.') { - if (dot_count > 3 || num_size == 0) return 0; - dot_count++; - num_size = 0; - } else { - return 0; - } - } - if (dot_count < 3 || num_size == 0) return 0; - return 1; -} - -/* Gets the subject CN from an X509 cert. */ -static tsi_result ssl_get_x509_common_name(X509 *cert, unsigned char **utf8, - size_t *utf8_size) { - int common_name_index = -1; - X509_NAME_ENTRY *common_name_entry = NULL; - ASN1_STRING *common_name_asn1 = NULL; - X509_NAME *subject_name = X509_get_subject_name(cert); - int utf8_returned_size = 0; - if (subject_name == NULL) { - gpr_log(GPR_ERROR, "Could not get subject name from certificate."); - return TSI_NOT_FOUND; - } - common_name_index = - X509_NAME_get_index_by_NID(subject_name, NID_commonName, -1); - if (common_name_index == -1) { - gpr_log(GPR_ERROR, - "Could not get common name of subject from certificate."); - return TSI_NOT_FOUND; - } - common_name_entry = X509_NAME_get_entry(subject_name, common_name_index); - if (common_name_entry == NULL) { - gpr_log(GPR_ERROR, "Could not get common name entry from certificate."); - return TSI_INTERNAL_ERROR; - } - common_name_asn1 = X509_NAME_ENTRY_get_data(common_name_entry); - if (common_name_asn1 == NULL) { - gpr_log(GPR_ERROR, - "Could not get common name entry asn1 from certificate."); - return TSI_INTERNAL_ERROR; - } - utf8_returned_size = ASN1_STRING_to_UTF8(utf8, common_name_asn1); - if (utf8_returned_size < 0) { - gpr_log(GPR_ERROR, "Could not extract utf8 from asn1 string."); - return TSI_OUT_OF_RESOURCES; - } - *utf8_size = (size_t)utf8_returned_size; - return TSI_OK; -} - -/* Gets the subject CN of an X509 cert as a tsi_peer_property. */ -static tsi_result peer_property_from_x509_common_name( - X509 *cert, tsi_peer_property *property) { - unsigned char *common_name; - size_t common_name_size; - tsi_result result = - ssl_get_x509_common_name(cert, &common_name, &common_name_size); - if (result != TSI_OK) { - if (result == TSI_NOT_FOUND) { - common_name = NULL; - common_name_size = 0; - } else { - return result; - } - } - result = tsi_construct_string_peer_property( - TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY, - common_name == NULL ? "" : (const char *)common_name, common_name_size, - property); - OPENSSL_free(common_name); - return result; -} - -/* Gets the X509 cert in PEM format as a tsi_peer_property. */ -static tsi_result add_pem_certificate(X509 *cert, tsi_peer_property *property) { - BIO *bio = BIO_new(BIO_s_mem()); - if (!PEM_write_bio_X509(bio, cert)) { - BIO_free(bio); - return TSI_INTERNAL_ERROR; - } - char *contents; - long len = BIO_get_mem_data(bio, &contents); - if (len <= 0) { - BIO_free(bio); - return TSI_INTERNAL_ERROR; - } - tsi_result result = tsi_construct_string_peer_property( - TSI_X509_PEM_CERT_PROPERTY, (const char *)contents, (size_t)len, - property); - BIO_free(bio); - return result; -} - -/* Gets the subject SANs from an X509 cert as a tsi_peer_property. */ -static tsi_result add_subject_alt_names_properties_to_peer( - tsi_peer *peer, GENERAL_NAMES *subject_alt_names, - size_t subject_alt_name_count) { - size_t i; - tsi_result result = TSI_OK; - - /* Reset for DNS entries filtering. */ - peer->property_count -= subject_alt_name_count; - - for (i = 0; i < subject_alt_name_count; i++) { - GENERAL_NAME *subject_alt_name = - sk_GENERAL_NAME_value(subject_alt_names, TSI_SIZE_AS_SIZE(i)); - /* Filter out the non-dns entries names. */ - if (subject_alt_name->type == GEN_DNS) { - unsigned char *name = NULL; - int name_size; - name_size = ASN1_STRING_to_UTF8(&name, subject_alt_name->d.dNSName); - if (name_size < 0) { - gpr_log(GPR_ERROR, "Could not get utf8 from asn1 string."); - result = TSI_INTERNAL_ERROR; - break; - } - result = tsi_construct_string_peer_property( - TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY, (const char *)name, - (size_t)name_size, &peer->properties[peer->property_count++]); - OPENSSL_free(name); - } else if (subject_alt_name->type == GEN_IPADD) { - char ntop_buf[INET6_ADDRSTRLEN]; - int af; - - if (subject_alt_name->d.iPAddress->length == 4) { - af = AF_INET; - } else if (subject_alt_name->d.iPAddress->length == 16) { - af = AF_INET6; - } else { - gpr_log(GPR_ERROR, "SAN IP Address contained invalid IP"); - result = TSI_INTERNAL_ERROR; - break; - } - const char *name = inet_ntop(af, subject_alt_name->d.iPAddress->data, - ntop_buf, INET6_ADDRSTRLEN); - if (name == NULL) { - gpr_log(GPR_ERROR, "Could not get IP string from asn1 octet."); - result = TSI_INTERNAL_ERROR; - break; - } - - result = tsi_construct_string_peer_property_from_cstring( - TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY, name, - &peer->properties[peer->property_count++]); - } - if (result != TSI_OK) break; - } - return result; -} - -/* Gets information about the peer's X509 cert as a tsi_peer object. */ -static tsi_result peer_from_x509(X509 *cert, int include_certificate_type, - tsi_peer *peer) { - /* TODO(jboeuf): Maybe add more properties. */ - GENERAL_NAMES *subject_alt_names = - X509_get_ext_d2i(cert, NID_subject_alt_name, 0, 0); - int subject_alt_name_count = (subject_alt_names != NULL) - ? (int)sk_GENERAL_NAME_num(subject_alt_names) - : 0; - size_t property_count; - tsi_result result; - GPR_ASSERT(subject_alt_name_count >= 0); - property_count = (include_certificate_type ? (size_t)1 : 0) + - 2 /* common name, certificate */ + - (size_t)subject_alt_name_count; - result = tsi_construct_peer(property_count, peer); - if (result != TSI_OK) return result; - do { - if (include_certificate_type) { - result = tsi_construct_string_peer_property_from_cstring( - TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_X509_CERTIFICATE_TYPE, - &peer->properties[0]); - if (result != TSI_OK) break; - } - result = peer_property_from_x509_common_name( - cert, &peer->properties[include_certificate_type ? 1 : 0]); - if (result != TSI_OK) break; - - result = add_pem_certificate( - cert, &peer->properties[include_certificate_type ? 2 : 1]); - if (result != TSI_OK) break; - - if (subject_alt_name_count != 0) { - result = add_subject_alt_names_properties_to_peer( - peer, subject_alt_names, (size_t)subject_alt_name_count); - if (result != TSI_OK) break; - } - } while (0); - - if (subject_alt_names != NULL) { - sk_GENERAL_NAME_pop_free(subject_alt_names, GENERAL_NAME_free); - } - if (result != TSI_OK) tsi_peer_destruct(peer); - return result; -} - -/* Logs the SSL error stack. */ -static void log_ssl_error_stack(void) { - unsigned long err; - while ((err = ERR_get_error()) != 0) { - char details[256]; - ERR_error_string_n((uint32_t)err, details, sizeof(details)); - gpr_log(GPR_ERROR, "%s", details); - } -} - -/* Performs an SSL_read and handle errors. */ -static tsi_result do_ssl_read(SSL *ssl, unsigned char *unprotected_bytes, - size_t *unprotected_bytes_size) { - int read_from_ssl; - GPR_ASSERT(*unprotected_bytes_size <= INT_MAX); - read_from_ssl = - SSL_read(ssl, unprotected_bytes, (int)*unprotected_bytes_size); - if (read_from_ssl == 0) { - gpr_log(GPR_ERROR, "SSL_read returned 0 unexpectedly."); - return TSI_INTERNAL_ERROR; - } - if (read_from_ssl < 0) { - read_from_ssl = SSL_get_error(ssl, read_from_ssl); - switch (read_from_ssl) { - case SSL_ERROR_WANT_READ: - /* We need more data to finish the frame. */ - *unprotected_bytes_size = 0; - return TSI_OK; - case SSL_ERROR_WANT_WRITE: - gpr_log( - GPR_ERROR, - "Peer tried to renegotiate SSL connection. This is unsupported."); - return TSI_UNIMPLEMENTED; - case SSL_ERROR_SSL: - gpr_log(GPR_ERROR, "Corruption detected."); - log_ssl_error_stack(); - return TSI_DATA_CORRUPTED; - default: - gpr_log(GPR_ERROR, "SSL_read failed with error %s.", - ssl_error_string(read_from_ssl)); - return TSI_PROTOCOL_FAILURE; - } - } - *unprotected_bytes_size = (size_t)read_from_ssl; - return TSI_OK; -} - -/* Performs an SSL_write and handle errors. */ -static tsi_result do_ssl_write(SSL *ssl, unsigned char *unprotected_bytes, - size_t unprotected_bytes_size) { - int ssl_write_result; - GPR_ASSERT(unprotected_bytes_size <= INT_MAX); - ssl_write_result = - SSL_write(ssl, unprotected_bytes, (int)unprotected_bytes_size); - if (ssl_write_result < 0) { - ssl_write_result = SSL_get_error(ssl, ssl_write_result); - if (ssl_write_result == SSL_ERROR_WANT_READ) { - gpr_log(GPR_ERROR, - "Peer tried to renegotiate SSL connection. This is unsupported."); - return TSI_UNIMPLEMENTED; - } else { - gpr_log(GPR_ERROR, "SSL_write failed with error %s.", - ssl_error_string(ssl_write_result)); - return TSI_INTERNAL_ERROR; - } - } - return TSI_OK; -} - -/* Loads an in-memory PEM certificate chain into the SSL context. */ -static tsi_result ssl_ctx_use_certificate_chain( - SSL_CTX *context, const unsigned char *pem_cert_chain, - size_t pem_cert_chain_size) { - tsi_result result = TSI_OK; - X509 *certificate = NULL; - BIO *pem; - GPR_ASSERT(pem_cert_chain_size <= INT_MAX); - pem = BIO_new_mem_buf((void *)pem_cert_chain, (int)pem_cert_chain_size); - if (pem == NULL) return TSI_OUT_OF_RESOURCES; - - do { - certificate = PEM_read_bio_X509_AUX(pem, NULL, NULL, ""); - if (certificate == NULL) { - result = TSI_INVALID_ARGUMENT; - break; - } - if (!SSL_CTX_use_certificate(context, certificate)) { - result = TSI_INVALID_ARGUMENT; - break; - } - while (1) { - X509 *certificate_authority = PEM_read_bio_X509(pem, NULL, NULL, ""); - if (certificate_authority == NULL) { - ERR_clear_error(); - break; /* Done reading. */ - } - if (!SSL_CTX_add_extra_chain_cert(context, certificate_authority)) { - X509_free(certificate_authority); - result = TSI_INVALID_ARGUMENT; - break; - } - /* We don't need to free certificate_authority as its ownership has been - transfered to the context. That is not the case for certificate though. - */ - } - } while (0); - - if (certificate != NULL) X509_free(certificate); - BIO_free(pem); - return result; -} - -/* Loads an in-memory PEM private key into the SSL context. */ -static tsi_result ssl_ctx_use_private_key(SSL_CTX *context, - const unsigned char *pem_key, - size_t pem_key_size) { - tsi_result result = TSI_OK; - EVP_PKEY *private_key = NULL; - BIO *pem; - GPR_ASSERT(pem_key_size <= INT_MAX); - pem = BIO_new_mem_buf((void *)pem_key, (int)pem_key_size); - if (pem == NULL) return TSI_OUT_OF_RESOURCES; - do { - private_key = PEM_read_bio_PrivateKey(pem, NULL, NULL, ""); - if (private_key == NULL) { - result = TSI_INVALID_ARGUMENT; - break; - } - if (!SSL_CTX_use_PrivateKey(context, private_key)) { - result = TSI_INVALID_ARGUMENT; - break; - } - } while (0); - if (private_key != NULL) EVP_PKEY_free(private_key); - BIO_free(pem); - return result; -} - -/* Loads in-memory PEM verification certs into the SSL context and optionally - returns the verification cert names (root_names can be NULL). */ -static tsi_result ssl_ctx_load_verification_certs( - SSL_CTX *context, const unsigned char *pem_roots, size_t pem_roots_size, - STACK_OF(X509_NAME) * *root_names) { - tsi_result result = TSI_OK; - size_t num_roots = 0; - X509 *root = NULL; - X509_NAME *root_name = NULL; - BIO *pem; - X509_STORE *root_store; - GPR_ASSERT(pem_roots_size <= INT_MAX); - pem = BIO_new_mem_buf((void *)pem_roots, (int)pem_roots_size); - root_store = SSL_CTX_get_cert_store(context); - if (root_store == NULL) return TSI_INVALID_ARGUMENT; - if (pem == NULL) return TSI_OUT_OF_RESOURCES; - if (root_names != NULL) { - *root_names = sk_X509_NAME_new_null(); - if (*root_names == NULL) return TSI_OUT_OF_RESOURCES; - } - - while (1) { - root = PEM_read_bio_X509_AUX(pem, NULL, NULL, ""); - if (root == NULL) { - ERR_clear_error(); - break; /* We're at the end of stream. */ - } - if (root_names != NULL) { - root_name = X509_get_subject_name(root); - if (root_name == NULL) { - gpr_log(GPR_ERROR, "Could not get name from root certificate."); - result = TSI_INVALID_ARGUMENT; - break; - } - root_name = X509_NAME_dup(root_name); - if (root_name == NULL) { - result = TSI_OUT_OF_RESOURCES; - break; - } - sk_X509_NAME_push(*root_names, root_name); - root_name = NULL; - } - if (!X509_STORE_add_cert(root_store, root)) { - gpr_log(GPR_ERROR, "Could not add root certificate to ssl context."); - result = TSI_INTERNAL_ERROR; - break; - } - X509_free(root); - num_roots++; - } - - if (num_roots == 0) { - gpr_log(GPR_ERROR, "Could not load any root certificate."); - result = TSI_INVALID_ARGUMENT; - } - - if (result != TSI_OK) { - if (root != NULL) X509_free(root); - if (root_names != NULL) { - sk_X509_NAME_pop_free(*root_names, X509_NAME_free); - *root_names = NULL; - if (root_name != NULL) X509_NAME_free(root_name); - } - } - BIO_free(pem); - return result; -} - -/* Populates the SSL context with a private key and a cert chain, and sets the - cipher list and the ephemeral ECDH key. */ -static tsi_result populate_ssl_context( - SSL_CTX *context, const unsigned char *pem_private_key, - size_t pem_private_key_size, const unsigned char *pem_certificate_chain, - size_t pem_certificate_chain_size, const char *cipher_list) { - tsi_result result = TSI_OK; - if (pem_certificate_chain != NULL) { - result = ssl_ctx_use_certificate_chain(context, pem_certificate_chain, - pem_certificate_chain_size); - if (result != TSI_OK) { - gpr_log(GPR_ERROR, "Invalid cert chain file."); - return result; - } - } - if (pem_private_key != NULL) { - result = - ssl_ctx_use_private_key(context, pem_private_key, pem_private_key_size); - if (result != TSI_OK || !SSL_CTX_check_private_key(context)) { - gpr_log(GPR_ERROR, "Invalid private key."); - return result != TSI_OK ? result : TSI_INVALID_ARGUMENT; - } - } - if ((cipher_list != NULL) && !SSL_CTX_set_cipher_list(context, cipher_list)) { - gpr_log(GPR_ERROR, "Invalid cipher list: %s.", cipher_list); - return TSI_INVALID_ARGUMENT; - } - { - EC_KEY *ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); - if (!SSL_CTX_set_tmp_ecdh(context, ecdh)) { - gpr_log(GPR_ERROR, "Could not set ephemeral ECDH key."); - EC_KEY_free(ecdh); - return TSI_INTERNAL_ERROR; - } - SSL_CTX_set_options(context, SSL_OP_SINGLE_ECDH_USE); - EC_KEY_free(ecdh); - } - return TSI_OK; -} - -/* Extracts the CN and the SANs from an X509 cert as a peer object. */ -static tsi_result extract_x509_subject_names_from_pem_cert( - const unsigned char *pem_cert, size_t pem_cert_size, tsi_peer *peer) { - tsi_result result = TSI_OK; - X509 *cert = NULL; - BIO *pem; - GPR_ASSERT(pem_cert_size <= INT_MAX); - pem = BIO_new_mem_buf((void *)pem_cert, (int)pem_cert_size); - if (pem == NULL) return TSI_OUT_OF_RESOURCES; - - cert = PEM_read_bio_X509(pem, NULL, NULL, ""); - if (cert == NULL) { - gpr_log(GPR_ERROR, "Invalid certificate"); - result = TSI_INVALID_ARGUMENT; - } else { - result = peer_from_x509(cert, 0, peer); - } - if (cert != NULL) X509_free(cert); - BIO_free(pem); - return result; -} - -/* Builds the alpn protocol name list according to rfc 7301. */ -static tsi_result build_alpn_protocol_name_list( - const unsigned char **alpn_protocols, - const unsigned char *alpn_protocols_lengths, uint16_t num_alpn_protocols, - unsigned char **protocol_name_list, size_t *protocol_name_list_length) { - uint16_t i; - unsigned char *current; - *protocol_name_list = NULL; - *protocol_name_list_length = 0; - if (num_alpn_protocols == 0) return TSI_INVALID_ARGUMENT; - for (i = 0; i < num_alpn_protocols; i++) { - if (alpn_protocols_lengths[i] == 0) { - gpr_log(GPR_ERROR, "Invalid 0-length protocol name."); - return TSI_INVALID_ARGUMENT; - } - *protocol_name_list_length += (size_t)alpn_protocols_lengths[i] + 1; - } - *protocol_name_list = gpr_malloc(*protocol_name_list_length); - if (*protocol_name_list == NULL) return TSI_OUT_OF_RESOURCES; - current = *protocol_name_list; - for (i = 0; i < num_alpn_protocols; i++) { - *(current++) = alpn_protocols_lengths[i]; - memcpy(current, alpn_protocols[i], alpn_protocols_lengths[i]); - current += alpn_protocols_lengths[i]; - } - /* Safety check. */ - if ((current < *protocol_name_list) || - ((uintptr_t)(current - *protocol_name_list) != - *protocol_name_list_length)) { - return TSI_INTERNAL_ERROR; - } - return TSI_OK; -} - -// The verification callback is used for clients that don't really care about -// the server's certificate, but we need to pull it anyway, in case a higher -// layer wants to look at it. In this case the verification may fail, but -// we don't really care. -static int NullVerifyCallback(int preverify_ok, X509_STORE_CTX *ctx) { - return 1; -} - -/* --- tsi_frame_protector methods implementation. ---*/ - -static tsi_result ssl_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) { - tsi_ssl_frame_protector *impl = (tsi_ssl_frame_protector *)self; - int read_from_ssl; - size_t available; - tsi_result result = TSI_OK; - - /* First see if we have some pending data in the SSL BIO. */ - int pending_in_ssl = (int)BIO_pending(impl->from_ssl); - if (pending_in_ssl > 0) { - *unprotected_bytes_size = 0; - GPR_ASSERT(*protected_output_frames_size <= INT_MAX); - read_from_ssl = BIO_read(impl->from_ssl, protected_output_frames, - (int)*protected_output_frames_size); - if (read_from_ssl < 0) { - gpr_log(GPR_ERROR, - "Could not read from BIO even though some data is pending"); - return TSI_INTERNAL_ERROR; - } - *protected_output_frames_size = (size_t)read_from_ssl; - return TSI_OK; - } - - /* Now see if we can send a complete frame. */ - available = impl->buffer_size - impl->buffer_offset; - if (available > *unprotected_bytes_size) { - /* If we cannot, just copy the data in our internal buffer. */ - memcpy(impl->buffer + impl->buffer_offset, unprotected_bytes, - *unprotected_bytes_size); - impl->buffer_offset += *unprotected_bytes_size; - *protected_output_frames_size = 0; - return TSI_OK; - } - - /* If we can, prepare the buffer, send it to SSL_write and read. */ - memcpy(impl->buffer + impl->buffer_offset, unprotected_bytes, available); - result = do_ssl_write(impl->ssl, impl->buffer, impl->buffer_size); - if (result != TSI_OK) return result; - - GPR_ASSERT(*protected_output_frames_size <= INT_MAX); - read_from_ssl = BIO_read(impl->from_ssl, protected_output_frames, - (int)*protected_output_frames_size); - if (read_from_ssl < 0) { - gpr_log(GPR_ERROR, "Could not read from BIO after SSL_write."); - return TSI_INTERNAL_ERROR; - } - *protected_output_frames_size = (size_t)read_from_ssl; - *unprotected_bytes_size = available; - impl->buffer_offset = 0; - return TSI_OK; -} - -static tsi_result ssl_protector_protect_flush( - tsi_frame_protector *self, unsigned char *protected_output_frames, - size_t *protected_output_frames_size, size_t *still_pending_size) { - tsi_result result = TSI_OK; - tsi_ssl_frame_protector *impl = (tsi_ssl_frame_protector *)self; - int read_from_ssl = 0; - int pending; - - if (impl->buffer_offset != 0) { - result = do_ssl_write(impl->ssl, impl->buffer, impl->buffer_offset); - if (result != TSI_OK) return result; - impl->buffer_offset = 0; - } - - pending = (int)BIO_pending(impl->from_ssl); - GPR_ASSERT(pending >= 0); - *still_pending_size = (size_t)pending; - if (*still_pending_size == 0) return TSI_OK; - - GPR_ASSERT(*protected_output_frames_size <= INT_MAX); - read_from_ssl = BIO_read(impl->from_ssl, protected_output_frames, - (int)*protected_output_frames_size); - if (read_from_ssl <= 0) { - gpr_log(GPR_ERROR, "Could not read from BIO after SSL_write."); - return TSI_INTERNAL_ERROR; - } - *protected_output_frames_size = (size_t)read_from_ssl; - pending = (int)BIO_pending(impl->from_ssl); - GPR_ASSERT(pending >= 0); - *still_pending_size = (size_t)pending; - return TSI_OK; -} - -static tsi_result ssl_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) { - tsi_result result = TSI_OK; - int written_into_ssl = 0; - size_t output_bytes_size = *unprotected_bytes_size; - size_t output_bytes_offset = 0; - tsi_ssl_frame_protector *impl = (tsi_ssl_frame_protector *)self; - - /* First, try to read remaining data from ssl. */ - result = do_ssl_read(impl->ssl, unprotected_bytes, unprotected_bytes_size); - if (result != TSI_OK) return result; - if (*unprotected_bytes_size == output_bytes_size) { - /* We have read everything we could and cannot process any more input. */ - *protected_frames_bytes_size = 0; - return TSI_OK; - } - output_bytes_offset = *unprotected_bytes_size; - unprotected_bytes += output_bytes_offset; - *unprotected_bytes_size = output_bytes_size - output_bytes_offset; - - /* Then, try to write some data to ssl. */ - GPR_ASSERT(*protected_frames_bytes_size <= INT_MAX); - written_into_ssl = BIO_write(impl->into_ssl, protected_frames_bytes, - (int)*protected_frames_bytes_size); - if (written_into_ssl < 0) { - gpr_log(GPR_ERROR, "Sending protected frame to ssl failed with %d", - written_into_ssl); - return TSI_INTERNAL_ERROR; - } - *protected_frames_bytes_size = (size_t)written_into_ssl; - - /* Now try to read some data again. */ - result = do_ssl_read(impl->ssl, unprotected_bytes, unprotected_bytes_size); - if (result == TSI_OK) { - /* Don't forget to output the total number of bytes read. */ - *unprotected_bytes_size += output_bytes_offset; - } - return result; -} - -static void ssl_protector_destroy(tsi_frame_protector *self) { - tsi_ssl_frame_protector *impl = (tsi_ssl_frame_protector *)self; - if (impl->buffer != NULL) gpr_free(impl->buffer); - if (impl->ssl != NULL) SSL_free(impl->ssl); - gpr_free(self); -} - -static const tsi_frame_protector_vtable frame_protector_vtable = { - ssl_protector_protect, ssl_protector_protect_flush, ssl_protector_unprotect, - ssl_protector_destroy, -}; - -/* --- tsi_handshaker methods implementation. ---*/ - -static tsi_result ssl_handshaker_get_bytes_to_send_to_peer(tsi_handshaker *self, - unsigned char *bytes, - size_t *bytes_size) { - tsi_ssl_handshaker *impl = (tsi_ssl_handshaker *)self; - int bytes_read_from_ssl = 0; - if (bytes == NULL || bytes_size == NULL || *bytes_size == 0 || - *bytes_size > INT_MAX) { - return TSI_INVALID_ARGUMENT; - } - GPR_ASSERT(*bytes_size <= INT_MAX); - bytes_read_from_ssl = BIO_read(impl->from_ssl, bytes, (int)*bytes_size); - if (bytes_read_from_ssl < 0) { - *bytes_size = 0; - if (!BIO_should_retry(impl->from_ssl)) { - impl->result = TSI_INTERNAL_ERROR; - return impl->result; - } else { - return TSI_OK; - } - } - *bytes_size = (size_t)bytes_read_from_ssl; - return BIO_pending(impl->from_ssl) == 0 ? TSI_OK : TSI_INCOMPLETE_DATA; -} - -static tsi_result ssl_handshaker_get_result(tsi_handshaker *self) { - tsi_ssl_handshaker *impl = (tsi_ssl_handshaker *)self; - if ((impl->result == TSI_HANDSHAKE_IN_PROGRESS) && - SSL_is_init_finished(impl->ssl)) { - impl->result = TSI_OK; - } - return impl->result; -} - -static tsi_result ssl_handshaker_process_bytes_from_peer( - tsi_handshaker *self, const unsigned char *bytes, size_t *bytes_size) { - tsi_ssl_handshaker *impl = (tsi_ssl_handshaker *)self; - int bytes_written_into_ssl_size = 0; - if (bytes == NULL || bytes_size == 0 || *bytes_size > INT_MAX) { - return TSI_INVALID_ARGUMENT; - } - GPR_ASSERT(*bytes_size <= INT_MAX); - bytes_written_into_ssl_size = - BIO_write(impl->into_ssl, bytes, (int)*bytes_size); - if (bytes_written_into_ssl_size < 0) { - gpr_log(GPR_ERROR, "Could not write to memory BIO."); - impl->result = TSI_INTERNAL_ERROR; - return impl->result; - } - *bytes_size = (size_t)bytes_written_into_ssl_size; - - if (!tsi_handshaker_is_in_progress(self)) { - impl->result = TSI_OK; - return impl->result; - } else { - /* Get ready to get some bytes from SSL. */ - int ssl_result = SSL_do_handshake(impl->ssl); - ssl_result = SSL_get_error(impl->ssl, ssl_result); - switch (ssl_result) { - case SSL_ERROR_WANT_READ: - if (BIO_pending(impl->from_ssl) == 0) { - /* We need more data. */ - return TSI_INCOMPLETE_DATA; - } else { - return TSI_OK; - } - case SSL_ERROR_NONE: - return TSI_OK; - default: { - char err_str[256]; - ERR_error_string_n(ERR_get_error(), err_str, sizeof(err_str)); - gpr_log(GPR_ERROR, "Handshake failed with fatal error %s: %s.", - ssl_error_string(ssl_result), err_str); - impl->result = TSI_PROTOCOL_FAILURE; - return impl->result; - } - } - } -} - -static tsi_result ssl_handshaker_extract_peer(tsi_handshaker *self, - tsi_peer *peer) { - tsi_result result = TSI_OK; - const unsigned char *alpn_selected = NULL; - unsigned int alpn_selected_len; - tsi_ssl_handshaker *impl = (tsi_ssl_handshaker *)self; - X509 *peer_cert = SSL_get_peer_certificate(impl->ssl); - if (peer_cert != NULL) { - result = peer_from_x509(peer_cert, 1, peer); - X509_free(peer_cert); - if (result != TSI_OK) return result; - } -#if TSI_OPENSSL_ALPN_SUPPORT - SSL_get0_alpn_selected(impl->ssl, &alpn_selected, &alpn_selected_len); -#endif /* TSI_OPENSSL_ALPN_SUPPORT */ - if (alpn_selected == NULL) { - /* Try npn. */ - SSL_get0_next_proto_negotiated(impl->ssl, &alpn_selected, - &alpn_selected_len); - } - if (alpn_selected != NULL) { - size_t i; - tsi_peer_property *new_properties = - gpr_zalloc(sizeof(*new_properties) * (peer->property_count + 1)); - for (i = 0; i < peer->property_count; i++) { - new_properties[i] = peer->properties[i]; - } - result = tsi_construct_string_peer_property( - TSI_SSL_ALPN_SELECTED_PROTOCOL, (const char *)alpn_selected, - alpn_selected_len, &new_properties[peer->property_count]); - if (result != TSI_OK) { - gpr_free(new_properties); - return result; - } - if (peer->properties != NULL) gpr_free(peer->properties); - peer->property_count++; - peer->properties = new_properties; - } - return result; -} - -static tsi_result ssl_handshaker_create_frame_protector( - tsi_handshaker *self, size_t *max_output_protected_frame_size, - tsi_frame_protector **protector) { - size_t actual_max_output_protected_frame_size = - TSI_SSL_MAX_PROTECTED_FRAME_SIZE_UPPER_BOUND; - tsi_ssl_handshaker *impl = (tsi_ssl_handshaker *)self; - tsi_ssl_frame_protector *protector_impl = gpr_zalloc(sizeof(*protector_impl)); - - if (max_output_protected_frame_size != NULL) { - if (*max_output_protected_frame_size > - TSI_SSL_MAX_PROTECTED_FRAME_SIZE_UPPER_BOUND) { - *max_output_protected_frame_size = - TSI_SSL_MAX_PROTECTED_FRAME_SIZE_UPPER_BOUND; - } else if (*max_output_protected_frame_size < - TSI_SSL_MAX_PROTECTED_FRAME_SIZE_LOWER_BOUND) { - *max_output_protected_frame_size = - TSI_SSL_MAX_PROTECTED_FRAME_SIZE_LOWER_BOUND; - } - actual_max_output_protected_frame_size = *max_output_protected_frame_size; - } - protector_impl->buffer_size = - actual_max_output_protected_frame_size - TSI_SSL_MAX_PROTECTION_OVERHEAD; - protector_impl->buffer = gpr_malloc(protector_impl->buffer_size); - if (protector_impl->buffer == NULL) { - gpr_log(GPR_ERROR, - "Could not allocated buffer for tsi_ssl_frame_protector."); - gpr_free(protector_impl); - return TSI_INTERNAL_ERROR; - } - - /* Transfer ownership of ssl to the frame protector. It is OK as the caller - * cannot call anything else but destroy on the handshaker after this call. */ - protector_impl->ssl = impl->ssl; - impl->ssl = NULL; - protector_impl->into_ssl = impl->into_ssl; - protector_impl->from_ssl = impl->from_ssl; - - protector_impl->base.vtable = &frame_protector_vtable; - *protector = &protector_impl->base; - return TSI_OK; -} - -static void ssl_handshaker_destroy(tsi_handshaker *self) { - tsi_ssl_handshaker *impl = (tsi_ssl_handshaker *)self; - SSL_free(impl->ssl); /* The BIO objects are owned by ssl */ - gpr_free(impl); -} - -static const tsi_handshaker_vtable handshaker_vtable = { - ssl_handshaker_get_bytes_to_send_to_peer, - ssl_handshaker_process_bytes_from_peer, - ssl_handshaker_get_result, - ssl_handshaker_extract_peer, - ssl_handshaker_create_frame_protector, - ssl_handshaker_destroy, -}; - -/* --- tsi_ssl_handshaker_factory common methods. --- */ - -tsi_result tsi_ssl_handshaker_factory_create_handshaker( - tsi_ssl_handshaker_factory *self, const char *server_name_indication, - tsi_handshaker **handshaker) { - if (self == NULL || handshaker == NULL) return TSI_INVALID_ARGUMENT; - return self->create_handshaker(self, server_name_indication, handshaker); -} - -void tsi_ssl_handshaker_factory_destroy(tsi_ssl_handshaker_factory *self) { - if (self == NULL) return; - self->destroy(self); -} - -static tsi_result create_tsi_ssl_handshaker(SSL_CTX *ctx, int is_client, - const char *server_name_indication, - tsi_handshaker **handshaker) { - SSL *ssl = SSL_new(ctx); - BIO *into_ssl = NULL; - BIO *from_ssl = NULL; - tsi_ssl_handshaker *impl = NULL; - *handshaker = NULL; - if (ctx == NULL) { - gpr_log(GPR_ERROR, "SSL Context is null. Should never happen."); - return TSI_INTERNAL_ERROR; - } - if (ssl == NULL) { - return TSI_OUT_OF_RESOURCES; - } - SSL_set_info_callback(ssl, ssl_info_callback); - - into_ssl = BIO_new(BIO_s_mem()); - from_ssl = BIO_new(BIO_s_mem()); - if (into_ssl == NULL || from_ssl == NULL) { - gpr_log(GPR_ERROR, "BIO_new failed."); - SSL_free(ssl); - if (into_ssl != NULL) BIO_free(into_ssl); - if (from_ssl != NULL) BIO_free(into_ssl); - return TSI_OUT_OF_RESOURCES; - } - SSL_set_bio(ssl, into_ssl, from_ssl); - if (is_client) { - int ssl_result; - SSL_set_connect_state(ssl); - if (server_name_indication != NULL) { - if (!SSL_set_tlsext_host_name(ssl, server_name_indication)) { - gpr_log(GPR_ERROR, "Invalid server name indication %s.", - server_name_indication); - SSL_free(ssl); - return TSI_INTERNAL_ERROR; - } - } - ssl_result = SSL_do_handshake(ssl); - ssl_result = SSL_get_error(ssl, ssl_result); - if (ssl_result != SSL_ERROR_WANT_READ) { - gpr_log(GPR_ERROR, - "Unexpected error received from first SSL_do_handshake call: %s", - ssl_error_string(ssl_result)); - SSL_free(ssl); - return TSI_INTERNAL_ERROR; - } - } else { - SSL_set_accept_state(ssl); - } - - impl = gpr_zalloc(sizeof(*impl)); - impl->ssl = ssl; - impl->into_ssl = into_ssl; - impl->from_ssl = from_ssl; - impl->result = TSI_HANDSHAKE_IN_PROGRESS; - impl->base.vtable = &handshaker_vtable; - *handshaker = &impl->base; - return TSI_OK; -} - -static int select_protocol_list(const unsigned char **out, - unsigned char *outlen, - const unsigned char *client_list, - size_t client_list_len, - const unsigned char *server_list, - size_t server_list_len) { - const unsigned char *client_current = client_list; - while ((unsigned int)(client_current - client_list) < client_list_len) { - unsigned char client_current_len = *(client_current++); - const unsigned char *server_current = server_list; - while ((server_current >= server_list) && - (uintptr_t)(server_current - server_list) < server_list_len) { - unsigned char server_current_len = *(server_current++); - if ((client_current_len == server_current_len) && - !memcmp(client_current, server_current, server_current_len)) { - *out = server_current; - *outlen = server_current_len; - return SSL_TLSEXT_ERR_OK; - } - server_current += server_current_len; - } - client_current += client_current_len; - } - return SSL_TLSEXT_ERR_NOACK; -} - -/* --- tsi_ssl__client_handshaker_factory methods implementation. --- */ - -static tsi_result ssl_client_handshaker_factory_create_handshaker( - tsi_ssl_handshaker_factory *self, const char *server_name_indication, - tsi_handshaker **handshaker) { - tsi_ssl_client_handshaker_factory *impl = - (tsi_ssl_client_handshaker_factory *)self; - return create_tsi_ssl_handshaker(impl->ssl_context, 1, server_name_indication, - handshaker); -} - -static void ssl_client_handshaker_factory_destroy( - tsi_ssl_handshaker_factory *self) { - tsi_ssl_client_handshaker_factory *impl = - (tsi_ssl_client_handshaker_factory *)self; - if (impl->ssl_context != NULL) SSL_CTX_free(impl->ssl_context); - if (impl->alpn_protocol_list != NULL) gpr_free(impl->alpn_protocol_list); - gpr_free(impl); -} - -static int client_handshaker_factory_npn_callback(SSL *ssl, unsigned char **out, - unsigned char *outlen, - const unsigned char *in, - unsigned int inlen, - void *arg) { - tsi_ssl_client_handshaker_factory *factory = - (tsi_ssl_client_handshaker_factory *)arg; - return select_protocol_list((const unsigned char **)out, outlen, - factory->alpn_protocol_list, - factory->alpn_protocol_list_length, in, inlen); -} - -/* --- tsi_ssl_server_handshaker_factory methods implementation. --- */ - -static tsi_result ssl_server_handshaker_factory_create_handshaker( - tsi_ssl_handshaker_factory *self, const char *server_name_indication, - tsi_handshaker **handshaker) { - tsi_ssl_server_handshaker_factory *impl = - (tsi_ssl_server_handshaker_factory *)self; - if (impl->ssl_context_count == 0 || server_name_indication != NULL) { - return TSI_INVALID_ARGUMENT; - } - /* Create the handshaker with the first context. We will switch if needed - because of SNI in ssl_server_handshaker_factory_servername_callback. */ - return create_tsi_ssl_handshaker(impl->ssl_contexts[0], 0, NULL, handshaker); -} - -static void ssl_server_handshaker_factory_destroy( - tsi_ssl_handshaker_factory *self) { - tsi_ssl_server_handshaker_factory *impl = - (tsi_ssl_server_handshaker_factory *)self; - size_t i; - for (i = 0; i < impl->ssl_context_count; i++) { - if (impl->ssl_contexts[i] != NULL) { - SSL_CTX_free(impl->ssl_contexts[i]); - tsi_peer_destruct(&impl->ssl_context_x509_subject_names[i]); - } - } - if (impl->ssl_contexts != NULL) gpr_free(impl->ssl_contexts); - if (impl->ssl_context_x509_subject_names != NULL) { - gpr_free(impl->ssl_context_x509_subject_names); - } - if (impl->alpn_protocol_list != NULL) gpr_free(impl->alpn_protocol_list); - gpr_free(impl); -} - -static int does_entry_match_name(const char *entry, size_t entry_length, - const char *name) { - const char *dot; - const char *name_subdomain = NULL; - size_t name_length = strlen(name); - size_t name_subdomain_length; - if (entry_length == 0) return 0; - - /* Take care of '.' terminations. */ - if (name[name_length - 1] == '.') { - name_length--; - } - if (entry[entry_length - 1] == '.') { - entry_length--; - if (entry_length == 0) return 0; - } - - if ((name_length == entry_length) && - strncmp(name, entry, entry_length) == 0) { - return 1; /* Perfect match. */ - } - if (entry[0] != '*') return 0; - - /* Wildchar subdomain matching. */ - if (entry_length < 3 || entry[1] != '.') { /* At least *.x */ - gpr_log(GPR_ERROR, "Invalid wildchar entry."); - return 0; - } - name_subdomain = strchr(name, '.'); - if (name_subdomain == NULL) return 0; - name_subdomain_length = strlen(name_subdomain); - if (name_subdomain_length < 2) return 0; - name_subdomain++; /* Starts after the dot. */ - name_subdomain_length--; - entry += 2; /* Remove *. */ - entry_length -= 2; - dot = strchr(name_subdomain, '.'); - if ((dot == NULL) || (dot == &name_subdomain[name_subdomain_length - 1])) { - gpr_log(GPR_ERROR, "Invalid toplevel subdomain: %s", name_subdomain); - return 0; - } - if (name_subdomain[name_subdomain_length - 1] == '.') { - name_subdomain_length--; - } - return ((entry_length > 0) && (name_subdomain_length == entry_length) && - strncmp(entry, name_subdomain, entry_length) == 0); -} - -static int ssl_server_handshaker_factory_servername_callback(SSL *ssl, int *ap, - void *arg) { - tsi_ssl_server_handshaker_factory *impl = - (tsi_ssl_server_handshaker_factory *)arg; - size_t i = 0; - const char *servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name); - if (servername == NULL || strlen(servername) == 0) { - return SSL_TLSEXT_ERR_NOACK; - } - - for (i = 0; i < impl->ssl_context_count; i++) { - if (tsi_ssl_peer_matches_name(&impl->ssl_context_x509_subject_names[i], - servername)) { - SSL_set_SSL_CTX(ssl, impl->ssl_contexts[i]); - return SSL_TLSEXT_ERR_OK; - } - } - gpr_log(GPR_ERROR, "No match found for server name: %s.", servername); - return SSL_TLSEXT_ERR_ALERT_WARNING; -} - -#if TSI_OPENSSL_ALPN_SUPPORT -static int server_handshaker_factory_alpn_callback( - SSL *ssl, const unsigned char **out, unsigned char *outlen, - const unsigned char *in, unsigned int inlen, void *arg) { - tsi_ssl_server_handshaker_factory *factory = - (tsi_ssl_server_handshaker_factory *)arg; - return select_protocol_list(out, outlen, in, inlen, - factory->alpn_protocol_list, - factory->alpn_protocol_list_length); -} -#endif /* TSI_OPENSSL_ALPN_SUPPORT */ - -static int server_handshaker_factory_npn_advertised_callback( - SSL *ssl, const unsigned char **out, unsigned int *outlen, void *arg) { - tsi_ssl_server_handshaker_factory *factory = - (tsi_ssl_server_handshaker_factory *)arg; - *out = factory->alpn_protocol_list; - GPR_ASSERT(factory->alpn_protocol_list_length <= UINT_MAX); - *outlen = (unsigned int)factory->alpn_protocol_list_length; - return SSL_TLSEXT_ERR_OK; -} - -/* --- tsi_ssl_handshaker_factory constructors. --- */ - -tsi_result tsi_create_ssl_client_handshaker_factory( - const unsigned char *pem_private_key, size_t pem_private_key_size, - const unsigned char *pem_cert_chain, size_t pem_cert_chain_size, - const unsigned char *pem_root_certs, size_t pem_root_certs_size, - const char *cipher_list, const unsigned char **alpn_protocols, - const unsigned char *alpn_protocols_lengths, uint16_t num_alpn_protocols, - tsi_ssl_handshaker_factory **factory) { - SSL_CTX *ssl_context = NULL; - tsi_ssl_client_handshaker_factory *impl = NULL; - tsi_result result = TSI_OK; - - gpr_once_init(&init_openssl_once, init_openssl); - - if (factory == NULL) return TSI_INVALID_ARGUMENT; - *factory = NULL; - if (pem_root_certs == NULL) return TSI_INVALID_ARGUMENT; - - ssl_context = SSL_CTX_new(TLSv1_2_method()); - if (ssl_context == NULL) { - gpr_log(GPR_ERROR, "Could not create ssl context."); - return TSI_INVALID_ARGUMENT; - } - - impl = gpr_zalloc(sizeof(*impl)); - impl->ssl_context = ssl_context; - - do { - result = - populate_ssl_context(ssl_context, pem_private_key, pem_private_key_size, - pem_cert_chain, pem_cert_chain_size, cipher_list); - if (result != TSI_OK) break; - result = ssl_ctx_load_verification_certs(ssl_context, pem_root_certs, - pem_root_certs_size, NULL); - if (result != TSI_OK) { - gpr_log(GPR_ERROR, "Cannot load server root certificates."); - break; - } - - if (num_alpn_protocols != 0) { - result = build_alpn_protocol_name_list( - alpn_protocols, alpn_protocols_lengths, num_alpn_protocols, - &impl->alpn_protocol_list, &impl->alpn_protocol_list_length); - if (result != TSI_OK) { - gpr_log(GPR_ERROR, "Building alpn list failed with error %s.", - tsi_result_to_string(result)); - break; - } -#if TSI_OPENSSL_ALPN_SUPPORT - GPR_ASSERT(impl->alpn_protocol_list_length < UINT_MAX); - if (SSL_CTX_set_alpn_protos( - ssl_context, impl->alpn_protocol_list, - (unsigned int)impl->alpn_protocol_list_length)) { - gpr_log(GPR_ERROR, "Could not set alpn protocol list to context."); - result = TSI_INVALID_ARGUMENT; - break; - } -#endif /* TSI_OPENSSL_ALPN_SUPPORT */ - SSL_CTX_set_next_proto_select_cb( - ssl_context, client_handshaker_factory_npn_callback, impl); - } - } while (0); - if (result != TSI_OK) { - ssl_client_handshaker_factory_destroy(&impl->base); - return result; - } - SSL_CTX_set_verify(ssl_context, SSL_VERIFY_PEER, NULL); - /* TODO(jboeuf): Add revocation verification. */ - - impl->base.create_handshaker = - ssl_client_handshaker_factory_create_handshaker; - impl->base.destroy = ssl_client_handshaker_factory_destroy; - *factory = &impl->base; - return TSI_OK; -} - -tsi_result tsi_create_ssl_server_handshaker_factory( - const unsigned char **pem_private_keys, - const size_t *pem_private_keys_sizes, const unsigned char **pem_cert_chains, - const size_t *pem_cert_chains_sizes, size_t key_cert_pair_count, - const unsigned char *pem_client_root_certs, - size_t pem_client_root_certs_size, int force_client_auth, - const char *cipher_list, const unsigned char **alpn_protocols, - const unsigned char *alpn_protocols_lengths, uint16_t num_alpn_protocols, - tsi_ssl_handshaker_factory **factory) { - return tsi_create_ssl_server_handshaker_factory_ex( - pem_private_keys, pem_private_keys_sizes, pem_cert_chains, - pem_cert_chains_sizes, key_cert_pair_count, pem_client_root_certs, - pem_client_root_certs_size, - force_client_auth ? TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY - : TSI_DONT_REQUEST_CLIENT_CERTIFICATE, - cipher_list, alpn_protocols, alpn_protocols_lengths, num_alpn_protocols, - factory); -} - -tsi_result tsi_create_ssl_server_handshaker_factory_ex( - const unsigned char **pem_private_keys, - const size_t *pem_private_keys_sizes, const unsigned char **pem_cert_chains, - const size_t *pem_cert_chains_sizes, size_t key_cert_pair_count, - const unsigned char *pem_client_root_certs, - size_t pem_client_root_certs_size, - tsi_client_certificate_request_type client_certificate_request, - const char *cipher_list, const unsigned char **alpn_protocols, - const unsigned char *alpn_protocols_lengths, uint16_t num_alpn_protocols, - tsi_ssl_handshaker_factory **factory) { - tsi_ssl_server_handshaker_factory *impl = NULL; - tsi_result result = TSI_OK; - size_t i = 0; - - gpr_once_init(&init_openssl_once, init_openssl); - - if (factory == NULL) return TSI_INVALID_ARGUMENT; - *factory = NULL; - if (key_cert_pair_count == 0 || pem_private_keys == NULL || - pem_cert_chains == NULL) { - return TSI_INVALID_ARGUMENT; - } - - impl = gpr_zalloc(sizeof(*impl)); - impl->base.create_handshaker = - ssl_server_handshaker_factory_create_handshaker; - impl->base.destroy = ssl_server_handshaker_factory_destroy; - impl->ssl_contexts = gpr_zalloc(key_cert_pair_count * sizeof(SSL_CTX *)); - impl->ssl_context_x509_subject_names = - gpr_zalloc(key_cert_pair_count * sizeof(tsi_peer)); - if (impl->ssl_contexts == NULL || - impl->ssl_context_x509_subject_names == NULL) { - tsi_ssl_handshaker_factory_destroy(&impl->base); - return TSI_OUT_OF_RESOURCES; - } - impl->ssl_context_count = key_cert_pair_count; - - if (num_alpn_protocols > 0) { - result = build_alpn_protocol_name_list( - alpn_protocols, alpn_protocols_lengths, num_alpn_protocols, - &impl->alpn_protocol_list, &impl->alpn_protocol_list_length); - if (result != TSI_OK) { - tsi_ssl_handshaker_factory_destroy(&impl->base); - return result; - } - } - - for (i = 0; i < key_cert_pair_count; i++) { - do { - impl->ssl_contexts[i] = SSL_CTX_new(TLSv1_2_method()); - if (impl->ssl_contexts[i] == NULL) { - gpr_log(GPR_ERROR, "Could not create ssl context."); - result = TSI_OUT_OF_RESOURCES; - break; - } - result = populate_ssl_context( - impl->ssl_contexts[i], pem_private_keys[i], pem_private_keys_sizes[i], - pem_cert_chains[i], pem_cert_chains_sizes[i], cipher_list); - if (result != TSI_OK) break; - - if (pem_client_root_certs != NULL) { - STACK_OF(X509_NAME) *root_names = NULL; - result = ssl_ctx_load_verification_certs( - impl->ssl_contexts[i], pem_client_root_certs, - pem_client_root_certs_size, &root_names); - if (result != TSI_OK) { - gpr_log(GPR_ERROR, "Invalid verification certs."); - break; - } - SSL_CTX_set_client_CA_list(impl->ssl_contexts[i], root_names); - switch (client_certificate_request) { - case TSI_DONT_REQUEST_CLIENT_CERTIFICATE: - SSL_CTX_set_verify(impl->ssl_contexts[i], SSL_VERIFY_NONE, NULL); - break; - case TSI_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY: - SSL_CTX_set_verify(impl->ssl_contexts[i], SSL_VERIFY_PEER, - NullVerifyCallback); - break; - case TSI_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY: - SSL_CTX_set_verify(impl->ssl_contexts[i], SSL_VERIFY_PEER, NULL); - break; - case TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY: - SSL_CTX_set_verify( - impl->ssl_contexts[i], - SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, - NullVerifyCallback); - break; - case TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY: - SSL_CTX_set_verify( - impl->ssl_contexts[i], - SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL); - break; - } - /* TODO(jboeuf): Add revocation verification. */ - } - - result = extract_x509_subject_names_from_pem_cert( - pem_cert_chains[i], pem_cert_chains_sizes[i], - &impl->ssl_context_x509_subject_names[i]); - if (result != TSI_OK) break; - - SSL_CTX_set_tlsext_servername_callback( - impl->ssl_contexts[i], - ssl_server_handshaker_factory_servername_callback); - SSL_CTX_set_tlsext_servername_arg(impl->ssl_contexts[i], impl); -#if TSI_OPENSSL_ALPN_SUPPORT - SSL_CTX_set_alpn_select_cb(impl->ssl_contexts[i], - server_handshaker_factory_alpn_callback, impl); -#endif /* TSI_OPENSSL_ALPN_SUPPORT */ - SSL_CTX_set_next_protos_advertised_cb( - impl->ssl_contexts[i], - server_handshaker_factory_npn_advertised_callback, impl); - } while (0); - - if (result != TSI_OK) { - tsi_ssl_handshaker_factory_destroy(&impl->base); - return result; - } - } - *factory = &impl->base; - return TSI_OK; -} - -/* --- tsi_ssl utils. --- */ - -int tsi_ssl_peer_matches_name(const tsi_peer *peer, const char *name) { - size_t i = 0; - size_t san_count = 0; - const tsi_peer_property *cn_property = NULL; - int like_ip = looks_like_ip_address(name); - - /* Check the SAN first. */ - for (i = 0; i < peer->property_count; i++) { - const tsi_peer_property *property = &peer->properties[i]; - if (property->name == NULL) continue; - if (strcmp(property->name, - TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY) == 0) { - san_count++; - - if (!like_ip && does_entry_match_name(property->value.data, - property->value.length, name)) { - return 1; - } else if (like_ip && - strncmp(name, property->value.data, property->value.length) == - 0 && - strlen(name) == property->value.length) { - /* IP Addresses are exact matches only. */ - return 1; - } - } else if (strcmp(property->name, - TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY) == 0) { - cn_property = property; - } - } - - /* If there's no SAN, try the CN, but only if its not like an IP Address */ - if (san_count == 0 && cn_property != NULL && !like_ip) { - if (does_entry_match_name(cn_property->value.data, - cn_property->value.length, name)) { - return 1; - } - } - - return 0; /* Not found. */ -} diff --git a/src/core/lib/tsi/ssl_transport_security.h b/src/core/lib/tsi/ssl_transport_security.h deleted file mode 100644 index 7407246118..0000000000 --- a/src/core/lib/tsi/ssl_transport_security.h +++ /dev/null @@ -1,191 +0,0 @@ -/* - * - * 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. - * - */ - -#ifndef GRPC_CORE_LIB_TSI_SSL_TRANSPORT_SECURITY_H -#define GRPC_CORE_LIB_TSI_SSL_TRANSPORT_SECURITY_H - -#include "src/core/lib/tsi/transport_security_interface.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* Value for the TSI_CERTIFICATE_TYPE_PEER_PROPERTY property for X509 certs. */ -#define TSI_X509_CERTIFICATE_TYPE "X509" - -/* This property is of type TSI_PEER_PROPERTY_STRING. */ -#define TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY "x509_subject_common_name" -#define TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY \ - "x509_subject_alternative_name" - -#define TSI_X509_PEM_CERT_PROPERTY "x509_pem_cert" - -#define TSI_SSL_ALPN_SELECTED_PROTOCOL "ssl_alpn_selected_protocol" - -/* --- tsi_ssl_handshaker_factory object --- - - This object creates tsi_handshaker objects implemented in terms of the - TLS 1.2 specificiation. */ - -typedef struct tsi_ssl_handshaker_factory tsi_ssl_handshaker_factory; - -/* Creates a client handshaker factory. - - pem_private_key is the buffer containing the PEM encoding of the client's - private key. This parameter can be NULL if the client does not have a - private key. - - pem_private_key_size is the size of the associated buffer. - - pem_cert_chain is the buffer containing the PEM encoding of the client's - certificate chain. This parameter can be NULL if the client does not have - a certificate chain. - - pem_cert_chain_size is the size of the associated buffer. - - pem_roots_cert is the buffer containing the PEM encoding of the server - root certificates. This parameter cannot be NULL. - - pem_roots_cert_size is the size of the associated buffer. - - cipher_suites contains an optional list of the ciphers that the client - supports. The format of this string is described in: - https://www.openssl.org/docs/apps/ciphers.html. - This parameter can be set to NULL to use the default set of ciphers. - TODO(jboeuf): Revisit the format of this parameter. - - alpn_protocols is an array containing the protocol names that the - handshakers created with this factory support. This parameter can be NULL. - - alpn_protocols_lengths is an array containing the lengths of the alpn - protocols specified in alpn_protocols. This parameter can be NULL. - - num_alpn_protocols is the number of alpn protocols and associated lengths - specified. If this parameter is 0, the other alpn parameters must be NULL. - - factory is the address of the factory pointer to be created. - - - This method returns TSI_OK on success or TSI_INVALID_PARAMETER in the case - where a parameter is invalid. */ -tsi_result tsi_create_ssl_client_handshaker_factory( - const unsigned char *pem_private_key, size_t pem_private_key_size, - const unsigned char *pem_cert_chain, size_t pem_cert_chain_size, - const unsigned char *pem_root_certs, size_t pem_root_certs_size, - const char *cipher_suites, const unsigned char **alpn_protocols, - const unsigned char *alpn_protocols_lengths, uint16_t num_alpn_protocols, - tsi_ssl_handshaker_factory **factory); - -/* Creates a server handshaker factory. - - version indicates which version of the specification to use. - - pem_private_keys is an array containing the PEM encoding of the server's - private keys. This parameter cannot be NULL. The size of the array is - given by the key_cert_pair_count parameter. - - pem_private_keys_sizes is the array containing the sizes of the associated - buffers. - - pem_cert_chains is an array containing the PEM encoding of the server's - cert chains. This parameter cannot be NULL. The size of the array is - given by the key_cert_pair_count parameter. - - pem_cert_chains_sizes is the array containing the sizes of the associated - buffers. - - key_cert_pair_count indicates the number of items in the private_key_files - and cert_chain_files parameters. - - pem_client_roots is the buffer containing the PEM encoding of the client - root certificates. This parameter may be NULL in which case the server will - not authenticate the client. If not NULL, the force_client_auth parameter - specifies if the server will accept only authenticated clients or both - authenticated and non-authenticated clients. - - pem_client_root_certs_size is the size of the associated buffer. - - force_client_auth, if set to non-zero will force the client to authenticate - with an SSL cert. Note that this option is ignored if pem_client_root_certs - is NULL or pem_client_roots_certs_size is 0 - - cipher_suites contains an optional list of the ciphers that the server - supports. The format of this string is described in: - https://www.openssl.org/docs/apps/ciphers.html. - This parameter can be set to NULL to use the default set of ciphers. - TODO(jboeuf): Revisit the format of this parameter. - - alpn_protocols is an array containing the protocol names that the - handshakers created with this factory support. This parameter can be NULL. - - alpn_protocols_lengths is an array containing the lengths of the alpn - protocols specified in alpn_protocols. This parameter can be NULL. - - num_alpn_protocols is the number of alpn protocols and associated lengths - specified. If this parameter is 0, the other alpn parameters must be NULL. - - factory is the address of the factory pointer to be created. - - - This method returns TSI_OK on success or TSI_INVALID_PARAMETER in the case - where a parameter is invalid. */ -tsi_result tsi_create_ssl_server_handshaker_factory( - const unsigned char **pem_private_keys, - const size_t *pem_private_keys_sizes, const unsigned char **pem_cert_chains, - const size_t *pem_cert_chains_sizes, size_t key_cert_pair_count, - const unsigned char *pem_client_root_certs, - size_t pem_client_root_certs_size, int force_client_auth, - const char *cipher_suites, const unsigned char **alpn_protocols, - const unsigned char *alpn_protocols_lengths, uint16_t num_alpn_protocols, - tsi_ssl_handshaker_factory **factory); - -/* Same as tsi_create_ssl_server_handshaker_factory method except uses - tsi_client_certificate_request_type to support more ways to handle client - certificate authentication. - - client_certificate_request, if set to non-zero will force the client to - authenticate with an SSL cert. Note that this option is ignored if - pem_client_root_certs is NULL or pem_client_roots_certs_size is 0 */ -tsi_result tsi_create_ssl_server_handshaker_factory_ex( - const unsigned char **pem_private_keys, - const size_t *pem_private_keys_sizes, const unsigned char **pem_cert_chains, - const size_t *pem_cert_chains_sizes, size_t key_cert_pair_count, - const unsigned char *pem_client_root_certs, - size_t pem_client_root_certs_size, - tsi_client_certificate_request_type client_certificate_request, - const char *cipher_suites, const unsigned char **alpn_protocols, - const unsigned char *alpn_protocols_lengths, uint16_t num_alpn_protocols, - tsi_ssl_handshaker_factory **factory); - -/* Creates a handshaker. - - self is the factory from which the handshaker will be created. - - server_name_indication indicates the name of the server the client is - trying to connect to which will be relayed to the server using the SNI - extension. - This parameter must be NULL for a server handshaker factory. - - handhshaker is the address of the handshaker pointer to be created. - - - This method returns TSI_OK on success or TSI_INVALID_PARAMETER in the case - where a parameter is invalid. */ -tsi_result tsi_ssl_handshaker_factory_create_handshaker( - tsi_ssl_handshaker_factory *self, const char *server_name_indication, - tsi_handshaker **handshaker); - -/* Destroys the handshaker factory. WARNING: it is unsafe to destroy a factory - while handshakers created with this factory are still in use. */ -void tsi_ssl_handshaker_factory_destroy(tsi_ssl_handshaker_factory *self); - -/* Util that checks that an ssl peer matches a specific name. - Still TODO(jboeuf): - - handle mixed case. - - handle %encoded chars. - - handle public suffix wildchar more strictly (e.g. *.co.uk) */ -int tsi_ssl_peer_matches_name(const tsi_peer *peer, const char *name); - -#ifdef __cplusplus -} -#endif - -#endif /* GRPC_CORE_LIB_TSI_SSL_TRANSPORT_SECURITY_H */ diff --git a/src/core/lib/tsi/ssl_types.h b/src/core/lib/tsi/ssl_types.h deleted file mode 100644 index 0a988effd0..0000000000 --- a/src/core/lib/tsi/ssl_types.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * - * 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. - * - */ - -#ifndef GRPC_CORE_LIB_TSI_SSL_TYPES_H -#define GRPC_CORE_LIB_TSI_SSL_TYPES_H - -/* A collection of macros to cast between various integer types that are - * used differently between BoringSSL and OpenSSL: - * TSI_INT_AS_SIZE(x): convert 'int x' to a length parameter for an OpenSSL - * function - * TSI_SIZE_AS_SIZE(x): convert 'size_t x' to a length parameter for an OpenSSL - * function - */ - -#include <openssl/ssl.h> - -#ifdef OPENSSL_IS_BORINGSSL -#define TSI_INT_AS_SIZE(x) ((size_t)(x)) -#define TSI_SIZE_AS_SIZE(x) (x) -#else -#define TSI_INT_AS_SIZE(x) (x) -#define TSI_SIZE_AS_SIZE(x) ((int)(x)) -#endif - -#endif /* GRPC_CORE_LIB_TSI_SSL_TYPES_H */ diff --git a/src/core/lib/tsi/test_creds/BUILD b/src/core/lib/tsi/test_creds/BUILD deleted file mode 100644 index 5cf04caf17..0000000000 --- a/src/core/lib/tsi/test_creds/BUILD +++ /dev/null @@ -1,36 +0,0 @@ -# Copyright 2017, 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. - -licenses(["notice"]) # 3-clause BSD - -exports_files([ - "ca.pem", - "server1.key", - "server1.pem", -]) diff --git a/src/core/lib/tsi/test_creds/README b/src/core/lib/tsi/test_creds/README deleted file mode 100644 index eb8482d648..0000000000 --- a/src/core/lib/tsi/test_creds/README +++ /dev/null @@ -1,62 +0,0 @@ -The test credentials (CONFIRMEDTESTKEY) have been generated with the following -commands: - -Bad credentials (badclient.* / badserver.*): -============================================ - -These are self-signed certificates: - -$ openssl req -x509 -newkey rsa:1024 -keyout badserver.key -out badserver.pem \ - -days 3650 -nodes - -When prompted for certificate information, everything is default except the -common name which is set to badserver.test.google.com. - - -Valid test credentials: -======================= - -The ca is self-signed: ----------------------- - -$ openssl req -x509 -new -newkey rsa:1024 -nodes -out ca.pem -config ca-openssl.cnf -days 3650 -extensions v3_req -When prompted for certificate information, everything is default. - -client is issued by CA: ------------------------ - -$ openssl genrsa -out client.key.rsa 1024 -$ openssl pkcs8 -topk8 -in client.key.rsa -out client.key -nocrypt -$ rm client.key.rsa -$ openssl req -new -key client.key -out client.csr - -When prompted for certificate information, everything is default except the -common name which is set to testclient. - -$ openssl ca -in client.csr -out client.pem - -server0 is issued by CA: ------------------------- - -$ openssl genrsa -out server0.key.rsa 1024 -$ openssl pkcs8 -topk8 -in server0.key.rsa -out server0.key -nocrypt -$ rm server0.key.rsa -$ openssl req -new -key server0.key -out server0.csr - -When prompted for certificate information, everything is default except the -common name which is set to *.test.google.com.au. - -$ openssl ca -in server0.csr -out server0.pem - -server1 is issued by CA with a special config for subject alternative names: ----------------------------------------------------------------------------- - -$ openssl genrsa -out server1.key.rsa 1024 -$ openssl pkcs8 -topk8 -in server1.key.rsa -out server1.key -nocrypt -$ rm server1.key.rsa -$ openssl req -new -key server1.key -out server1.csr -config server1-openssl.cnf - -When prompted for certificate information, everything is default except the -common name which is set to *.test.google.com. - -$ openssl ca -in server1.csr -out server1.pem diff --git a/src/core/lib/tsi/test_creds/badclient.key b/src/core/lib/tsi/test_creds/badclient.key deleted file mode 100644 index 5832685122..0000000000 --- a/src/core/lib/tsi/test_creds/badclient.key +++ /dev/null @@ -1,16 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALJfYnFn4nkj52WF -E5W2qUxCfjsEFyuXYYKS/07UPWsv3gpZhtjXgdeGL+dpwEBC0IRDBfGnkMp6YY5S -O7rnEz0X3r/fvgYy+dEl2jnaA6zgc7RzMGl9U11d56gP9FiDC2190mvP/hpq2xLZ -CTbIximpmaoQyxuuH1bbYunesIG/AgMBAAECgYAdqJCEzMIyZE7oaW0tOpcB0BiP -FYoIvH4BKRH8eHvR476mt+YdDhBP1scGUmYeCT4Ej+RgHv2LPTgVYwT9eciP2+E/ -CBCNRel0Sw9JepwW0r+jWJtDY1pp6YXAgNRGX2UflvUsT+o9lZvagf9moLTMyGvU -uLFnsyfLim1B4vXvWQJBANouZllXGZoSrZLtR3VgV4tzRQvJxu84kLeIk64Ov47X -pHVBMTRBfzPEhbBodjr1m5OLaVLqkFcXftzRCrbWoKsCQQDRSoLLXOiLrtJ3DLJC -rX7Y8wrHZrqk5bMdZLGa/UX8RanhVw3+Xp+urd1711umeNJfzu/MCk4a1KkG/CU0 -rqs9AkA4cSx1DD1JSG+yxMNpsAS1xJomFIrsM9vsPt7FdndDwrF+y+CovhDkGYDk -RAHh+svGfZg/pQK2JRPimAmHhzqFAkEAu6Ya70s2FUeB3Mu9aJs2CD6hg3dQEVkB -53DI7TX48d9kGW58VX1xnqS02LyWqAPcW5qm1kLHFLdndaPNmBaj4QJBAJugl367 -9d9t/QLTSuULLaoYv2vJT3s1y9HN89EoaDDEkPVfQu6GVEXgIBtim1sI/VPSzI8H -aXvaTUwblFWSM70= ------END PRIVATE KEY----- diff --git a/src/core/lib/tsi/test_creds/badclient.pem b/src/core/lib/tsi/test_creds/badclient.pem deleted file mode 100644 index 1785970221..0000000000 --- a/src/core/lib/tsi/test_creds/badclient.pem +++ /dev/null @@ -1,17 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICoDCCAgmgAwIBAgIJANIz2/zoRiapMA0GCSqGSIb3DQEBBQUAMGkxCzAJBgNV -BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX -aWRnaXRzIFB0eSBMdGQxIjAgBgNVBAMMGWJhZGNsaWVudC50ZXN0Lmdvb2dsZS5j -b20wHhcNMTQwNzI4MjAwODI1WhcNMjQwNzI1MjAwODI1WjBpMQswCQYDVQQGEwJB -VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0 -cyBQdHkgTHRkMSIwIAYDVQQDDBliYWRjbGllbnQudGVzdC5nb29nbGUuY29tMIGf -MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCyX2JxZ+J5I+dlhROVtqlMQn47BBcr -l2GCkv9O1D1rL94KWYbY14HXhi/nacBAQtCEQwXxp5DKemGOUju65xM9F96/374G -MvnRJdo52gOs4HO0czBpfVNdXeeoD/RYgwttfdJrz/4aatsS2Qk2yMYpqZmqEMsb -rh9W22Lp3rCBvwIDAQABo1AwTjAdBgNVHQ4EFgQU523AJMR8Ds9V8fhf7gu1i0MM -UqAwHwYDVR0jBBgwFoAU523AJMR8Ds9V8fhf7gu1i0MMUqAwDAYDVR0TBAUwAwEB -/zANBgkqhkiG9w0BAQUFAAOBgQCI/tvSBYH1iyfLaCTBKwpdj36+MkR9EeJJmImx -X+bjhKWXwsBX4PDMWvdusr++QGUYtyoya+hfYMXRhXua39mD54xgloQNuu9REDwX -Ffto+aOw3BcYducz6ofxicFK/Y2VeXDurSMpRv5TfGf2Qr6eOOdaRhj6ed7BibHk -X1VGZA== ------END CERTIFICATE----- diff --git a/src/core/lib/tsi/test_creds/badserver.key b/src/core/lib/tsi/test_creds/badserver.key deleted file mode 100644 index abfbde10ff..0000000000 --- a/src/core/lib/tsi/test_creds/badserver.key +++ /dev/null @@ -1,16 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKeZ1e1y29cmBKaW -oIUwJ5neOJUjx+eD/3nRPe+dvLXEd9+db0fG5RYRR0S3mF1Ywuj4PIxlTW2YprUS -oGSw+tcqWNIzxv94HjwYFkkvER3AblXcDBh0P2zAkzg+nf9AcAsMh0QpDTyrXtMl -gqryjq1/vkhFofKMMbY+aXJdG6OBAgMBAAECgYAAgaB51S0A22aMMkxN2rVj6530 -JWWHN4jgD1fGj41wZyWNkWYyq1Ep3ed/N6bIMWp1VbqpGe0/9YQba/D8HOTFHGRt -72YXnP1e/ds8cxU4x4j1vvqSPtXpMmkiXfXijOvCl9mrMH2xjghFAt6/1Nb9xo1m -VdcOB8OdSuOIw6CI+QJBAN5FZUbS+bRXDWII/FaAih1DBpwCxhYEN+TXPJBxSen6 -kOzGt5g+mB6YqRMZ/qshshwPq7bsgFGfJ2lIdS2t3GsCQQDBCKifV5AAkOdOUrkK -HvoX3qnVmyIA8CyvWLcIWpfZ76QAYh0q0StedKdOMXaB1jTeSJ2KU1nlss7UD1Yw -VbrDAkAwjMHpbW3jiVw//Kx5jIwehiRscWKpLnSzBJyTBFvbwsJjJai2lX2OuVO8 -+2GYKb0Iyhd81j3VFkl6grwtpRtPAkB7+n+yt555fpfRKjhGU9b09cHGu7h/OcK5 -bBVCfE0DYHLI/DsXgPiF1g6Onh4rDdUu3xyv9xDKAqnscV099hHZAkEAvcFBfXZs -tk18N+bUcvXTdZjzZbfLCHlJmwPIspZ8G/6Pn63deg4GVYoCvTwGruah+8y734Ph -7PskfPgUQlB7Ag== ------END PRIVATE KEY----- diff --git a/src/core/lib/tsi/test_creds/badserver.pem b/src/core/lib/tsi/test_creds/badserver.pem deleted file mode 100644 index 983c979f31..0000000000 --- a/src/core/lib/tsi/test_creds/badserver.pem +++ /dev/null @@ -1,17 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICoDCCAgmgAwIBAgIJAPdqwqsKNy81MA0GCSqGSIb3DQEBBQUAMGkxCzAJBgNV -BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX -aWRnaXRzIFB0eSBMdGQxIjAgBgNVBAMMGWJhZHNlcnZlci50ZXN0Lmdvb2dsZS5j -b20wHhcNMTQwNzI4MjAwODU0WhcNMjQwNzI1MjAwODU0WjBpMQswCQYDVQQGEwJB -VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0 -cyBQdHkgTHRkMSIwIAYDVQQDDBliYWRzZXJ2ZXIudGVzdC5nb29nbGUuY29tMIGf -MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCnmdXtctvXJgSmlqCFMCeZ3jiVI8fn -g/950T3vnby1xHffnW9HxuUWEUdEt5hdWMLo+DyMZU1tmKa1EqBksPrXKljSM8b/ -eB48GBZJLxEdwG5V3AwYdD9swJM4Pp3/QHALDIdEKQ08q17TJYKq8o6tf75IRaHy -jDG2PmlyXRujgQIDAQABo1AwTjAdBgNVHQ4EFgQU3u/qvHr9knMBeZyAD7mAA/ec -8cUwHwYDVR0jBBgwFoAU3u/qvHr9knMBeZyAD7mAA/ec8cUwDAYDVR0TBAUwAwEB -/zANBgkqhkiG9w0BAQUFAAOBgQA/FmR1SGLguxCCfhp4CYCbrAePSyPWDi48gTwj -vVZf/OMxdVu/H8sBYFf27BjbrEugAw16DElFtgTZ83pLb2BvkUgb6vBUK5sEkgmh -z88zBsgDp8aCf4STDOLFZMBh/E9ZKkm1zogbEmlTjFp/ceSpa2gNv7OuN4WiorOh -Wvw40g== ------END CERTIFICATE----- diff --git a/src/core/lib/tsi/test_creds/ca-openssl.cnf b/src/core/lib/tsi/test_creds/ca-openssl.cnf deleted file mode 100644 index e97b945e4b..0000000000 --- a/src/core/lib/tsi/test_creds/ca-openssl.cnf +++ /dev/null @@ -1,17 +0,0 @@ -[req] -distinguished_name = req_distinguished_name -req_extensions = v3_req - -[req_distinguished_name] -countryName = Country Name (2 letter code) -countryName_default = AU -stateOrProvinceName = State or Province Name (full name) -stateOrProvinceName_default = Some-State -organizationName = Organization Name (eg, company) -organizationName_default = Internet Widgits Pty Ltd -commonName = Common Name (eg, YOUR name) -commonName_default = testca - -[v3_req] -basicConstraints = CA:true -keyUsage = critical, keyCertSign diff --git a/src/core/lib/tsi/test_creds/ca.key b/src/core/lib/tsi/test_creds/ca.key deleted file mode 100644 index 03c4f950e3..0000000000 --- a/src/core/lib/tsi/test_creds/ca.key +++ /dev/null @@ -1,16 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAMBA3wVeTGHZR1Ry -e/i+J8a2cu5gXwFV6TnObzGM7bLFCO5i9v4mLo4iFzPsHmWDUxKS3Y8iXbu0eYBl -LoNY0lSvxDx33O+DuwMmVN+DzSD+Eod9zfvwOWHsazYCZT2PhNxnVWIuJXViY4JA -HUGodjx+QAi6yCAurUZGvYXGgZSBAgMBAAECgYAxRi8i9BlFlufGSBVoGmydbJOm -bwLKl9dP3o33ODSP9hok5y6A0w5plWk3AJSF1hPLleK9VcSKYGYnt0clmPVHF35g -bx2rVK8dOT0mn7rz9Zr70jcSz1ETA2QonHZ+Y+niLmcic9At6hRtWiewblUmyFQm -GwggIzi7LOyEUHrEcQJBAOXxyQvnLvtKzXiqcsW/K6rExqVJVk+KF0fzzVyMzTJx -HRBxUVgvGdEJT7j+7P2kcTyafve0BBzDSPIaDyiJ+Y0CQQDWCb7jASFSbu5M3Zcd -Gkr4ZKN1XO3VLQX10b22bQYdF45hrTN2tnzRvVUR4q86VVnXmiGiTqmLkXcA2WWf -pHfFAkAhv9olUBo6MeF0i3frBEMRfm41hk0PwZHnMqZ6pgPcGnQMnMU2rzsXzkkQ -OwJnvAIOxhJKovZTjmofdqmw5odlAkBYVUdRWjsNUTjJwj3GRf6gyq/nFMYWz3EB -RWFdM1ttkDYzu45ctO2IhfHg4sPceDMO1s6AtKQmNI9/azkUjITdAkApNa9yFRzc -TBaDNPd5KVd58LVIzoPQ6i7uMHteLXJUWqSroji6S3s4gKMFJ/dO+ZXIlgQgfJJJ -ZDL4cdrdkeoM ------END PRIVATE KEY----- diff --git a/src/core/lib/tsi/test_creds/ca.pem b/src/core/lib/tsi/test_creds/ca.pem deleted file mode 100644 index 6c8511a73c..0000000000 --- a/src/core/lib/tsi/test_creds/ca.pem +++ /dev/null @@ -1,15 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICSjCCAbOgAwIBAgIJAJHGGR4dGioHMA0GCSqGSIb3DQEBCwUAMFYxCzAJBgNV -BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX -aWRnaXRzIFB0eSBMdGQxDzANBgNVBAMTBnRlc3RjYTAeFw0xNDExMTEyMjMxMjla -Fw0yNDExMDgyMjMxMjlaMFYxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0 -YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxDzANBgNVBAMT -BnRlc3RjYTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwEDfBV5MYdlHVHJ7 -+L4nxrZy7mBfAVXpOc5vMYztssUI7mL2/iYujiIXM+weZYNTEpLdjyJdu7R5gGUu -g1jSVK/EPHfc74O7AyZU34PNIP4Sh33N+/A5YexrNgJlPY+E3GdVYi4ldWJjgkAd -Qah2PH5ACLrIIC6tRka9hcaBlIECAwEAAaMgMB4wDAYDVR0TBAUwAwEB/zAOBgNV -HQ8BAf8EBAMCAgQwDQYJKoZIhvcNAQELBQADgYEAHzC7jdYlzAVmddi/gdAeKPau -sPBG/C2HCWqHzpCUHcKuvMzDVkY/MP2o6JIW2DBbY64bO/FceExhjcykgaYtCH/m -oIU63+CFOTtR7otyQAWHqXa7q4SbCDlG7DyRFxqG0txPtGvy12lgldA2+RgcigQG -Dfcog5wrJytaQ6UA0wE= ------END CERTIFICATE----- diff --git a/src/core/lib/tsi/test_creds/client.key b/src/core/lib/tsi/test_creds/client.key deleted file mode 100644 index f48d0735d9..0000000000 --- a/src/core/lib/tsi/test_creds/client.key +++ /dev/null @@ -1,16 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIICeQIBADANBgkqhkiG9w0BAQEFAASCAmMwggJfAgEAAoGBAOxUR9uhvhbeVUIM -s5WbH0px0mehl2+6sZpNjzvE2KimZpHzMJHukVH0Ffkvhs0b8+S5Ut9VNUAqd3IM -JCCAEGtRNoQhM1t9Yr2zAckSvbRacp+FL/Cj9eDmyo00KsVGaeefA4Dh4OW+ZhkT -NKcldXqkSuj1sEf244JZYuqZp6/tAgMBAAECgYEAi2NSVqpZMafE5YYUTcMGe6QS -k2jtpsqYgggI2RnLJ/2tNZwYI5pwP8QVSbnMaiF4gokD5hGdrNDfTnb2v+yIwYEH -0w8+oG7Z81KodsiZSIDJfTGsAZhVNwOz9y0VD8BBZZ1/274Zh52AUKLjZS/ZwIbS -W2ywya855dPnH/wj+0ECQQD9X8D920kByTNHhBG18biAEZ4pxs9f0OAG8333eVcI -w2lJDLsYDZrCB2ocgA3lUdozlzPC7YDYw8reg0tkiRY5AkEA7sdNzOeQsQRn7++5 -0bP9DtT/iON1gbfxRzCfCfXdoOtfQWIzTePWtURt9X/5D9NofI0Rg5W2oGy/MLe5 -/sXHVQJBAIup5XrJDkQywNZyAUU2ecn2bCWBFjwtqd+LBmuMciI9fOKsZtEKZrz/ -U0lkeMRoSwvXE8wmGLjjrAbdfohrXFkCQQDZEx/LtIl6JINJQiswVe0tWr6k+ASP -1WXoTm+HYpoF/XUvv9LccNF1IazFj34hwRQwhx7w/V52Ieb+p0jUMYGxAkEAjDhd -9pBO1fKXWiXzi9ZKfoyTNcUq3eBSVKwPG2nItg5ycXengjT5sgcWDnciIzW7BIVI -JiqOszq9GWESErAatg== ------END PRIVATE KEY----- diff --git a/src/core/lib/tsi/test_creds/client.pem b/src/core/lib/tsi/test_creds/client.pem deleted file mode 100644 index e332091019..0000000000 --- a/src/core/lib/tsi/test_creds/client.pem +++ /dev/null @@ -1,14 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICHzCCAYgCAQEwDQYJKoZIhvcNAQEFBQAwVjELMAkGA1UEBhMCQVUxEzARBgNV -BAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0 -ZDEPMA0GA1UEAwwGdGVzdGNhMB4XDTE0MDcxNzIzNTYwMloXDTI0MDcxNDIzNTYw -MlowWjELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM -GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDETMBEGA1UEAwwKdGVzdGNsaWVudDCB -nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA7FRH26G+Ft5VQgyzlZsfSnHSZ6GX -b7qxmk2PO8TYqKZmkfMwke6RUfQV+S+GzRvz5LlS31U1QCp3cgwkIIAQa1E2hCEz -W31ivbMByRK9tFpyn4Uv8KP14ObKjTQqxUZp558DgOHg5b5mGRM0pyV1eqRK6PWw -R/bjglli6pmnr+0CAwEAATANBgkqhkiG9w0BAQUFAAOBgQAStSm5PM7ubROiKK6/ -T2FkKlhiTOx+Ryenm3Eio59emq+jXl+1nhPySX5G2PQzSR5vd1dIhwgZSR4Gyttk -tRZ57k/NI1brUW8joiEOMJA/Mr7H7asx7wIRYDE91Fs8GkKWd5LhoPAQj+qdG35C -OO+svdkmqH0KZo320ZUqdl2ooQ== ------END CERTIFICATE----- diff --git a/src/core/lib/tsi/test_creds/server0.key b/src/core/lib/tsi/test_creds/server0.key deleted file mode 100644 index add153c9ae..0000000000 --- a/src/core/lib/tsi/test_creds/server0.key +++ /dev/null @@ -1,16 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBANOmffupIGC8YDau -rOF4eKnHwPszgpkkhWzKsVxhNDBxCVYx4TEjG0XWIO0iyRXupZbUC+7N/8HnEVNa -8F1jYhng14Iiq99cNQbbnuHHhIztmpocrJTxmnhGzoAnRa1Tb+GnAuRoIHRA/V2c -VUE9tbikQugFx/SPgXAw6tfWB+YvAgMBAAECgYEAoEq9qzUBgoHoVEGiSPiWWe8g -5p6yUA1qx2QTQyWTAwT4z0DjjfVKmG99bFsl8+hTnJFnoCp/gnjflEOROwkjp5kG -m0drqOPx1jeipJjpXYTBu49h+WpZ1PF+KhVtxsIm3OOCvh67iWaKyyOVb5Og8aiR -jl6dn/TdG/dlGD8AfUECQQDuNMle6p0oU8amC6O9wIMBroxx2nFstzE6O35PLEzG -/tj0kxxn9Jp2TS9mGaLCzSuXmpjlF4+NOWiBPkrLC2TfAkEA43Xg7uEUkaJAz2/W -m1lIBTLt+4rIQY/2emh33bDcA+rv8rwwrMMIv17/xPx7bs49YqGG5xufD+Rwl6TL -qFXYsQJAPrOwagax1aKvwJeBw3oAQhoTKAkLIEXcdGqipe6QSzVcIIz0xjxxyEAr -AOIwoLxnBCISqwMXq2H4K0UdZPMb2wJAdhdYLY1L6YRMk6XjzImg25oidisKZweA -FvMv8DgHMj2CUAqmVrt3SivfLH1M9C09L3zfFhOAFHcsgX58gav4MQJBANSBnrHj -tIq4l8z79CPUIuu3QyeEh+XwY8s5qE5CNTck0U59lzp9NvENHbkx3KO896TTerko -+8bXHMLkJkHPXms= ------END PRIVATE KEY----- diff --git a/src/core/lib/tsi/test_creds/server0.pem b/src/core/lib/tsi/test_creds/server0.pem deleted file mode 100644 index ade75d8563..0000000000 --- a/src/core/lib/tsi/test_creds/server0.pem +++ /dev/null @@ -1,14 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICHDCCAYUCAQQwDQYJKoZIhvcNAQEFBQAwVjELMAkGA1UEBhMCQVUxEzARBgNV -BAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0 -ZDEPMA0GA1UEAwwGdGVzdGNhMB4XDTE0MDcyMjE3NTk0OVoXDTI0MDcxOTE3NTk0 -OVowVzELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxFDASBgNVBAoM -C0dvb2dsZSBJbmMuMR0wGwYDVQQDDBQqLnRlc3QuZ29vZ2xlLmNvbS5hdTCBnzAN -BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA06Z9+6kgYLxgNq6s4Xh4qcfA+zOCmSSF -bMqxXGE0MHEJVjHhMSMbRdYg7SLJFe6lltQL7s3/wecRU1rwXWNiGeDXgiKr31w1 -Btue4ceEjO2amhyslPGaeEbOgCdFrVNv4acC5GggdED9XZxVQT21uKRC6AXH9I+B -cDDq19YH5i8CAwEAATANBgkqhkiG9w0BAQUFAAOBgQBtfR5qXG9TTI8YcYh7sA4V -GeNoplp0x6p7OG0NLvbJqAkUnkvjIkk1m1R2AUHhbkxzx6G75JIOoNJcWrCzywBA -BIsaTdmnNysf/s1hQJuD3IHiVb+7Ji0jhttnJlYcMid4o0tJO/a2E9YUxR+9cg0i -obb+Ql3qsvKdWBC1dDLDLw== ------END CERTIFICATE----- diff --git a/src/core/lib/tsi/test_creds/server1-openssl.cnf b/src/core/lib/tsi/test_creds/server1-openssl.cnf deleted file mode 100644 index 8a02108289..0000000000 --- a/src/core/lib/tsi/test_creds/server1-openssl.cnf +++ /dev/null @@ -1,26 +0,0 @@ -[req] -distinguished_name = req_distinguished_name -req_extensions = v3_req - -[req_distinguished_name] -countryName = Country Name (2 letter code) -countryName_default = US -stateOrProvinceName = State or Province Name (full name) -stateOrProvinceName_default = Illinois -localityName = Locality Name (eg, city) -localityName_default = Chicago -organizationName = Organization Name (eg, company) -organizationName_default = Example, Co. -commonName = Common Name (eg, YOUR name) -commonName_max = 64 - -[v3_req] -basicConstraints = CA:FALSE -keyUsage = nonRepudiation, digitalSignature, keyEncipherment -subjectAltName = @alt_names - -[alt_names] -DNS.1 = *.test.google.fr -DNS.2 = waterzooi.test.google.be -DNS.3 = *.test.youtube.com -IP.1 = "192.168.1.3" diff --git a/src/core/lib/tsi/test_creds/server1.key b/src/core/lib/tsi/test_creds/server1.key deleted file mode 100644 index 143a5b8765..0000000000 --- a/src/core/lib/tsi/test_creds/server1.key +++ /dev/null @@ -1,16 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAOHDFScoLCVJpYDD -M4HYtIdV6Ake/sMNaaKdODjDMsux/4tDydlumN+fm+AjPEK5GHhGn1BgzkWF+slf -3BxhrA/8dNsnunstVA7ZBgA/5qQxMfGAq4wHNVX77fBZOgp9VlSMVfyd9N8YwbBY -AckOeUQadTi2X1S6OgJXgQ0m3MWhAgMBAAECgYAn7qGnM2vbjJNBm0VZCkOkTIWm -V10okw7EPJrdL2mkre9NasghNXbE1y5zDshx5Nt3KsazKOxTT8d0Jwh/3KbaN+YY -tTCbKGW0pXDRBhwUHRcuRzScjli8Rih5UOCiZkhefUTcRb6xIhZJuQy71tjaSy0p -dHZRmYyBYO2YEQ8xoQJBAPrJPhMBkzmEYFtyIEqAxQ/o/A6E+E4w8i+KM7nQCK7q -K4JXzyXVAjLfyBZWHGM2uro/fjqPggGD6QH1qXCkI4MCQQDmdKeb2TrKRh5BY1LR -81aJGKcJ2XbcDu6wMZK4oqWbTX2KiYn9GB0woM6nSr/Y6iy1u145YzYxEV/iMwff -DJULAkB8B2MnyzOg0pNFJqBJuH29bKCcHa8gHJzqXhNO5lAlEbMK95p/P2Wi+4Hd -aiEIAF1BF326QJcvYKmwSmrORp85AkAlSNxRJ50OWrfMZnBgzVjDx3xG6KsFQVk2 -ol6VhqL6dFgKUORFUWBvnKSyhjJxurlPEahV6oo6+A+mPhFY8eUvAkAZQyTdupP3 -XEFQKctGz+9+gKkemDp7LBBMEMBXrGTLPhpEfcjv/7KPdnFHYmhYeBTBnuVmTVWe -F98XJ7tIFfJq ------END PRIVATE KEY----- diff --git a/src/core/lib/tsi/test_creds/server1.pem b/src/core/lib/tsi/test_creds/server1.pem deleted file mode 100644 index f3d43fcc5b..0000000000 --- a/src/core/lib/tsi/test_creds/server1.pem +++ /dev/null @@ -1,16 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICnDCCAgWgAwIBAgIBBzANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJBVTET -MBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQ -dHkgTHRkMQ8wDQYDVQQDEwZ0ZXN0Y2EwHhcNMTUxMTA0MDIyMDI0WhcNMjUxMTAx -MDIyMDI0WjBlMQswCQYDVQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNV -BAcTB0NoaWNhZ28xFTATBgNVBAoTDEV4YW1wbGUsIENvLjEaMBgGA1UEAxQRKi50 -ZXN0Lmdvb2dsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOHDFSco -LCVJpYDDM4HYtIdV6Ake/sMNaaKdODjDMsux/4tDydlumN+fm+AjPEK5GHhGn1Bg -zkWF+slf3BxhrA/8dNsnunstVA7ZBgA/5qQxMfGAq4wHNVX77fBZOgp9VlSMVfyd -9N8YwbBYAckOeUQadTi2X1S6OgJXgQ0m3MWhAgMBAAGjazBpMAkGA1UdEwQCMAAw -CwYDVR0PBAQDAgXgME8GA1UdEQRIMEaCECoudGVzdC5nb29nbGUuZnKCGHdhdGVy -em9vaS50ZXN0Lmdvb2dsZS5iZYISKi50ZXN0LnlvdXR1YmUuY29thwTAqAEDMA0G -CSqGSIb3DQEBCwUAA4GBAJFXVifQNub1LUP4JlnX5lXNlo8FxZ2a12AFQs+bzoJ6 -hM044EDjqyxUqSbVePK0ni3w1fHQB5rY9yYC5f8G7aqqTY1QOhoUk8ZTSTRpnkTh -y4jjdvTZeLDVBlueZUTDRmy2feY5aZIU18vFDK08dTG0A87pppuv1LNIR3loveU8 ------END CERTIFICATE----- diff --git a/src/core/lib/tsi/transport_security.c b/src/core/lib/tsi/transport_security.c deleted file mode 100644 index 2cbf381c88..0000000000 --- a/src/core/lib/tsi/transport_security.c +++ /dev/null @@ -1,266 +0,0 @@ -/* - * - * 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/lib/tsi/transport_security.h" - -#include <grpc/support/alloc.h> -#include <grpc/support/string_util.h> - -#include <stdlib.h> -#include <string.h> - -/* --- Tracing. --- */ - -int tsi_tracing_enabled = 0; - -/* --- 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]); - } - gpr_free(children); -} - -void tsi_peer_property_destruct(tsi_peer_property *property) { - if (property->name != NULL) { - gpr_free(property->name); - } - if (property->value.data != NULL) { - gpr_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 = gpr_strdup(name); - if (value_length > 0) { - property->value.data = gpr_zalloc(value_length); - 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 = gpr_zalloc(property_count * sizeof(tsi_peer_property)); - peer->property_count = property_count; - } - return TSI_OK; -} diff --git a/src/core/lib/tsi/transport_security.h b/src/core/lib/tsi/transport_security.h deleted file mode 100644 index aaf110ee05..0000000000 --- a/src/core/lib/tsi/transport_security.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * - * 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. - * - */ - -#ifndef GRPC_CORE_LIB_TSI_TRANSPORT_SECURITY_H -#define GRPC_CORE_LIB_TSI_TRANSPORT_SECURITY_H - -#include "src/core/lib/tsi/transport_security_interface.h" - -#ifdef __cplusplus -extern "C" { -#endif - -extern int tsi_tracing_enabled; - -/* Base for tsi_frame_protector implementations. - See transport_security_interface.h for documentation. */ -typedef struct { - tsi_result (*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); - tsi_result (*protect_flush)(tsi_frame_protector *self, - unsigned char *protected_output_frames, - size_t *protected_output_frames_size, - size_t *still_pending_size); - tsi_result (*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); - void (*destroy)(tsi_frame_protector *self); -} tsi_frame_protector_vtable; - -struct tsi_frame_protector { - const tsi_frame_protector_vtable *vtable; -}; - -/* Base for tsi_handshaker implementations. - See transport_security_interface.h for documentation. */ -typedef struct { - tsi_result (*get_bytes_to_send_to_peer)(tsi_handshaker *self, - unsigned char *bytes, - size_t *bytes_size); - tsi_result (*process_bytes_from_peer)(tsi_handshaker *self, - const unsigned char *bytes, - size_t *bytes_size); - tsi_result (*get_result)(tsi_handshaker *self); - tsi_result (*extract_peer)(tsi_handshaker *self, tsi_peer *peer); - tsi_result (*create_frame_protector)(tsi_handshaker *self, - size_t *max_protected_frame_size, - tsi_frame_protector **protector); - void (*destroy)(tsi_handshaker *self); -} tsi_handshaker_vtable; - -struct tsi_handshaker { - const tsi_handshaker_vtable *vtable; - int frame_protector_created; -}; - -/* Peer and property construction/destruction functions. */ -tsi_result tsi_construct_peer(size_t property_count, tsi_peer *peer); -tsi_peer_property tsi_init_peer_property(void); -void tsi_peer_property_destruct(tsi_peer_property *property); -tsi_result tsi_construct_string_peer_property(const char *name, - const char *value, - size_t value_length, - tsi_peer_property *property); -tsi_result tsi_construct_allocated_string_peer_property( - const char *name, size_t value_length, tsi_peer_property *property); -tsi_result tsi_construct_string_peer_property_from_cstring( - const char *name, const char *value, tsi_peer_property *property); - -/* Utils. */ -char *tsi_strdup(const char *src); /* Sadly, no strdup in C89. */ - -#ifdef __cplusplus -} -#endif - -#endif /* GRPC_CORE_LIB_TSI_TRANSPORT_SECURITY_H */ diff --git a/src/core/lib/tsi/transport_security_interface.h b/src/core/lib/tsi/transport_security_interface.h deleted file mode 100644 index 3e8c9d7ffe..0000000000 --- a/src/core/lib/tsi/transport_security_interface.h +++ /dev/null @@ -1,353 +0,0 @@ -/* - * - * 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. - * - */ - -#ifndef GRPC_CORE_LIB_TSI_TRANSPORT_SECURITY_INTERFACE_H -#define GRPC_CORE_LIB_TSI_TRANSPORT_SECURITY_INTERFACE_H - -#include <stdint.h> -#include <stdlib.h> - -#ifdef __cplusplus -extern "C" { -#endif - -/* --- tsi result --- */ - -typedef enum { - TSI_OK = 0, - TSI_UNKNOWN_ERROR = 1, - TSI_INVALID_ARGUMENT = 2, - TSI_PERMISSION_DENIED = 3, - TSI_INCOMPLETE_DATA = 4, - TSI_FAILED_PRECONDITION = 5, - TSI_UNIMPLEMENTED = 6, - TSI_INTERNAL_ERROR = 7, - TSI_DATA_CORRUPTED = 8, - TSI_NOT_FOUND = 9, - TSI_PROTOCOL_FAILURE = 10, - TSI_HANDSHAKE_IN_PROGRESS = 11, - TSI_OUT_OF_RESOURCES = 12 -} tsi_result; - -typedef enum { - // Default option - TSI_DONT_REQUEST_CLIENT_CERTIFICATE, - TSI_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY, - TSI_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY, - TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY, - TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY, -} tsi_client_certificate_request_type; - -const char *tsi_result_to_string(tsi_result result); - -/* --- tsi tracing --- */ - -/* Set this early to avoid races */ -extern int tsi_tracing_enabled; - -/* --- tsi_frame_protector object --- - - This object protects and unprotects buffers once the handshake is done. - Implementations of this object must be thread compatible. */ - -typedef struct tsi_frame_protector tsi_frame_protector; - -/* Outputs protected frames. - - unprotected_bytes is an input only parameter and points to the data - to be protected. - - unprotected_bytes_size is an input/output parameter used by the caller to - specify how many bytes are available in unprotected_bytes. The output - value is the number of bytes consumed during the call. - - protected_output_frames points to a buffer allocated by the caller that - will be written. - - protected_output_frames_size is an input/output parameter used by the - caller to specify how many bytes are available in protected_output_frames. - As an output, this value indicates the number of bytes written. - - This method returns TSI_OK in case of success or a specific error code in - case of failure. Note that even if all the input unprotected bytes are - consumed, they may not have been processed into the returned protected - output frames. The caller should call the protect_flush method - to make sure that there are no more protected bytes buffered in the - protector. - - A typical way to call this method would be: - - ------------------------------------------------------------------------ - unsigned char protected_buffer[4096]; - size_t protected_buffer_size = sizeof(protected_buffer); - tsi_result result = TSI_OK; - while (message_size > 0) { - size_t protected_buffer_size_to_send = protected_buffer_size; - size_t processed_message_size = message_size; - result = tsi_frame_protector_protect(protector, - message_bytes, - &processed_message_size, - protected_buffer, - &protected_buffer_size_to_send); - if (result != TSI_OK) break; - send_bytes_to_peer(protected_buffer, protected_buffer_size_to_send); - message_bytes += processed_message_size; - message_size -= processed_message_size; - - // Don't forget to flush. - if (message_size == 0) { - size_t still_pending_size; - do { - protected_buffer_size_to_send = protected_buffer_size; - result = tsi_frame_protector_protect_flush( - protector, protected_buffer, - &protected_buffer_size_to_send, &still_pending_size); - if (result != TSI_OK) break; - send_bytes_to_peer(protected_buffer, protected_buffer_size_to_send); - } while (still_pending_size > 0); - } - } - - if (result != TSI_OK) HandleError(result); - ------------------------------------------------------------------------ */ -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); - -/* Indicates that we need to flush the bytes buffered in the protector and get - the resulting frame. - - protected_output_frames points to a buffer allocated by the caller that - will be written. - - protected_output_frames_size is an input/output parameter used by the - caller to specify how many bytes are available in protected_output_frames. - - still_pending_bytes is an output parameter indicating the number of bytes - that still need to be flushed from the protector.*/ -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); - -/* Outputs unprotected bytes. - - protected_frames_bytes is an input only parameter and points to the - protected frames to be unprotected. - - protected_frames_bytes_size is an input/output only parameter used by the - caller to specify how many bytes are available in protected_bytes. The - output value is the number of bytes consumed during the call. - Implementations will buffer up to a frame of protected data. - - unprotected_bytes points to a buffer allocated by the caller that will be - written. - - unprotected_bytes_size is an input/output parameter used by the caller to - specify how many bytes are available in unprotected_bytes. This - value is expected to be at most max_protected_frame_size minus overhead - which means that max_protected_frame_size is a safe bet. The output value - is the number of bytes actually written. - If *unprotected_bytes_size is unchanged, there may be more data remaining - to unprotect, and the caller should call this function again. - - - This method returns TSI_OK in case of success. Success includes cases where - there is not enough data to output a frame in which case - unprotected_bytes_size will be set to 0 and cases where the internal buffer - needs to be read before new protected data can be processed in which case - protected_frames_size will be set to 0. */ -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); - -/* Destroys the tsi_frame_protector object. */ -void tsi_frame_protector_destroy(tsi_frame_protector *self); - -/* --- tsi_peer objects --- - - tsi_peer objects are a set of properties. The peer owns the properties. */ - -/* This property is of type TSI_PEER_PROPERTY_STRING. */ -#define TSI_CERTIFICATE_TYPE_PEER_PROPERTY "certificate_type" - -/* Property values may contain NULL characters just like C++ strings. - The length field gives the length of the string. */ -typedef struct tsi_peer_property { - char *name; - struct { - char *data; - size_t length; - } value; -} tsi_peer_property; - -typedef struct { - tsi_peer_property *properties; - size_t property_count; -} tsi_peer; - -/* Destructs the tsi_peer object. */ -void tsi_peer_destruct(tsi_peer *self); - -/* --- tsi_handshaker objects ---- - - Implementations of this object must be thread compatible. - - A typical usage of this object would be: - - ------------------------------------------------------------------------ - tsi_result result = TSI_OK; - unsigned char buf[4096]; - size_t buf_offset; - size_t buf_size; - while (1) { - // See if we need to send some bytes to the peer. - do { - size_t buf_size_to_send = sizeof(buf); - result = tsi_handshaker_get_bytes_to_send_to_peer(handshaker, buf, - &buf_size_to_send); - if (buf_size_to_send > 0) send_bytes_to_peer(buf, buf_size_to_send); - } while (result == TSI_INCOMPLETE_DATA); - if (result != TSI_OK) return result; - if (!tsi_handshaker_is_in_progress(handshaker)) break; - - do { - // Read bytes from the peer. - buf_size = sizeof(buf); - buf_offset = 0; - read_bytes_from_peer(buf, &buf_size); - if (buf_size == 0) break; - - // Process the bytes from the peer. We have to be careful as these bytes - // may contain non-handshake data (protected data). If this is the case, - // we will exit from the loop with buf_size > 0. - size_t consumed_by_handshaker = buf_size; - result = tsi_handshaker_process_bytes_from_peer( - handshaker, buf, &consumed_by_handshaker); - buf_size -= consumed_by_handshaker; - buf_offset += consumed_by_handshaker; - } while (result == TSI_INCOMPLETE_DATA); - - if (result != TSI_OK) return result; - if (!tsi_handshaker_is_in_progress(handshaker)) break; - } - - // Check the Peer. - tsi_peer peer; - do { - result = tsi_handshaker_extract_peer(handshaker, &peer); - if (result != TSI_OK) break; - result = check_peer(&peer); - } while (0); - tsi_peer_destruct(&peer); - if (result != TSI_OK) return result; - - // Create the protector. - tsi_frame_protector* protector = NULL; - result = tsi_handshaker_create_frame_protector(handshaker, NULL, - &protector); - if (result != TSI_OK) return result; - - // Do not forget to unprotect outstanding data if any. - if (buf_size > 0) { - result = tsi_frame_protector_unprotect(protector, buf + buf_offset, - buf_size, ..., ...); - .... - } - ... - ------------------------------------------------------------------------ */ -typedef struct tsi_handshaker tsi_handshaker; - -/* Gets bytes that need to be sent to the peer. - - bytes is the buffer that will be written with the data to be sent to the - peer. - - bytes_size is an input/output parameter specifying the capacity of the - bytes parameter as input and the number of bytes written as output. - Returns TSI_OK if all the data to send to the peer has been written or if - nothing has to be sent to the peer (in which base bytes_size outputs to 0), - otherwise returns TSI_INCOMPLETE_DATA which indicates that this method - needs to be called again to get all the bytes to send to the peer (there - was more data to write than the specified bytes_size). In case of a fatal - error in the handshake, another specific error code is returned. */ -tsi_result tsi_handshaker_get_bytes_to_send_to_peer(tsi_handshaker *self, - unsigned char *bytes, - size_t *bytes_size); - -/* Processes bytes received from the peer. - - bytes is the buffer containing the data. - - bytes_size is an input/output parameter specifying the size of the data as - input and the number of bytes consumed as output. - Return TSI_OK if the handshake has all the data it needs to process, - otherwise return TSI_INCOMPLETE_DATA which indicates that this method - needs to be called again to complete the data needed for processing. In - case of a fatal error in the handshake, another specific error code is - returned. */ -tsi_result tsi_handshaker_process_bytes_from_peer(tsi_handshaker *self, - const unsigned char *bytes, - size_t *bytes_size); - -/* Gets the result of the handshaker. - Returns TSI_OK if the hanshake completed successfully and there has been no - errors. Returns TSI_HANDSHAKE_IN_PROGRESS if the handshaker is not done yet - but no error has been encountered so far. Otherwise the handshaker failed - with the returned error. */ -tsi_result tsi_handshaker_get_result(tsi_handshaker *self); - -/* Returns 1 if the handshake is in progress, 0 otherwise. */ -#define tsi_handshaker_is_in_progress(h) \ - (tsi_handshaker_get_result((h)) == TSI_HANDSHAKE_IN_PROGRESS) - -/* This method may return TSI_FAILED_PRECONDITION if - tsi_handshaker_is_in_progress returns 1, it returns TSI_OK otherwise - assuming the handshaker is not in a fatal error state. - The caller is responsible for destructing the peer. */ -tsi_result tsi_handshaker_extract_peer(tsi_handshaker *self, tsi_peer *peer); - -/* This method creates a tsi_frame_protector object after the handshake phase - is done. After this method has been called successfully, the only method - that can be called on this object is Destroy. - - max_output_protected_frame_size is an input/output parameter specifying the - desired max output protected frame size as input and outputing the actual - max output frame size as the output. Passing NULL is OK and will result in - the implementation choosing the default maximum protected frame size. Note - that this size only applies to outgoing frames (generated with - tsi_frame_protector_protect) and not incoming frames (input of - tsi_frame_protector_unprotect). - - protector is an output parameter pointing to the newly created - tsi_frame_protector object. - This method may return TSI_FAILED_PRECONDITION if - tsi_handshaker_is_in_progress returns 1, it returns TSI_OK otherwise assuming - the handshaker is not in a fatal error state. - The caller is responsible for destroying the protector. */ -tsi_result tsi_handshaker_create_frame_protector( - tsi_handshaker *self, size_t *max_output_protected_frame_size, - tsi_frame_protector **protector); - -/* This method releases the tsi_handshaker object. After this method is called, - no other method can be called on the object. */ -void tsi_handshaker_destroy(tsi_handshaker *self); - -#ifdef __cplusplus -} -#endif - -#endif /* GRPC_CORE_LIB_TSI_TRANSPORT_SECURITY_INTERFACE_H */ |