diff --git a/BUILD b/BUILD index 1cf4782eaf787077b161b496126adfc5e11b4170..d6598487fbab566e0859d55a5c8bb77debdd9344 100644 --- a/BUILD +++ b/BUILD @@ -511,6 +511,7 @@ grpc_cc_library( "src/core/lib/json/json_reader.c", "src/core/lib/json/json_string.c", "src/core/lib/json/json_writer.c", + "src/core/lib/security/util/b64.c", "src/core/lib/slice/percent_encoding.c", "src/core/lib/slice/slice.c", "src/core/lib/slice/slice_buffer.c", @@ -629,6 +630,7 @@ grpc_cc_library( "src/core/lib/json/json_common.h", "src/core/lib/json/json_reader.h", "src/core/lib/json/json_writer.h", + "src/core/lib/security/util/b64.h", "src/core/lib/slice/percent_encoding.h", "src/core/lib/slice/slice_hash_table.h", "src/core/lib/slice/slice_internal.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index dac4095a5452ee515c4052ccee47c5aa45cfc902..c9d0098539df42bddbcb30bd31c882a9af9d37a1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -993,6 +993,7 @@ add_library(grpc src/core/lib/json/json_reader.c src/core/lib/json/json_string.c src/core/lib/json/json_writer.c + src/core/lib/security/util/b64.c src/core/lib/slice/percent_encoding.c src/core/lib/slice/slice.c src/core/lib/slice/slice_buffer.c @@ -1075,7 +1076,6 @@ add_library(grpc src/core/lib/security/transport/security_handshaker.c src/core/lib/security/transport/server_auth_filter.c src/core/lib/security/transport/tsi_error.c - src/core/lib/security/util/b64.c src/core/lib/security/util/json_util.c src/core/lib/surface/init_secure.c src/core/lib/tsi/fake_transport_security.c @@ -1314,6 +1314,7 @@ add_library(grpc_cronet src/core/lib/json/json_reader.c src/core/lib/json/json_string.c src/core/lib/json/json_writer.c + src/core/lib/security/util/b64.c src/core/lib/slice/percent_encoding.c src/core/lib/slice/slice.c src/core/lib/slice/slice_buffer.c @@ -1419,7 +1420,6 @@ add_library(grpc_cronet src/core/lib/security/transport/security_handshaker.c src/core/lib/security/transport/server_auth_filter.c src/core/lib/security/transport/tsi_error.c - src/core/lib/security/util/b64.c src/core/lib/security/util/json_util.c src/core/lib/surface/init_secure.c src/core/lib/tsi/fake_transport_security.c @@ -1622,6 +1622,7 @@ add_library(grpc_test_util src/core/lib/json/json_reader.c src/core/lib/json/json_string.c src/core/lib/json/json_writer.c + src/core/lib/security/util/b64.c src/core/lib/slice/percent_encoding.c src/core/lib/slice/slice.c src/core/lib/slice/slice_buffer.c @@ -1881,6 +1882,7 @@ add_library(grpc_unsecure src/core/lib/json/json_reader.c src/core/lib/json/json_string.c src/core/lib/json/json_writer.c + src/core/lib/security/util/b64.c src/core/lib/slice/percent_encoding.c src/core/lib/slice/slice.c src/core/lib/slice/slice_buffer.c @@ -2511,6 +2513,7 @@ add_library(grpc++_cronet src/core/lib/json/json_reader.c src/core/lib/json/json_string.c src/core/lib/json/json_writer.c + src/core/lib/security/util/b64.c src/core/lib/slice/percent_encoding.c src/core/lib/slice/slice.c src/core/lib/slice/slice_buffer.c diff --git a/Makefile b/Makefile index 4985907f5c1e9d34f0906beb5d2100f231c642db..ddd1ffb19165092c541af464e901d7bd593e9384 100644 --- a/Makefile +++ b/Makefile @@ -2887,6 +2887,7 @@ LIBGRPC_SRC = \ src/core/lib/json/json_reader.c \ src/core/lib/json/json_string.c \ src/core/lib/json/json_writer.c \ + src/core/lib/security/util/b64.c \ src/core/lib/slice/percent_encoding.c \ src/core/lib/slice/slice.c \ src/core/lib/slice/slice_buffer.c \ @@ -2969,7 +2970,6 @@ LIBGRPC_SRC = \ src/core/lib/security/transport/security_handshaker.c \ src/core/lib/security/transport/server_auth_filter.c \ src/core/lib/security/transport/tsi_error.c \ - src/core/lib/security/util/b64.c \ src/core/lib/security/util/json_util.c \ src/core/lib/surface/init_secure.c \ src/core/lib/tsi/fake_transport_security.c \ @@ -3206,6 +3206,7 @@ LIBGRPC_CRONET_SRC = \ src/core/lib/json/json_reader.c \ src/core/lib/json/json_string.c \ src/core/lib/json/json_writer.c \ + src/core/lib/security/util/b64.c \ src/core/lib/slice/percent_encoding.c \ src/core/lib/slice/slice.c \ src/core/lib/slice/slice_buffer.c \ @@ -3311,7 +3312,6 @@ LIBGRPC_CRONET_SRC = \ src/core/lib/security/transport/security_handshaker.c \ src/core/lib/security/transport/server_auth_filter.c \ src/core/lib/security/transport/tsi_error.c \ - src/core/lib/security/util/b64.c \ src/core/lib/security/util/json_util.c \ src/core/lib/surface/init_secure.c \ src/core/lib/tsi/fake_transport_security.c \ @@ -3513,6 +3513,7 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/lib/json/json_reader.c \ src/core/lib/json/json_string.c \ src/core/lib/json/json_writer.c \ + src/core/lib/security/util/b64.c \ src/core/lib/slice/percent_encoding.c \ src/core/lib/slice/slice.c \ src/core/lib/slice/slice_buffer.c \ @@ -3744,6 +3745,7 @@ LIBGRPC_UNSECURE_SRC = \ src/core/lib/json/json_reader.c \ src/core/lib/json/json_string.c \ src/core/lib/json/json_writer.c \ + src/core/lib/security/util/b64.c \ src/core/lib/slice/percent_encoding.c \ src/core/lib/slice/slice.c \ src/core/lib/slice/slice_buffer.c \ @@ -4360,6 +4362,7 @@ LIBGRPC++_CRONET_SRC = \ src/core/lib/json/json_reader.c \ src/core/lib/json/json_string.c \ src/core/lib/json/json_writer.c \ + src/core/lib/security/util/b64.c \ src/core/lib/slice/percent_encoding.c \ src/core/lib/slice/slice.c \ src/core/lib/slice/slice_buffer.c \ @@ -18806,7 +18809,6 @@ src/core/lib/security/transport/security_connector.c: $(OPENSSL_DEP) src/core/lib/security/transport/security_handshaker.c: $(OPENSSL_DEP) src/core/lib/security/transport/server_auth_filter.c: $(OPENSSL_DEP) src/core/lib/security/transport/tsi_error.c: $(OPENSSL_DEP) -src/core/lib/security/util/b64.c: $(OPENSSL_DEP) src/core/lib/security/util/json_util.c: $(OPENSSL_DEP) src/core/lib/surface/init_secure.c: $(OPENSSL_DEP) src/core/lib/tsi/fake_transport_security.c: $(OPENSSL_DEP) diff --git a/binding.gyp b/binding.gyp index 26904ae2f7b7d645714848bf2d2851df09b116d8..b91f5f61e21a367f346c9cd85b803a3f7b06e851 100644 --- a/binding.gyp +++ b/binding.gyp @@ -700,6 +700,7 @@ 'src/core/lib/json/json_reader.c', 'src/core/lib/json/json_string.c', 'src/core/lib/json/json_writer.c', + 'src/core/lib/security/util/b64.c', 'src/core/lib/slice/percent_encoding.c', 'src/core/lib/slice/slice.c', 'src/core/lib/slice/slice_buffer.c', @@ -782,7 +783,6 @@ 'src/core/lib/security/transport/security_handshaker.c', 'src/core/lib/security/transport/server_auth_filter.c', 'src/core/lib/security/transport/tsi_error.c', - 'src/core/lib/security/util/b64.c', 'src/core/lib/security/util/json_util.c', 'src/core/lib/surface/init_secure.c', 'src/core/lib/tsi/fake_transport_security.c', diff --git a/build.yaml b/build.yaml index b11a3cf3190ed8d9de1deca2a7763a7364d4ff89..c0587331411c0b64a4065ae65b935b94dfd0d21c 100644 --- a/build.yaml +++ b/build.yaml @@ -369,6 +369,7 @@ filegroups: - src/core/lib/json/json_reader.c - src/core/lib/json/json_string.c - src/core/lib/json/json_writer.c + - src/core/lib/security/util/b64.c - src/core/lib/slice/percent_encoding.c - src/core/lib/slice/slice.c - src/core/lib/slice/slice_buffer.c diff --git a/config.m4 b/config.m4 index 94e3ba1ab59e8ecf1abe32c17ad66f1143cb374b..b6f0bff7ef0bdb068c2a08425331ca04d408d583 100644 --- a/config.m4 +++ b/config.m4 @@ -168,6 +168,7 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/json/json_reader.c \ src/core/lib/json/json_string.c \ src/core/lib/json/json_writer.c \ + src/core/lib/security/util/b64.c \ src/core/lib/slice/percent_encoding.c \ src/core/lib/slice/slice.c \ src/core/lib/slice/slice_buffer.c \ @@ -250,7 +251,6 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/security/transport/security_handshaker.c \ src/core/lib/security/transport/server_auth_filter.c \ src/core/lib/security/transport/tsi_error.c \ - src/core/lib/security/util/b64.c \ src/core/lib/security/util/json_util.c \ src/core/lib/surface/init_secure.c \ src/core/lib/tsi/fake_transport_security.c \ diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index f9408ab1dbc1808f9bc49d1dbe6ee991dd34b668..8ea9e5fbdec53cb85a4b5ad854b0732b7732897f 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -543,6 +543,7 @@ Pod::Spec.new do |s| 'src/core/lib/json/json_reader.c', 'src/core/lib/json/json_string.c', 'src/core/lib/json/json_writer.c', + 'src/core/lib/security/util/b64.c', 'src/core/lib/slice/percent_encoding.c', 'src/core/lib/slice/slice.c', 'src/core/lib/slice/slice_buffer.c', @@ -625,7 +626,6 @@ Pod::Spec.new do |s| 'src/core/lib/security/transport/security_handshaker.c', 'src/core/lib/security/transport/server_auth_filter.c', 'src/core/lib/security/transport/tsi_error.c', - 'src/core/lib/security/util/b64.c', 'src/core/lib/security/util/json_util.c', 'src/core/lib/surface/init_secure.c', 'src/core/lib/tsi/fake_transport_security.c', diff --git a/grpc.gemspec b/grpc.gemspec index 46097cb4e70ce3b391adfd036a6817f032c0b0ae..06da332bed5b5cb4ce3f30b321414aaee6f84b24 100755 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -459,6 +459,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/json/json_reader.c ) s.files += %w( src/core/lib/json/json_string.c ) s.files += %w( src/core/lib/json/json_writer.c ) + s.files += %w( src/core/lib/security/util/b64.c ) s.files += %w( src/core/lib/slice/percent_encoding.c ) s.files += %w( src/core/lib/slice/slice.c ) s.files += %w( src/core/lib/slice/slice_buffer.c ) @@ -541,7 +542,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/security/transport/security_handshaker.c ) s.files += %w( src/core/lib/security/transport/server_auth_filter.c ) s.files += %w( src/core/lib/security/transport/tsi_error.c ) - s.files += %w( src/core/lib/security/util/b64.c ) s.files += %w( src/core/lib/security/util/json_util.c ) s.files += %w( src/core/lib/surface/init_secure.c ) s.files += %w( src/core/lib/tsi/fake_transport_security.c ) diff --git a/package.xml b/package.xml index f9407bb3edd21d78b563f5a0343e90cb8f248a70..5d585845556eb652f7bd812e02855eefe956de28 100644 --- a/package.xml +++ b/package.xml @@ -468,6 +468,7 @@ <file baseinstalldir="/" name="src/core/lib/json/json_reader.c" role="src" /> <file baseinstalldir="/" name="src/core/lib/json/json_string.c" role="src" /> <file baseinstalldir="/" name="src/core/lib/json/json_writer.c" role="src" /> + <file baseinstalldir="/" name="src/core/lib/security/util/b64.c" role="src" /> <file baseinstalldir="/" name="src/core/lib/slice/percent_encoding.c" role="src" /> <file baseinstalldir="/" name="src/core/lib/slice/slice.c" role="src" /> <file baseinstalldir="/" name="src/core/lib/slice/slice_buffer.c" role="src" /> @@ -550,7 +551,6 @@ <file baseinstalldir="/" name="src/core/lib/security/transport/security_handshaker.c" role="src" /> <file baseinstalldir="/" name="src/core/lib/security/transport/server_auth_filter.c" role="src" /> <file baseinstalldir="/" name="src/core/lib/security/transport/tsi_error.c" role="src" /> - <file baseinstalldir="/" name="src/core/lib/security/util/b64.c" role="src" /> <file baseinstalldir="/" name="src/core/lib/security/util/json_util.c" role="src" /> <file baseinstalldir="/" name="src/core/lib/surface/init_secure.c" role="src" /> <file baseinstalldir="/" name="src/core/lib/tsi/fake_transport_security.c" role="src" /> diff --git a/src/core/lib/channel/http_client_filter.c b/src/core/lib/channel/http_client_filter.c index 028e9a5d04e0468779352e29b78638fc7dca31ca..967904df1eeb40d249b81f778b12f73a7f7f58ee 100644 --- a/src/core/lib/channel/http_client_filter.c +++ b/src/core/lib/channel/http_client_filter.c @@ -36,6 +36,7 @@ #include <grpc/support/string_util.h> #include <string.h> #include "src/core/lib/profiling/timers.h" +#include "src/core/lib/security/util/b64.h" #include "src/core/lib/slice/percent_encoding.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/slice/slice_string_helpers.h" @@ -56,7 +57,6 @@ typedef struct call_data { grpc_linked_mdelem te_trailers; grpc_linked_mdelem content_type; grpc_linked_mdelem user_agent; - grpc_linked_mdelem payload_bin; grpc_metadata_batch *recv_initial_metadata; grpc_metadata_batch *recv_trailing_metadata; @@ -292,19 +292,58 @@ static grpc_error *hc_mutate_op(grpc_exec_ctx *exec_ctx, continue_send_message(exec_ctx, elem); if (calld->send_message_blocked == false) { - /* when all the send_message data is available, then create a MDELEM and - append to headers */ - grpc_mdelem payload_bin = grpc_mdelem_from_slices( - exec_ctx, GRPC_MDSTR_GRPC_PAYLOAD_BIN, - grpc_slice_from_copied_buffer((const char *)calld->payload_bytes, - op->send_message->length)); - error = - grpc_metadata_batch_add_tail(exec_ctx, op->send_initial_metadata, - &calld->payload_bin, payload_bin); + /* when all the send_message data is available, then modify the path + * MDELEM by appending base64 encoded query to the path */ + const int k_url_safe = 1; + const int k_multi_line = 0; + const unsigned char k_query_separator = '?'; + + grpc_slice path_slice = + GRPC_MDVALUE(op->send_initial_metadata->idx.named.path->md); + /* sum up individual component's lengths and allocate enough memory to + * hold combined path+query */ + size_t estimated_len = GRPC_SLICE_LENGTH(path_slice); + estimated_len++; /* for the '?' */ + estimated_len += grpc_base64_estimate_encoded_size( + op->send_message->length, k_url_safe, k_multi_line); + estimated_len += 1; /* for the trailing 0 */ + grpc_slice path_with_query_slice = grpc_slice_malloc(estimated_len); + + /* memcopy individual pieces into this slice */ + uint8_t *write_ptr = + (uint8_t *)GRPC_SLICE_START_PTR(path_with_query_slice); + uint8_t *original_path = (uint8_t *)GRPC_SLICE_START_PTR(path_slice); + memcpy(write_ptr, original_path, GRPC_SLICE_LENGTH(path_slice)); + write_ptr += GRPC_SLICE_LENGTH(path_slice); + + *write_ptr = k_query_separator; + write_ptr++; /* for the '?' */ + + grpc_base64_encode_core((char *)write_ptr, calld->payload_bytes, + op->send_message->length, k_url_safe, + k_multi_line); + + /* remove trailing unused memory and add trailing 0 to terminate string + */ + char *t = (char *)GRPC_SLICE_START_PTR(path_with_query_slice); + /* safe to use strlen since base64_encode will always add '\0' */ + size_t path_length = strlen(t) + 1; + *(t + path_length) = '\0'; + path_with_query_slice = + grpc_slice_sub(path_with_query_slice, 0, path_length); + + /* substitute previous path with the new path+query */ + grpc_mdelem mdelem_path_and_query = grpc_mdelem_from_slices( + exec_ctx, GRPC_MDSTR_PATH, path_with_query_slice); + grpc_metadata_batch *b = op->send_initial_metadata; + error = grpc_metadata_batch_substitute(exec_ctx, b, b->idx.named.path, + mdelem_path_and_query); if (error != GRPC_ERROR_NONE) return error; + calld->on_complete = op->on_complete; op->on_complete = &calld->hc_on_complete; op->send_message = NULL; + grpc_slice_unref_internal(exec_ctx, path_with_query_slice); } else { /* Not all data is available. Fall back to POST. */ gpr_log(GPR_DEBUG, diff --git a/src/core/lib/channel/http_server_filter.c b/src/core/lib/channel/http_server_filter.c index 41a325bc04b6e5a866dee602176f46f0216bf2f2..8d3c488ea0ace4415f7888aec77ad422fdad4a74 100644 --- a/src/core/lib/channel/http_server_filter.c +++ b/src/core/lib/channel/http_server_filter.c @@ -37,6 +37,7 @@ #include <grpc/support/log.h> #include <string.h> #include "src/core/lib/profiling/timers.h" +#include "src/core/lib/security/util/b64.h" #include "src/core/lib/slice/percent_encoding.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/slice/slice_string_helpers.h" @@ -51,8 +52,8 @@ typedef struct call_data { grpc_linked_mdelem status; grpc_linked_mdelem content_type; - /* did this request come with payload-bin */ - bool seen_payload_bin; + /* did this request come with path query containing request payload */ + bool seen_path_with_query; /* flag to ensure payload_bin is delivered only once */ bool payload_bin_delivered; @@ -61,7 +62,7 @@ typedef struct call_data { bool *recv_cacheable_request; /** Closure to call when finished with the hs_on_recv hook */ grpc_closure *on_done_recv; - /** Closure to call when we retrieve read message from the payload-bin header + /** Closure to call when we retrieve read message from the path URI */ grpc_closure *recv_message_ready; grpc_closure *on_complete; @@ -205,6 +206,43 @@ static grpc_error *server_filter_incoming_metadata(grpc_exec_ctx *exec_ctx, grpc_error_set_str( GRPC_ERROR_CREATE_FROM_STATIC_STRING("Missing header"), GRPC_ERROR_STR_KEY, grpc_slice_from_static_string(":path"))); + } else if (*calld->recv_cacheable_request == true) { + /* We have a cacheable request made with GET verb. The path contains the + * query parameter which is base64 encoded request payload. */ + const char k_query_separator = '?'; + grpc_slice path_slice = GRPC_MDVALUE(b->idx.named.path->md); + uint8_t *path_ptr = (uint8_t *)GRPC_SLICE_START_PTR(path_slice); + size_t path_length = GRPC_SLICE_LENGTH(path_slice); + /* offset of the character '?' */ + size_t offset = 0; + for (offset = 0; *path_ptr != k_query_separator && offset < path_length; + path_ptr++, offset++) + ; + if (offset < path_length) { + grpc_slice query_slice = + grpc_slice_sub(path_slice, offset + 1, path_length); + + /* substitute path metadata with just the path (not query) */ + grpc_mdelem mdelem_path_without_query = grpc_mdelem_from_slices( + exec_ctx, GRPC_MDSTR_PATH, grpc_slice_sub(path_slice, 0, offset)); + + grpc_metadata_batch_substitute(exec_ctx, b, b->idx.named.path, + mdelem_path_without_query); + + /* decode payload from query and add to the slice buffer to be returned */ + const int k_url_safe = 1; + grpc_slice_buffer_add( + &calld->read_slice_buffer, + grpc_base64_decode(exec_ctx, + (const char *)GRPC_SLICE_START_PTR(query_slice), + k_url_safe)); + grpc_slice_buffer_stream_init(&calld->read_stream, + &calld->read_slice_buffer, 0); + calld->seen_path_with_query = true; + grpc_slice_unref_internal(exec_ctx, query_slice); + } else { + gpr_log(GPR_ERROR, "GET request without QUERY"); + } } if (b->idx.named.host != NULL && b->idx.named.authority == NULL) { @@ -228,16 +266,6 @@ static grpc_error *server_filter_incoming_metadata(grpc_exec_ctx *exec_ctx, GRPC_ERROR_STR_KEY, grpc_slice_from_static_string(":authority"))); } - if (b->idx.named.grpc_payload_bin != NULL) { - calld->seen_payload_bin = true; - grpc_slice_buffer_add(&calld->read_slice_buffer, - grpc_slice_ref_internal( - GRPC_MDVALUE(b->idx.named.grpc_payload_bin->md))); - grpc_slice_buffer_stream_init(&calld->read_stream, - &calld->read_slice_buffer, 0); - grpc_metadata_batch_remove(exec_ctx, b, b->idx.named.grpc_payload_bin); - } - return error; } @@ -258,8 +286,8 @@ static void hs_on_complete(grpc_exec_ctx *exec_ctx, void *user_data, grpc_error *err) { grpc_call_element *elem = user_data; call_data *calld = elem->call_data; - /* Call recv_message_ready if we got the payload via the header field */ - if (calld->seen_payload_bin && calld->recv_message_ready != NULL) { + /* Call recv_message_ready if we got the payload via the path field */ + if (calld->seen_path_with_query && calld->recv_message_ready != NULL) { *calld->pp_recv_message = calld->payload_bin_delivered ? NULL : (grpc_byte_stream *)&calld->read_stream; @@ -274,7 +302,7 @@ static void hs_recv_message_ready(grpc_exec_ctx *exec_ctx, void *user_data, grpc_error *err) { grpc_call_element *elem = user_data; call_data *calld = elem->call_data; - if (calld->seen_payload_bin) { + if (calld->seen_path_with_query) { /* do nothing. This is probably a GET request, and payload will be returned in hs_on_complete callback. */ } else { diff --git a/src/core/lib/security/util/b64.c b/src/core/lib/security/util/b64.c index 09c821313162069aaaccaede30609d0d9447e5b6..0d5a9176602c876477e512c658cc95c2e6666960 100644 --- a/src/core/lib/security/util/b64.c +++ b/src/core/lib/security/util/b64.c @@ -71,15 +71,31 @@ static const char base64_url_safe_chars[] = char *grpc_base64_encode(const void *vdata, size_t data_size, int url_safe, int multiline) { - const unsigned char *data = vdata; - const char *base64_chars = - url_safe ? base64_url_safe_chars : base64_url_unsafe_chars; + size_t result_projected_size = + grpc_base64_estimate_encoded_size(data_size, url_safe, multiline); + char *result = gpr_malloc(result_projected_size); + grpc_base64_encode_core(result, vdata, data_size, url_safe, multiline); + return result; +} + +size_t grpc_base64_estimate_encoded_size(size_t data_size, int url_safe, + int multiline) { size_t result_projected_size = 4 * ((data_size + 3) / 3) + 2 * (multiline ? (data_size / (3 * GRPC_BASE64_MULTILINE_NUM_BLOCKS)) : 0) + 1; - char *result = gpr_malloc(result_projected_size); + return result_projected_size; +} + +void grpc_base64_encode_core(char *result, const void *vdata, size_t data_size, + int url_safe, int multiline) { + const unsigned char *data = vdata; + const char *base64_chars = + url_safe ? base64_url_safe_chars : base64_url_unsafe_chars; + const size_t result_projected_size = + grpc_base64_estimate_encoded_size(data_size, url_safe, multiline); + char *current = result; size_t num_blocks = 0; size_t i = 0; @@ -119,7 +135,6 @@ char *grpc_base64_encode(const void *vdata, size_t data_size, int url_safe, GPR_ASSERT(current >= result); GPR_ASSERT((uintptr_t)(current - result) < result_projected_size); result[current - result] = '\0'; - return result; } grpc_slice grpc_base64_decode(grpc_exec_ctx *exec_ctx, const char *b64, diff --git a/src/core/lib/security/util/b64.h b/src/core/lib/security/util/b64.h index d42a136f61a2a85e4e02b3c316feb6caf3a4ca45..ef52291c6a45e32066d218c3287883ac8cab934a 100644 --- a/src/core/lib/security/util/b64.h +++ b/src/core/lib/security/util/b64.h @@ -37,10 +37,22 @@ #include <grpc/slice.h> /* Encodes data using base64. It is the caller's responsability to free - the returned char * using gpr_free. Returns NULL on NULL input. */ + the returned char * using gpr_free. Returns NULL on NULL input. + TODO(makdharma) : change the flags to bool from int */ char *grpc_base64_encode(const void *data, size_t data_size, int url_safe, int multiline); +/* estimate the upper bound on size of base64 encoded data. The actual size + * is guaranteed to be less than or equal to the size returned here. */ +size_t grpc_base64_estimate_encoded_size(size_t data_size, int url_safe, + int multiline); + +/* Encodes data using base64 and write it to memory pointed to by result. It is + * the caller's responsiblity to allocate enough memory in |result| to fit the + * encoded data. */ +void grpc_base64_encode_core(char *result, const void *vdata, size_t data_size, + int url_safe, int multiline); + /* Decodes data according to the base64 specification. Returns an empty slice in case of failure. */ grpc_slice grpc_base64_decode(grpc_exec_ctx *exec_ctx, const char *b64, diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 86445393cec25efa69ca1022d59458e2bcfacc07..258c65c08e983de01d219969ad48b181fa7a6270 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -162,6 +162,7 @@ CORE_SOURCE_FILES = [ 'src/core/lib/json/json_reader.c', 'src/core/lib/json/json_string.c', 'src/core/lib/json/json_writer.c', + 'src/core/lib/security/util/b64.c', 'src/core/lib/slice/percent_encoding.c', 'src/core/lib/slice/slice.c', 'src/core/lib/slice/slice_buffer.c', @@ -244,7 +245,6 @@ CORE_SOURCE_FILES = [ 'src/core/lib/security/transport/security_handshaker.c', 'src/core/lib/security/transport/server_auth_filter.c', 'src/core/lib/security/transport/tsi_error.c', - 'src/core/lib/security/util/b64.c', 'src/core/lib/security/util/json_util.c', 'src/core/lib/surface/init_secure.c', 'src/core/lib/tsi/fake_transport_security.c', diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index e3190152447f88e378c62247cb07ccf1b041d851..61d3c5e88e9b1910256aed1007619b9fe707485c 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -7787,6 +7787,7 @@ "src/core/lib/json/json_string.c", "src/core/lib/json/json_writer.c", "src/core/lib/json/json_writer.h", + "src/core/lib/security/util/b64.c", "src/core/lib/slice/percent_encoding.c", "src/core/lib/slice/percent_encoding.h", "src/core/lib/slice/slice.c", diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj b/vsprojects/vcxproj/grpc/grpc.vcxproj index 0b2127f308c6489a424945b24e0219589fe5eb64..7abff218ddec49cdef951514ad7bfe6dadeb47a0 100644 --- a/vsprojects/vcxproj/grpc/grpc.vcxproj +++ b/vsprojects/vcxproj/grpc/grpc.vcxproj @@ -675,6 +675,8 @@ </ClCompile> <ClCompile Include="$(SolutionDir)\..\src\core\lib\json\json_writer.c"> </ClCompile> + <ClCompile Include="$(SolutionDir)\..\src\core\lib\security\util\b64.c"> + </ClCompile> <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\percent_encoding.c"> </ClCompile> <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\slice.c"> @@ -839,8 +841,6 @@ </ClCompile> <ClCompile Include="$(SolutionDir)\..\src\core\lib\security\transport\tsi_error.c"> </ClCompile> - <ClCompile Include="$(SolutionDir)\..\src\core\lib\security\util\b64.c"> - </ClCompile> <ClCompile Include="$(SolutionDir)\..\src\core\lib\security\util\json_util.c"> </ClCompile> <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\init_secure.c"> diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters index 0a3c9c621d000b8d32cee6a10aa5639e79533592..aa3e5a77aa6b5a28d979a2ce97df15171ff35e3d 100644 --- a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters +++ b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters @@ -259,6 +259,9 @@ <ClCompile Include="$(SolutionDir)\..\src\core\lib\json\json_writer.c"> <Filter>src\core\lib\json</Filter> </ClCompile> + <ClCompile Include="$(SolutionDir)\..\src\core\lib\security\util\b64.c"> + <Filter>src\core\lib\security\util</Filter> + </ClCompile> <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\percent_encoding.c"> <Filter>src\core\lib\slice</Filter> </ClCompile> @@ -505,9 +508,6 @@ <ClCompile Include="$(SolutionDir)\..\src\core\lib\security\transport\tsi_error.c"> <Filter>src\core\lib\security\transport</Filter> </ClCompile> - <ClCompile Include="$(SolutionDir)\..\src\core\lib\security\util\b64.c"> - <Filter>src\core\lib\security\util</Filter> - </ClCompile> <ClCompile Include="$(SolutionDir)\..\src\core\lib\security\util\json_util.c"> <Filter>src\core\lib\security\util</Filter> </ClCompile> diff --git a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj index 04d6d9f55a32d0328b519eea885790d8a6f337fb..9f3743b238e6ced3942c7d8e70147b33883cc273 100644 --- a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj +++ b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj @@ -516,6 +516,8 @@ </ClCompile> <ClCompile Include="$(SolutionDir)\..\src\core\lib\json\json_writer.c"> </ClCompile> + <ClCompile Include="$(SolutionDir)\..\src\core\lib\security\util\b64.c"> + </ClCompile> <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\percent_encoding.c"> </ClCompile> <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\slice.c"> diff --git a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters index a2849888a14d12c5455acd9f846ce4ef008f57cd..bc52644206e7b70a7d9ff1280888617bb76cb930 100644 --- a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters +++ b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters @@ -316,6 +316,9 @@ <ClCompile Include="$(SolutionDir)\..\src\core\lib\json\json_writer.c"> <Filter>src\core\lib\json</Filter> </ClCompile> + <ClCompile Include="$(SolutionDir)\..\src\core\lib\security\util\b64.c"> + <Filter>src\core\lib\security\util</Filter> + </ClCompile> <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\percent_encoding.c"> <Filter>src\core\lib\slice</Filter> </ClCompile> @@ -941,6 +944,12 @@ <Filter Include="src\core\lib\json"> <UniqueIdentifier>{89bc8f83-e29a-ddab-8f6b-22df11cdc867}</UniqueIdentifier> </Filter> + <Filter Include="src\core\lib\security"> + <UniqueIdentifier>{83d9c8a0-c579-769e-e2df-270c67b8c159}</UniqueIdentifier> + </Filter> + <Filter Include="src\core\lib\security\util"> + <UniqueIdentifier>{d55417ff-35a3-ef69-80c4-e6a95673728b}</UniqueIdentifier> + </Filter> <Filter Include="src\core\lib\slice"> <UniqueIdentifier>{4d172bbc-20c4-6e7d-872a-2d287b589aa0}</UniqueIdentifier> </Filter> diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj index 86549398dc87d16bab7f6f4d89adeb8dea12d6cc..1a0c38cecbf921838b201f2aae7a80f2f38f415b 100644 --- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj +++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj @@ -642,6 +642,8 @@ </ClCompile> <ClCompile Include="$(SolutionDir)\..\src\core\lib\json\json_writer.c"> </ClCompile> + <ClCompile Include="$(SolutionDir)\..\src\core\lib\security\util\b64.c"> + </ClCompile> <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\percent_encoding.c"> </ClCompile> <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\slice.c"> diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters index 625f276a55eefaeebfc0eaae09e2617a172ec680..b11766ecfd9448997628a52c58e8fe84a4b2eeb9 100644 --- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters +++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters @@ -262,6 +262,9 @@ <ClCompile Include="$(SolutionDir)\..\src\core\lib\json\json_writer.c"> <Filter>src\core\lib\json</Filter> </ClCompile> + <ClCompile Include="$(SolutionDir)\..\src\core\lib\security\util\b64.c"> + <Filter>src\core\lib\security\util</Filter> + </ClCompile> <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\percent_encoding.c"> <Filter>src\core\lib\slice</Filter> </ClCompile> @@ -1352,6 +1355,12 @@ <Filter Include="src\core\lib\json"> <UniqueIdentifier>{681cdaeb-c47f-8853-d985-bf13c2873947}</UniqueIdentifier> </Filter> + <Filter Include="src\core\lib\security"> + <UniqueIdentifier>{02c849c5-66eb-e42f-c9f7-2cf7cc9db06a}</UniqueIdentifier> + </Filter> + <Filter Include="src\core\lib\security\util"> + <UniqueIdentifier>{c22aef1f-8b7b-6b5c-9e22-321b11f6352d}</UniqueIdentifier> + </Filter> <Filter Include="src\core\lib\slice"> <UniqueIdentifier>{74c81ab7-e329-a362-3890-4c41b90f0511}</UniqueIdentifier> </Filter>