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 "test/core/tsi/alts/handshaker/alts_handshaker_service_api_test_lib.h"
20
21 const size_t kHandshakeProtocolNum = 3;
22
grpc_gcp_handshaker_decoded_req_create(grpc_gcp_handshaker_req_type type)23 grpc_gcp_handshaker_req* grpc_gcp_handshaker_decoded_req_create(
24 grpc_gcp_handshaker_req_type type) {
25 grpc_gcp_handshaker_req* req =
26 static_cast<grpc_gcp_handshaker_req*>(gpr_zalloc(sizeof(*req)));
27 switch (type) {
28 case CLIENT_START_REQ:
29 req->has_client_start = true;
30 req->client_start.target_identities.funcs.decode =
31 decode_repeated_identity_cb;
32 req->client_start.application_protocols.funcs.decode =
33 decode_repeated_string_cb;
34 req->client_start.record_protocols.funcs.decode =
35 decode_repeated_string_cb;
36 req->client_start.local_identity.hostname.funcs.decode =
37 decode_string_or_bytes_cb;
38 req->client_start.local_identity.service_account.funcs.decode =
39 decode_string_or_bytes_cb;
40 req->client_start.local_endpoint.ip_address.funcs.decode =
41 decode_string_or_bytes_cb;
42 req->client_start.remote_endpoint.ip_address.funcs.decode =
43 decode_string_or_bytes_cb;
44 req->client_start.target_name.funcs.decode = decode_string_or_bytes_cb;
45 break;
46 case SERVER_START_REQ:
47 req->has_server_start = true;
48 req->server_start.application_protocols.funcs.decode =
49 &decode_repeated_string_cb;
50 for (size_t i = 0; i < kHandshakeProtocolNum; i++) {
51 req->server_start.handshake_parameters[i]
52 .value.local_identities.funcs.decode = &decode_repeated_identity_cb;
53 req->server_start.handshake_parameters[i]
54 .value.record_protocols.funcs.decode = &decode_repeated_string_cb;
55 }
56 req->server_start.in_bytes.funcs.decode = decode_string_or_bytes_cb;
57 req->server_start.local_endpoint.ip_address.funcs.decode =
58 decode_string_or_bytes_cb;
59 req->server_start.remote_endpoint.ip_address.funcs.decode =
60 decode_string_or_bytes_cb;
61 break;
62 case NEXT_REQ:
63 req->has_next = true;
64 break;
65 }
66 return req;
67 }
68
grpc_gcp_handshaker_resp_set_application_protocol(grpc_gcp_handshaker_resp * resp,const char * application_protocol)69 bool grpc_gcp_handshaker_resp_set_application_protocol(
70 grpc_gcp_handshaker_resp* resp, const char* application_protocol) {
71 if (resp == nullptr || application_protocol == nullptr) {
72 gpr_log(GPR_ERROR,
73 "Invalid nullptr arguments to "
74 "handshaker_resp_set_application_protocol().");
75 return false;
76 }
77 resp->has_result = true;
78 grpc_slice* slice =
79 create_slice(application_protocol, strlen(application_protocol));
80 resp->result.application_protocol.arg = slice;
81 resp->result.application_protocol.funcs.encode = encode_string_or_bytes_cb;
82 return true;
83 }
84
grpc_gcp_handshaker_resp_set_record_protocol(grpc_gcp_handshaker_resp * resp,const char * record_protocol)85 bool grpc_gcp_handshaker_resp_set_record_protocol(
86 grpc_gcp_handshaker_resp* resp, const char* record_protocol) {
87 if (resp == nullptr || record_protocol == nullptr) {
88 gpr_log(GPR_ERROR,
89 "Invalid nullptr arguments to "
90 "handshaker_resp_set_record_protocol().");
91 return false;
92 }
93 resp->has_result = true;
94 grpc_slice* slice = create_slice(record_protocol, strlen(record_protocol));
95 resp->result.record_protocol.arg = slice;
96 resp->result.record_protocol.funcs.encode = encode_string_or_bytes_cb;
97 return true;
98 }
99
grpc_gcp_handshaker_resp_set_key_data(grpc_gcp_handshaker_resp * resp,const char * key_data,size_t size)100 bool grpc_gcp_handshaker_resp_set_key_data(grpc_gcp_handshaker_resp* resp,
101 const char* key_data, size_t size) {
102 if (resp == nullptr || key_data == nullptr) {
103 gpr_log(GPR_ERROR,
104 "Invalid nullptr arguments to handshaker_resp_set_key_data().");
105 return false;
106 }
107 resp->has_result = true;
108 grpc_slice* slice = create_slice(key_data, size);
109 resp->result.key_data.arg = slice;
110 resp->result.key_data.funcs.encode = encode_string_or_bytes_cb;
111 return true;
112 }
113
set_identity_hostname(grpc_gcp_identity * identity,const char * hostname)114 static void set_identity_hostname(grpc_gcp_identity* identity,
115 const char* hostname) {
116 grpc_slice* slice = create_slice(hostname, strlen(hostname));
117 identity->hostname.arg = slice;
118 identity->hostname.funcs.encode = encode_string_or_bytes_cb;
119 }
120
set_identity_service_account(grpc_gcp_identity * identity,const char * service_account)121 static void set_identity_service_account(grpc_gcp_identity* identity,
122 const char* service_account) {
123 grpc_slice* slice = create_slice(service_account, strlen(service_account));
124 identity->service_account.arg = slice;
125 identity->service_account.funcs.encode = encode_string_or_bytes_cb;
126 }
127
grpc_gcp_handshaker_resp_set_local_identity_hostname(grpc_gcp_handshaker_resp * resp,const char * hostname)128 bool grpc_gcp_handshaker_resp_set_local_identity_hostname(
129 grpc_gcp_handshaker_resp* resp, const char* hostname) {
130 if (resp == nullptr || hostname == nullptr) {
131 gpr_log(GPR_ERROR,
132 "Invalid nullptr arguments to "
133 "grpc_gcp_handshaker_resp_set_local_identity_hostname().");
134 return false;
135 }
136 resp->has_result = true;
137 resp->result.has_local_identity = true;
138 set_identity_hostname(&resp->result.local_identity, hostname);
139 return true;
140 }
141
grpc_gcp_handshaker_resp_set_local_identity_service_account(grpc_gcp_handshaker_resp * resp,const char * service_account)142 bool grpc_gcp_handshaker_resp_set_local_identity_service_account(
143 grpc_gcp_handshaker_resp* resp, const char* service_account) {
144 if (resp == nullptr || service_account == nullptr) {
145 gpr_log(GPR_ERROR,
146 "Invalid nullptr arguments to "
147 "grpc_gcp_handshaker_resp_set_local_identity_service_account().");
148 return false;
149 }
150 resp->has_result = true;
151 resp->result.has_local_identity = true;
152 set_identity_service_account(&resp->result.local_identity, service_account);
153 return true;
154 }
155
grpc_gcp_handshaker_resp_set_peer_identity_hostname(grpc_gcp_handshaker_resp * resp,const char * hostname)156 bool grpc_gcp_handshaker_resp_set_peer_identity_hostname(
157 grpc_gcp_handshaker_resp* resp, const char* hostname) {
158 if (resp == nullptr || hostname == nullptr) {
159 gpr_log(GPR_ERROR,
160 "Invalid nullptr arguments to "
161 "grpc_gcp_handshaker_resp_set_peer_identity_hostname().");
162 return false;
163 }
164 resp->has_result = true;
165 resp->result.has_peer_identity = true;
166 set_identity_hostname(&resp->result.peer_identity, hostname);
167 return true;
168 }
169
grpc_gcp_handshaker_resp_set_peer_identity_service_account(grpc_gcp_handshaker_resp * resp,const char * service_account)170 bool grpc_gcp_handshaker_resp_set_peer_identity_service_account(
171 grpc_gcp_handshaker_resp* resp, const char* service_account) {
172 if (resp == nullptr || service_account == nullptr) {
173 gpr_log(GPR_ERROR,
174 "Invalid nullptr arguments to "
175 "grpc_gcp_handshaker_resp_set_peer_identity_service_account().");
176 return false;
177 }
178 resp->has_result = true;
179 resp->result.has_peer_identity = true;
180 set_identity_service_account(&resp->result.peer_identity, service_account);
181 return true;
182 }
183
grpc_gcp_handshaker_resp_set_channel_open(grpc_gcp_handshaker_resp * resp,bool keep_channel_open)184 bool grpc_gcp_handshaker_resp_set_channel_open(grpc_gcp_handshaker_resp* resp,
185 bool keep_channel_open) {
186 if (resp == nullptr) {
187 gpr_log(GPR_ERROR,
188 "Invalid nullptr argument to "
189 "grpc_gcp_handshaker_resp_set_channel_open().");
190 return false;
191 }
192 resp->has_result = true;
193 resp->result.has_keep_channel_open = true;
194 resp->result.keep_channel_open = keep_channel_open;
195 return true;
196 }
197
grpc_gcp_handshaker_resp_set_code(grpc_gcp_handshaker_resp * resp,uint32_t code)198 bool grpc_gcp_handshaker_resp_set_code(grpc_gcp_handshaker_resp* resp,
199 uint32_t code) {
200 if (resp == nullptr) {
201 gpr_log(GPR_ERROR,
202 "Invalid nullptr argument to grpc_gcp_handshaker_resp_set_code().");
203 return false;
204 }
205 resp->has_status = true;
206 resp->status.has_code = true;
207 resp->status.code = code;
208 return true;
209 }
210
grpc_gcp_handshaker_resp_set_details(grpc_gcp_handshaker_resp * resp,const char * details)211 bool grpc_gcp_handshaker_resp_set_details(grpc_gcp_handshaker_resp* resp,
212 const char* details) {
213 if (resp == nullptr || details == nullptr) {
214 gpr_log(
215 GPR_ERROR,
216 "Invalid nullptr arguments to grpc_gcp_handshaker_resp_set_details().");
217 return false;
218 }
219 resp->has_status = true;
220 grpc_slice* slice = create_slice(details, strlen(details));
221 resp->status.details.arg = slice;
222 resp->status.details.funcs.encode = encode_string_or_bytes_cb;
223 return true;
224 }
225
grpc_gcp_handshaker_resp_set_out_frames(grpc_gcp_handshaker_resp * resp,const char * out_frames,size_t size)226 bool grpc_gcp_handshaker_resp_set_out_frames(grpc_gcp_handshaker_resp* resp,
227 const char* out_frames,
228 size_t size) {
229 if (resp == nullptr || out_frames == nullptr) {
230 gpr_log(GPR_ERROR,
231 "Invalid nullptr arguments to "
232 "grpc_gcp_handshaker_resp_set_out_frames().");
233 return false;
234 }
235 grpc_slice* slice = create_slice(out_frames, size);
236 resp->out_frames.arg = slice;
237 resp->out_frames.funcs.encode = encode_string_or_bytes_cb;
238 return true;
239 }
240
grpc_gcp_handshaker_resp_set_bytes_consumed(grpc_gcp_handshaker_resp * resp,int32_t bytes_consumed)241 bool grpc_gcp_handshaker_resp_set_bytes_consumed(grpc_gcp_handshaker_resp* resp,
242 int32_t bytes_consumed) {
243 if (resp == nullptr) {
244 gpr_log(GPR_ERROR,
245 "Invalid nullptr argument to "
246 "grpc_gcp_handshaker_resp_set_bytes_consumed().");
247 return false;
248 }
249 resp->has_bytes_consumed = true;
250 resp->bytes_consumed = bytes_consumed;
251 return true;
252 }
253
grpc_gcp_handshaker_resp_set_peer_rpc_versions(grpc_gcp_handshaker_resp * resp,uint32_t max_major,uint32_t max_minor,uint32_t min_major,uint32_t min_minor)254 bool grpc_gcp_handshaker_resp_set_peer_rpc_versions(
255 grpc_gcp_handshaker_resp* resp, uint32_t max_major, uint32_t max_minor,
256 uint32_t min_major, uint32_t min_minor) {
257 if (resp == nullptr) {
258 gpr_log(GPR_ERROR,
259 "Invalid nullptr argument to "
260 "grpc_gcp_handshaker_resp_set_peer_rpc_versions().");
261 return false;
262 }
263 resp->has_result = true;
264 resp->result.has_peer_rpc_versions = true;
265 grpc_gcp_rpc_protocol_versions* versions = &resp->result.peer_rpc_versions;
266 versions->has_max_rpc_version = true;
267 versions->has_min_rpc_version = true;
268 versions->max_rpc_version.has_major = true;
269 versions->max_rpc_version.has_minor = true;
270 versions->min_rpc_version.has_major = true;
271 versions->min_rpc_version.has_minor = true;
272 versions->max_rpc_version.major = max_major;
273 versions->max_rpc_version.minor = max_minor;
274 versions->min_rpc_version.major = min_major;
275 versions->min_rpc_version.minor = min_minor;
276 return true;
277 }
278
grpc_gcp_handshaker_resp_encode(grpc_gcp_handshaker_resp * resp,grpc_slice * slice)279 bool grpc_gcp_handshaker_resp_encode(grpc_gcp_handshaker_resp* resp,
280 grpc_slice* slice) {
281 if (resp == nullptr || slice == nullptr) {
282 gpr_log(GPR_ERROR,
283 "Invalid nullptr arguments to grpc_gcp_handshaker_resp_encode().");
284 return false;
285 }
286 pb_ostream_t size_stream;
287 memset(&size_stream, 0, sizeof(pb_ostream_t));
288 if (!pb_encode(&size_stream, grpc_gcp_HandshakerResp_fields, resp)) {
289 gpr_log(GPR_ERROR, "nanopb error: %s", PB_GET_ERROR(&size_stream));
290 return false;
291 }
292 size_t encoded_length = size_stream.bytes_written;
293 *slice = grpc_slice_malloc(encoded_length);
294 pb_ostream_t output_stream =
295 pb_ostream_from_buffer(GRPC_SLICE_START_PTR(*slice), encoded_length);
296 if (!pb_encode(&output_stream, grpc_gcp_HandshakerResp_fields, resp)) {
297 gpr_log(GPR_ERROR, "nanopb error: %s", PB_GET_ERROR(&size_stream));
298 return false;
299 }
300 return true;
301 }
302
grpc_gcp_handshaker_req_decode(grpc_slice slice,grpc_gcp_handshaker_req * req)303 bool grpc_gcp_handshaker_req_decode(grpc_slice slice,
304 grpc_gcp_handshaker_req* req) {
305 if (req == nullptr) {
306 gpr_log(GPR_ERROR,
307 "Invalid nullptr argument to grpc_gcp_handshaker_req_decode().");
308 return false;
309 }
310 pb_istream_t stream = pb_istream_from_buffer(GRPC_SLICE_START_PTR(slice),
311 GRPC_SLICE_LENGTH(slice));
312 req->next.in_bytes.funcs.decode = decode_string_or_bytes_cb;
313 if (!pb_decode(&stream, grpc_gcp_HandshakerReq_fields, req)) {
314 gpr_log(GPR_ERROR, "nanopb error: %s", PB_GET_ERROR(&stream));
315 return false;
316 }
317 return true;
318 }
319
320 /* Check equality of a pair of grpc_slice fields. */
slice_equals(grpc_slice * l_slice,grpc_slice * r_slice)321 static bool slice_equals(grpc_slice* l_slice, grpc_slice* r_slice) {
322 if (l_slice == nullptr && r_slice == nullptr) {
323 return true;
324 }
325 if (l_slice != nullptr && r_slice != nullptr) {
326 return grpc_slice_eq(*l_slice, *r_slice);
327 }
328 return false;
329 }
330
331 /* Check equality of a pair of grpc_gcp_identity fields. */
handshaker_identity_equals(const grpc_gcp_identity * l_id,const grpc_gcp_identity * r_id)332 static bool handshaker_identity_equals(const grpc_gcp_identity* l_id,
333 const grpc_gcp_identity* r_id) {
334 if (!((l_id->hostname.arg != nullptr) != (r_id->hostname.arg != nullptr))) {
335 if (l_id->hostname.arg != nullptr) {
336 return slice_equals(static_cast<grpc_slice*>(l_id->hostname.arg),
337 static_cast<grpc_slice*>(r_id->hostname.arg));
338 }
339 } else {
340 return false;
341 }
342 if (!((l_id->service_account.arg != nullptr) !=
343 (r_id->service_account.arg != nullptr))) {
344 if (l_id->service_account.arg != nullptr) {
345 return slice_equals(static_cast<grpc_slice*>(l_id->service_account.arg),
346 static_cast<grpc_slice*>(r_id->service_account.arg));
347 }
348 } else {
349 return false;
350 }
351 return true;
352 }
353
handshaker_rpc_versions_equals(const grpc_gcp_rpc_protocol_versions * l_version,const grpc_gcp_rpc_protocol_versions * r_version)354 static bool handshaker_rpc_versions_equals(
355 const grpc_gcp_rpc_protocol_versions* l_version,
356 const grpc_gcp_rpc_protocol_versions* r_version) {
357 bool result = true;
358 result &=
359 (l_version->max_rpc_version.major == r_version->max_rpc_version.major);
360 result &=
361 (l_version->max_rpc_version.minor == r_version->max_rpc_version.minor);
362 result &=
363 (l_version->min_rpc_version.major == r_version->min_rpc_version.major);
364 result &=
365 (l_version->min_rpc_version.minor == r_version->min_rpc_version.minor);
366 return result;
367 }
368
369 /* Check equality of a pair of grpc_gcp_endpoint fields. */
handshaker_endpoint_equals(const grpc_gcp_endpoint * l_end,const grpc_gcp_endpoint * r_end)370 static bool handshaker_endpoint_equals(const grpc_gcp_endpoint* l_end,
371 const grpc_gcp_endpoint* r_end) {
372 bool result = true;
373 result &= (l_end->port == r_end->port);
374 result &= (l_end->protocol == r_end->protocol);
375 if (!((l_end->ip_address.arg != nullptr) !=
376 (r_end->ip_address.arg != nullptr))) {
377 if (l_end->ip_address.arg != nullptr) {
378 result &= slice_equals(static_cast<grpc_slice*>(l_end->ip_address.arg),
379 static_cast<grpc_slice*>(r_end->ip_address.arg));
380 }
381 } else {
382 return false;
383 }
384 return result;
385 }
386 /**
387 * Check if a specific repeated field (i.e., target) is contained in a repeated
388 * field list (i.e., head).
389 */
repeated_field_list_contains_identity(const repeated_field * head,const repeated_field * target)390 static bool repeated_field_list_contains_identity(
391 const repeated_field* head, const repeated_field* target) {
392 repeated_field* field = const_cast<repeated_field*>(head);
393 while (field != nullptr) {
394 if (handshaker_identity_equals(
395 static_cast<const grpc_gcp_identity*>(field->data),
396 static_cast<const grpc_gcp_identity*>(target->data))) {
397 return true;
398 }
399 field = field->next;
400 }
401 return false;
402 }
403
repeated_field_list_contains_string(const repeated_field * head,const repeated_field * target)404 static bool repeated_field_list_contains_string(const repeated_field* head,
405 const repeated_field* target) {
406 repeated_field* field = const_cast<repeated_field*>(head);
407 while (field != nullptr) {
408 if (slice_equals((grpc_slice*)field->data, (grpc_slice*)target->data)) {
409 return true;
410 }
411 field = field->next;
412 }
413 return false;
414 }
415
416 /* Return a length of repeated field list. */
repeated_field_list_get_length(const repeated_field * head)417 static size_t repeated_field_list_get_length(const repeated_field* head) {
418 repeated_field* field = const_cast<repeated_field*>(head);
419 size_t len = 0;
420 while (field != nullptr) {
421 len++;
422 field = field->next;
423 }
424 return len;
425 }
426
427 /**
428 * Check if a pair of repeated field lists contain the same set of repeated
429 * fields.
430 */
repeated_field_list_equals_identity(const repeated_field * l_head,const repeated_field * r_head)431 static bool repeated_field_list_equals_identity(const repeated_field* l_head,
432 const repeated_field* r_head) {
433 if (repeated_field_list_get_length(l_head) !=
434 repeated_field_list_get_length(r_head)) {
435 return false;
436 }
437 repeated_field* field = const_cast<repeated_field*>(l_head);
438 repeated_field* head = const_cast<repeated_field*>(r_head);
439 while (field != nullptr) {
440 if (!repeated_field_list_contains_identity(head, field)) {
441 return false;
442 }
443 field = field->next;
444 }
445 return true;
446 }
447
repeated_field_list_equals_string(const repeated_field * l_head,const repeated_field * r_head)448 static bool repeated_field_list_equals_string(const repeated_field* l_head,
449 const repeated_field* r_head) {
450 if (repeated_field_list_get_length(l_head) !=
451 repeated_field_list_get_length(r_head)) {
452 return false;
453 }
454 repeated_field* field = const_cast<repeated_field*>(l_head);
455 repeated_field* head = const_cast<repeated_field*>(r_head);
456 while (field != nullptr) {
457 if (!repeated_field_list_contains_string(head, field)) {
458 return false;
459 }
460 field = field->next;
461 }
462 return true;
463 }
464
465 /* Check equality of a pair of ALTS client_start handshake requests. */
grpc_gcp_handshaker_client_start_req_equals(grpc_gcp_start_client_handshake_req * l_req,grpc_gcp_start_client_handshake_req * r_req)466 bool grpc_gcp_handshaker_client_start_req_equals(
467 grpc_gcp_start_client_handshake_req* l_req,
468 grpc_gcp_start_client_handshake_req* r_req) {
469 bool result = true;
470 /* Compare handshake_security_protocol. */
471 result &=
472 l_req->handshake_security_protocol == r_req->handshake_security_protocol;
473 /* Compare application_protocols, record_protocols, and target_identities. */
474 result &= repeated_field_list_equals_string(
475 static_cast<const repeated_field*>(l_req->application_protocols.arg),
476 static_cast<const repeated_field*>(r_req->application_protocols.arg));
477 result &= repeated_field_list_equals_string(
478 static_cast<const repeated_field*>(l_req->record_protocols.arg),
479 static_cast<const repeated_field*>(r_req->record_protocols.arg));
480 result &= repeated_field_list_equals_identity(
481 static_cast<const repeated_field*>(l_req->target_identities.arg),
482 static_cast<const repeated_field*>(r_req->target_identities.arg));
483 if ((l_req->has_local_identity ^ r_req->has_local_identity) |
484 (l_req->has_local_endpoint ^ r_req->has_local_endpoint) |
485 ((l_req->has_remote_endpoint ^ r_req->has_remote_endpoint)) |
486 (l_req->has_rpc_versions ^ r_req->has_rpc_versions)) {
487 return false;
488 }
489 /* Compare local_identity, local_endpoint, and remote_endpoint. */
490 if (l_req->has_local_identity) {
491 result &= handshaker_identity_equals(&l_req->local_identity,
492 &r_req->local_identity);
493 }
494 if (l_req->has_local_endpoint) {
495 result &= handshaker_endpoint_equals(&l_req->local_endpoint,
496 &r_req->local_endpoint);
497 }
498 if (l_req->has_remote_endpoint) {
499 result &= handshaker_endpoint_equals(&l_req->remote_endpoint,
500 &r_req->remote_endpoint);
501 }
502 if (l_req->has_rpc_versions) {
503 result &= handshaker_rpc_versions_equals(&l_req->rpc_versions,
504 &r_req->rpc_versions);
505 }
506 return result;
507 }
508
509 /* Check equality of a pair of ALTS server_start handshake requests. */
grpc_gcp_handshaker_server_start_req_equals(grpc_gcp_start_server_handshake_req * l_req,grpc_gcp_start_server_handshake_req * r_req)510 bool grpc_gcp_handshaker_server_start_req_equals(
511 grpc_gcp_start_server_handshake_req* l_req,
512 grpc_gcp_start_server_handshake_req* r_req) {
513 bool result = true;
514 /* Compare application_protocols. */
515 result &= repeated_field_list_equals_string(
516 static_cast<const repeated_field*>(l_req->application_protocols.arg),
517 static_cast<const repeated_field*>(r_req->application_protocols.arg));
518 /* Compare handshake_parameters. */
519 size_t i = 0, j = 0;
520 result &=
521 (l_req->handshake_parameters_count == r_req->handshake_parameters_count);
522 for (i = 0; i < l_req->handshake_parameters_count; i++) {
523 bool found = false;
524 for (j = 0; j < r_req->handshake_parameters_count; j++) {
525 if (l_req->handshake_parameters[i].key ==
526 r_req->handshake_parameters[j].key) {
527 found = true;
528 result &= repeated_field_list_equals_string(
529 static_cast<const repeated_field*>(
530 l_req->handshake_parameters[i].value.record_protocols.arg),
531 static_cast<const repeated_field*>(
532 r_req->handshake_parameters[j].value.record_protocols.arg));
533 result &= repeated_field_list_equals_identity(
534 static_cast<const repeated_field*>(
535 l_req->handshake_parameters[i].value.local_identities.arg),
536 static_cast<const repeated_field*>(
537 r_req->handshake_parameters[j].value.local_identities.arg));
538 }
539 }
540 if (!found) {
541 return false;
542 }
543 }
544 /* Compare in_bytes, local_endpoint, remote_endpoint. */
545 result &= slice_equals(static_cast<grpc_slice*>(l_req->in_bytes.arg),
546 static_cast<grpc_slice*>(r_req->in_bytes.arg));
547 if ((l_req->has_local_endpoint ^ r_req->has_local_endpoint) |
548 (l_req->has_remote_endpoint ^ r_req->has_remote_endpoint) |
549 (l_req->has_rpc_versions ^ r_req->has_rpc_versions))
550 return false;
551 if (l_req->has_local_endpoint) {
552 result &= handshaker_endpoint_equals(&l_req->local_endpoint,
553 &r_req->local_endpoint);
554 }
555 if (l_req->has_remote_endpoint) {
556 result &= handshaker_endpoint_equals(&l_req->remote_endpoint,
557 &r_req->remote_endpoint);
558 }
559 if (l_req->has_rpc_versions) {
560 result &= handshaker_rpc_versions_equals(&l_req->rpc_versions,
561 &r_req->rpc_versions);
562 }
563 return result;
564 }
565
566 /* Check equality of a pair of ALTS handshake requests. */
grpc_gcp_handshaker_req_equals(grpc_gcp_handshaker_req * l_req,grpc_gcp_handshaker_req * r_req)567 bool grpc_gcp_handshaker_req_equals(grpc_gcp_handshaker_req* l_req,
568 grpc_gcp_handshaker_req* r_req) {
569 if (l_req->has_next && r_req->has_next) {
570 return slice_equals(static_cast<grpc_slice*>(l_req->next.in_bytes.arg),
571 static_cast<grpc_slice*>(r_req->next.in_bytes.arg));
572 } else if (l_req->has_client_start && r_req->has_client_start) {
573 return grpc_gcp_handshaker_client_start_req_equals(&l_req->client_start,
574 &r_req->client_start);
575 } else if (l_req->has_server_start && r_req->has_server_start) {
576 return grpc_gcp_handshaker_server_start_req_equals(&l_req->server_start,
577 &r_req->server_start);
578 }
579 return false;
580 }
581
582 /* Check equality of a pair of ALTS handshake results. */
grpc_gcp_handshaker_resp_result_equals(grpc_gcp_handshaker_result * l_result,grpc_gcp_handshaker_result * r_result)583 bool grpc_gcp_handshaker_resp_result_equals(
584 grpc_gcp_handshaker_result* l_result,
585 grpc_gcp_handshaker_result* r_result) {
586 bool result = true;
587 /* Compare application_protocol, record_protocol, and key_data. */
588 result &= slice_equals(
589 static_cast<grpc_slice*>(l_result->application_protocol.arg),
590 static_cast<grpc_slice*>(r_result->application_protocol.arg));
591 result &=
592 slice_equals(static_cast<grpc_slice*>(l_result->record_protocol.arg),
593 static_cast<grpc_slice*>(r_result->record_protocol.arg));
594 result &= slice_equals(static_cast<grpc_slice*>(l_result->key_data.arg),
595 static_cast<grpc_slice*>(r_result->key_data.arg));
596 /* Compare local_identity, peer_identity, and keep_channel_open. */
597 if ((l_result->has_local_identity ^ r_result->has_local_identity) |
598 (l_result->has_peer_identity ^ r_result->has_peer_identity) |
599 (l_result->has_peer_rpc_versions ^ r_result->has_peer_rpc_versions)) {
600 return false;
601 }
602 if (l_result->has_local_identity) {
603 result &= handshaker_identity_equals(&l_result->local_identity,
604 &r_result->local_identity);
605 }
606 if (l_result->has_peer_identity) {
607 result &= handshaker_identity_equals(&l_result->peer_identity,
608 &r_result->peer_identity);
609 }
610 if (l_result->has_peer_rpc_versions) {
611 result &= handshaker_rpc_versions_equals(&l_result->peer_rpc_versions,
612 &r_result->peer_rpc_versions);
613 }
614 result &= (l_result->keep_channel_open == r_result->keep_channel_open);
615 return result;
616 }
617
618 /* Check equality of a pair of ALTS handshake responses. */
grpc_gcp_handshaker_resp_equals(grpc_gcp_handshaker_resp * l_resp,grpc_gcp_handshaker_resp * r_resp)619 bool grpc_gcp_handshaker_resp_equals(grpc_gcp_handshaker_resp* l_resp,
620 grpc_gcp_handshaker_resp* r_resp) {
621 bool result = true;
622 /* Compare out_frames and bytes_consumed. */
623 result &= slice_equals(static_cast<grpc_slice*>(l_resp->out_frames.arg),
624 static_cast<grpc_slice*>(r_resp->out_frames.arg));
625 result &= (l_resp->bytes_consumed == r_resp->bytes_consumed);
626 /* Compare result and status. */
627 if ((l_resp->has_result ^ r_resp->has_result) |
628 (l_resp->has_status ^ r_resp->has_status)) {
629 return false;
630 }
631 if (l_resp->has_result) {
632 result &= grpc_gcp_handshaker_resp_result_equals(&l_resp->result,
633 &r_resp->result);
634 }
635 if (l_resp->has_status) {
636 result &= (l_resp->status.code == r_resp->status.code);
637 result &=
638 slice_equals(static_cast<grpc_slice*>(l_resp->status.details.arg),
639 static_cast<grpc_slice*>(r_resp->status.details.arg));
640 }
641 return result;
642 }
643