1 /*
2  *
3  * Copyright 2018 gRPC authors.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 #include <grpc/support/port_platform.h>
20 
21 #include "src/core/tsi/alts/handshaker/alts_handshaker_service_api_util.h"
22 
23 #include "src/core/lib/slice/slice_internal.h"
24 
add_repeated_field(repeated_field ** head,const void * data)25 void add_repeated_field(repeated_field** head, const void* data) {
26   repeated_field* field =
27       static_cast<repeated_field*>(gpr_zalloc(sizeof(*field)));
28   field->data = data;
29   if (*head == nullptr) {
30     *head = field;
31     (*head)->next = nullptr;
32   } else {
33     field->next = *head;
34     *head = field;
35   }
36 }
37 
destroy_repeated_field_list_identity(repeated_field * head)38 void destroy_repeated_field_list_identity(repeated_field* head) {
39   repeated_field* field = head;
40   while (field != nullptr) {
41     repeated_field* next_field = field->next;
42     const grpc_gcp_identity* identity =
43         static_cast<const grpc_gcp_identity*>(field->data);
44     destroy_slice(static_cast<grpc_slice*>(identity->hostname.arg));
45     destroy_slice(static_cast<grpc_slice*>(identity->service_account.arg));
46     gpr_free((void*)identity);
47     gpr_free(field);
48     field = next_field;
49   }
50 }
51 
destroy_repeated_field_list_string(repeated_field * head)52 void destroy_repeated_field_list_string(repeated_field* head) {
53   repeated_field* field = head;
54   while (field != nullptr) {
55     repeated_field* next_field = field->next;
56     destroy_slice((grpc_slice*)field->data);
57     gpr_free(field);
58     field = next_field;
59   }
60 }
61 
create_slice(const char * data,size_t size)62 grpc_slice* create_slice(const char* data, size_t size) {
63   grpc_slice slice = grpc_slice_from_copied_buffer(data, size);
64   grpc_slice* cb_slice =
65       static_cast<grpc_slice*>(gpr_zalloc(sizeof(*cb_slice)));
66   memcpy(cb_slice, &slice, sizeof(*cb_slice));
67   return cb_slice;
68 }
69 
destroy_slice(grpc_slice * slice)70 void destroy_slice(grpc_slice* slice) {
71   if (slice != nullptr) {
72     grpc_slice_unref_internal(*slice);
73     gpr_free(slice);
74   }
75 }
76 
encode_string_or_bytes_cb(pb_ostream_t * stream,const pb_field_t * field,void * const * arg)77 bool encode_string_or_bytes_cb(pb_ostream_t* stream, const pb_field_t* field,
78                                void* const* arg) {
79   grpc_slice* slice = static_cast<grpc_slice*>(*arg);
80   if (!pb_encode_tag_for_field(stream, field)) return false;
81   return pb_encode_string(stream, GRPC_SLICE_START_PTR(*slice),
82                           GRPC_SLICE_LENGTH(*slice));
83 }
84 
encode_repeated_identity_cb(pb_ostream_t * stream,const pb_field_t * field,void * const * arg)85 bool encode_repeated_identity_cb(pb_ostream_t* stream, const pb_field_t* field,
86                                  void* const* arg) {
87   repeated_field* var = static_cast<repeated_field*>(*arg);
88   while (var != nullptr) {
89     if (!pb_encode_tag_for_field(stream, field)) return false;
90     if (!pb_encode_submessage(stream, grpc_gcp_Identity_fields,
91                               (grpc_gcp_identity*)var->data))
92       return false;
93     var = var->next;
94   }
95   return true;
96 }
97 
encode_repeated_string_cb(pb_ostream_t * stream,const pb_field_t * field,void * const * arg)98 bool encode_repeated_string_cb(pb_ostream_t* stream, const pb_field_t* field,
99                                void* const* arg) {
100   repeated_field* var = static_cast<repeated_field*>(*arg);
101   while (var != nullptr) {
102     if (!pb_encode_tag_for_field(stream, field)) return false;
103     const grpc_slice* slice = static_cast<const grpc_slice*>(var->data);
104     if (!pb_encode_string(stream, GRPC_SLICE_START_PTR(*slice),
105                           GRPC_SLICE_LENGTH(*slice)))
106       return false;
107     var = var->next;
108   }
109   return true;
110 }
111 
decode_string_or_bytes_cb(pb_istream_t * stream,const pb_field_t * field,void ** arg)112 bool decode_string_or_bytes_cb(pb_istream_t* stream, const pb_field_t* field,
113                                void** arg) {
114   grpc_slice slice = grpc_slice_malloc(stream->bytes_left);
115   grpc_slice* cb_slice =
116       static_cast<grpc_slice*>(gpr_zalloc(sizeof(*cb_slice)));
117   memcpy(cb_slice, &slice, sizeof(*cb_slice));
118   if (!pb_read(stream, GRPC_SLICE_START_PTR(*cb_slice), stream->bytes_left))
119     return false;
120   *arg = cb_slice;
121   return true;
122 }
123 
decode_repeated_identity_cb(pb_istream_t * stream,const pb_field_t * field,void ** arg)124 bool decode_repeated_identity_cb(pb_istream_t* stream, const pb_field_t* field,
125                                  void** arg) {
126   grpc_gcp_identity* identity =
127       static_cast<grpc_gcp_identity*>(gpr_zalloc(sizeof(*identity)));
128   identity->hostname.funcs.decode = decode_string_or_bytes_cb;
129   identity->service_account.funcs.decode = decode_string_or_bytes_cb;
130   add_repeated_field(reinterpret_cast<repeated_field**>(arg), identity);
131   if (!pb_decode(stream, grpc_gcp_Identity_fields, identity)) return false;
132   return true;
133 }
134 
decode_repeated_string_cb(pb_istream_t * stream,const pb_field_t * field,void ** arg)135 bool decode_repeated_string_cb(pb_istream_t* stream, const pb_field_t* field,
136                                void** arg) {
137   grpc_slice slice = grpc_slice_malloc(stream->bytes_left);
138   grpc_slice* cb_slice =
139       static_cast<grpc_slice*>(gpr_zalloc(sizeof(*cb_slice)));
140   memcpy(cb_slice, &slice, sizeof(grpc_slice));
141   if (!pb_read(stream, GRPC_SLICE_START_PTR(*cb_slice), stream->bytes_left))
142     return false;
143   add_repeated_field(reinterpret_cast<repeated_field**>(arg), cb_slice);
144   return true;
145 }
146