| /* |
| * |
| * Copyright 2018 gRPC authors. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| */ |
| |
| #include <grpc/support/port_platform.h> |
| |
| #include "src/core/tsi/alts/handshaker/alts_handshaker_service_api_util.h" |
| |
| #include "src/core/lib/slice/slice_internal.h" |
| |
| void add_repeated_field(repeated_field** head, const void* data) { |
| repeated_field* field = |
| static_cast<repeated_field*>(gpr_zalloc(sizeof(*field))); |
| field->data = data; |
| if (*head == nullptr) { |
| *head = field; |
| (*head)->next = nullptr; |
| } else { |
| field->next = *head; |
| *head = field; |
| } |
| } |
| |
| void destroy_repeated_field_list_identity(repeated_field* head) { |
| repeated_field* field = head; |
| while (field != nullptr) { |
| repeated_field* next_field = field->next; |
| const grpc_gcp_identity* identity = |
| static_cast<const grpc_gcp_identity*>(field->data); |
| destroy_slice(static_cast<grpc_slice*>(identity->hostname.arg)); |
| destroy_slice(static_cast<grpc_slice*>(identity->service_account.arg)); |
| gpr_free((void*)identity); |
| gpr_free(field); |
| field = next_field; |
| } |
| } |
| |
| void destroy_repeated_field_list_string(repeated_field* head) { |
| repeated_field* field = head; |
| while (field != nullptr) { |
| repeated_field* next_field = field->next; |
| destroy_slice((grpc_slice*)field->data); |
| gpr_free(field); |
| field = next_field; |
| } |
| } |
| |
| grpc_slice* create_slice(const char* data, size_t size) { |
| grpc_slice slice = grpc_slice_from_copied_buffer(data, size); |
| grpc_slice* cb_slice = |
| static_cast<grpc_slice*>(gpr_zalloc(sizeof(*cb_slice))); |
| memcpy(cb_slice, &slice, sizeof(*cb_slice)); |
| return cb_slice; |
| } |
| |
| void destroy_slice(grpc_slice* slice) { |
| if (slice != nullptr) { |
| grpc_slice_unref_internal(*slice); |
| gpr_free(slice); |
| } |
| } |
| |
| bool encode_string_or_bytes_cb(pb_ostream_t* stream, const pb_field_t* field, |
| void* const* arg) { |
| grpc_slice* slice = static_cast<grpc_slice*>(*arg); |
| if (!pb_encode_tag_for_field(stream, field)) return false; |
| return pb_encode_string(stream, GRPC_SLICE_START_PTR(*slice), |
| GRPC_SLICE_LENGTH(*slice)); |
| } |
| |
| bool encode_repeated_identity_cb(pb_ostream_t* stream, const pb_field_t* field, |
| void* const* arg) { |
| repeated_field* var = static_cast<repeated_field*>(*arg); |
| while (var != nullptr) { |
| if (!pb_encode_tag_for_field(stream, field)) return false; |
| if (!pb_encode_submessage(stream, grpc_gcp_Identity_fields, |
| (grpc_gcp_identity*)var->data)) |
| return false; |
| var = var->next; |
| } |
| return true; |
| } |
| |
| bool encode_repeated_string_cb(pb_ostream_t* stream, const pb_field_t* field, |
| void* const* arg) { |
| repeated_field* var = static_cast<repeated_field*>(*arg); |
| while (var != nullptr) { |
| if (!pb_encode_tag_for_field(stream, field)) return false; |
| const grpc_slice* slice = static_cast<const grpc_slice*>(var->data); |
| if (!pb_encode_string(stream, GRPC_SLICE_START_PTR(*slice), |
| GRPC_SLICE_LENGTH(*slice))) |
| return false; |
| var = var->next; |
| } |
| return true; |
| } |
| |
| bool decode_string_or_bytes_cb(pb_istream_t* stream, const pb_field_t* field, |
| void** arg) { |
| grpc_slice slice = grpc_slice_malloc(stream->bytes_left); |
| grpc_slice* cb_slice = |
| static_cast<grpc_slice*>(gpr_zalloc(sizeof(*cb_slice))); |
| memcpy(cb_slice, &slice, sizeof(*cb_slice)); |
| if (!pb_read(stream, GRPC_SLICE_START_PTR(*cb_slice), stream->bytes_left)) |
| return false; |
| *arg = cb_slice; |
| return true; |
| } |
| |
| bool decode_repeated_identity_cb(pb_istream_t* stream, const pb_field_t* field, |
| void** arg) { |
| grpc_gcp_identity* identity = |
| static_cast<grpc_gcp_identity*>(gpr_zalloc(sizeof(*identity))); |
| identity->hostname.funcs.decode = decode_string_or_bytes_cb; |
| identity->service_account.funcs.decode = decode_string_or_bytes_cb; |
| add_repeated_field(reinterpret_cast<repeated_field**>(arg), identity); |
| if (!pb_decode(stream, grpc_gcp_Identity_fields, identity)) return false; |
| return true; |
| } |
| |
| bool decode_repeated_string_cb(pb_istream_t* stream, const pb_field_t* field, |
| void** arg) { |
| grpc_slice slice = grpc_slice_malloc(stream->bytes_left); |
| grpc_slice* cb_slice = |
| static_cast<grpc_slice*>(gpr_zalloc(sizeof(*cb_slice))); |
| memcpy(cb_slice, &slice, sizeof(grpc_slice)); |
| if (!pb_read(stream, GRPC_SLICE_START_PTR(*cb_slice), stream->bytes_left)) |
| return false; |
| add_repeated_field(reinterpret_cast<repeated_field**>(arg), cb_slice); |
| return true; |
| } |