aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/tsi/alts/handshaker/alts_handshaker_service_api.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/tsi/alts/handshaker/alts_handshaker_service_api.cc')
-rw-r--r--src/core/tsi/alts/handshaker/alts_handshaker_service_api.cc520
1 files changed, 520 insertions, 0 deletions
diff --git a/src/core/tsi/alts/handshaker/alts_handshaker_service_api.cc b/src/core/tsi/alts/handshaker/alts_handshaker_service_api.cc
new file mode 100644
index 0000000000..256e414ae4
--- /dev/null
+++ b/src/core/tsi/alts/handshaker/alts_handshaker_service_api.cc
@@ -0,0 +1,520 @@
+/*
+ *
+ * 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.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "src/core/tsi/alts/handshaker/transport_security_common_api.h"
+
+/* HandshakerReq */
+grpc_gcp_handshaker_req* grpc_gcp_handshaker_req_create(
+ grpc_gcp_handshaker_req_type type) {
+ grpc_gcp_handshaker_req* req =
+ static_cast<grpc_gcp_handshaker_req*>(gpr_zalloc(sizeof(*req)));
+ switch (type) {
+ case CLIENT_START_REQ:
+ req->has_client_start = true;
+ break;
+ case SERVER_START_REQ:
+ req->has_server_start = true;
+ break;
+ case NEXT_REQ:
+ req->has_next = true;
+ break;
+ }
+ return req;
+}
+
+void grpc_gcp_handshaker_req_destroy(grpc_gcp_handshaker_req* req) {
+ if (req == nullptr) {
+ return;
+ }
+ if (req->has_client_start) {
+ /* Destroy client_start request. */
+ destroy_repeated_field_list_identity(
+ static_cast<repeated_field*>(req->client_start.target_identities.arg));
+ destroy_repeated_field_list_string(static_cast<repeated_field*>(
+ req->client_start.application_protocols.arg));
+ destroy_repeated_field_list_string(
+ static_cast<repeated_field*>(req->client_start.record_protocols.arg));
+ if (req->client_start.has_local_identity) {
+ destroy_slice(static_cast<grpc_slice*>(
+ req->client_start.local_identity.hostname.arg));
+ destroy_slice(static_cast<grpc_slice*>(
+ req->client_start.local_identity.service_account.arg));
+ }
+ if (req->client_start.has_local_endpoint) {
+ destroy_slice(static_cast<grpc_slice*>(
+ req->client_start.local_endpoint.ip_address.arg));
+ }
+ if (req->client_start.has_remote_endpoint) {
+ destroy_slice(static_cast<grpc_slice*>(
+ req->client_start.remote_endpoint.ip_address.arg));
+ }
+ destroy_slice(static_cast<grpc_slice*>(req->client_start.target_name.arg));
+ } else if (req->has_server_start) {
+ /* Destroy server_start request. */
+ size_t i = 0;
+ for (i = 0; i < req->server_start.handshake_parameters_count; i++) {
+ destroy_repeated_field_list_identity(
+ static_cast<repeated_field*>(req->server_start.handshake_parameters[i]
+ .value.local_identities.arg));
+ destroy_repeated_field_list_string(
+ static_cast<repeated_field*>(req->server_start.handshake_parameters[i]
+ .value.record_protocols.arg));
+ }
+ destroy_repeated_field_list_string(static_cast<repeated_field*>(
+ req->server_start.application_protocols.arg));
+ if (req->server_start.has_local_endpoint) {
+ destroy_slice(static_cast<grpc_slice*>(
+ req->server_start.local_endpoint.ip_address.arg));
+ }
+ if (req->server_start.has_remote_endpoint) {
+ destroy_slice(static_cast<grpc_slice*>(
+ req->server_start.remote_endpoint.ip_address.arg));
+ }
+ destroy_slice(static_cast<grpc_slice*>(req->server_start.in_bytes.arg));
+ } else {
+ /* Destroy next request. */
+ destroy_slice(static_cast<grpc_slice*>(req->next.in_bytes.arg));
+ }
+ gpr_free(req);
+}
+
+bool grpc_gcp_handshaker_req_set_handshake_protocol(
+ grpc_gcp_handshaker_req* req,
+ grpc_gcp_handshake_protocol handshake_protocol) {
+ if (req == nullptr || !req->has_client_start) {
+ gpr_log(GPR_ERROR,
+ "Invalid arguments to "
+ "grpc_gcp_handshaker_req_set_handshake_protocol().");
+ return false;
+ }
+ req->client_start.has_handshake_security_protocol = true;
+ req->client_start.handshake_security_protocol = handshake_protocol;
+ return true;
+}
+
+bool grpc_gcp_handshaker_req_set_target_name(grpc_gcp_handshaker_req* req,
+ const char* target_name) {
+ if (req == nullptr || target_name == nullptr || !req->has_client_start) {
+ gpr_log(GPR_ERROR,
+ "Invalid arguments to "
+ "grpc_gcp_handshaker_req_set_target_name().");
+ return false;
+ }
+ grpc_slice* slice = create_slice(target_name, strlen(target_name));
+ req->client_start.target_name.arg = slice;
+ req->client_start.target_name.funcs.encode = encode_string_or_bytes_cb;
+ return true;
+}
+
+bool grpc_gcp_handshaker_req_add_application_protocol(
+ grpc_gcp_handshaker_req* req, const char* application_protocol) {
+ if (req == nullptr || application_protocol == nullptr || req->has_next) {
+ gpr_log(GPR_ERROR,
+ "Invalid arguments to "
+ "grpc_gcp_handshaker_req_add_application_protocol().");
+ return false;
+ }
+ grpc_slice* slice =
+ create_slice(application_protocol, strlen(application_protocol));
+ if (req->has_client_start) {
+ add_repeated_field(reinterpret_cast<repeated_field**>(
+ &req->client_start.application_protocols.arg),
+ slice);
+ req->client_start.application_protocols.funcs.encode =
+ encode_repeated_string_cb;
+ } else {
+ add_repeated_field(reinterpret_cast<repeated_field**>(
+ &req->server_start.application_protocols.arg),
+ slice);
+ req->server_start.application_protocols.funcs.encode =
+ encode_repeated_string_cb;
+ }
+ return true;
+}
+
+bool grpc_gcp_handshaker_req_add_record_protocol(grpc_gcp_handshaker_req* req,
+ const char* record_protocol) {
+ if (req == nullptr || record_protocol == nullptr || !req->has_client_start) {
+ gpr_log(GPR_ERROR,
+ "Invalid arguments to "
+ "grpc_gcp_handshaker_req_add_record_protocol().");
+ return false;
+ }
+ grpc_slice* slice = create_slice(record_protocol, strlen(record_protocol));
+ add_repeated_field(reinterpret_cast<repeated_field**>(
+ &req->client_start.record_protocols.arg),
+ slice);
+ req->client_start.record_protocols.funcs.encode = encode_repeated_string_cb;
+ return true;
+}
+
+static void set_identity_hostname(grpc_gcp_identity* identity,
+ const char* hostname) {
+ grpc_slice* slice = create_slice(hostname, strlen(hostname));
+ identity->hostname.arg = slice;
+ identity->hostname.funcs.encode = encode_string_or_bytes_cb;
+}
+
+static void set_identity_service_account(grpc_gcp_identity* identity,
+ const char* service_account) {
+ grpc_slice* slice = create_slice(service_account, strlen(service_account));
+ identity->service_account.arg = slice;
+ identity->service_account.funcs.encode = encode_string_or_bytes_cb;
+}
+
+bool grpc_gcp_handshaker_req_add_target_identity_hostname(
+ grpc_gcp_handshaker_req* req, const char* hostname) {
+ if (req == nullptr || hostname == nullptr || !req->has_client_start) {
+ gpr_log(GPR_ERROR,
+ "Invalid nullptr arguments to "
+ "grpc_gcp_handshaker_req_add_target_identity_hostname().");
+ return false;
+ }
+ grpc_gcp_identity* target_identity =
+ static_cast<grpc_gcp_identity*>(gpr_zalloc(sizeof(*target_identity)));
+ set_identity_hostname(target_identity, hostname);
+ req->client_start.target_identities.funcs.encode =
+ encode_repeated_identity_cb;
+ add_repeated_field(reinterpret_cast<repeated_field**>(
+ &req->client_start.target_identities.arg),
+ target_identity);
+ return true;
+}
+
+bool grpc_gcp_handshaker_req_add_target_identity_service_account(
+ grpc_gcp_handshaker_req* req, const char* service_account) {
+ if (req == nullptr || service_account == nullptr || !req->has_client_start) {
+ gpr_log(GPR_ERROR,
+ "Invalid nullptr arguments to "
+ "grpc_gcp_handshaker_req_add_target_identity_service_account().");
+ return false;
+ }
+ grpc_gcp_identity* target_identity =
+ static_cast<grpc_gcp_identity*>(gpr_zalloc(sizeof(*target_identity)));
+ set_identity_service_account(target_identity, service_account);
+ req->client_start.target_identities.funcs.encode =
+ encode_repeated_identity_cb;
+ add_repeated_field(reinterpret_cast<repeated_field**>(
+ &req->client_start.target_identities.arg),
+ target_identity);
+ return true;
+}
+
+bool grpc_gcp_handshaker_req_set_local_identity_hostname(
+ grpc_gcp_handshaker_req* req, const char* hostname) {
+ if (req == nullptr || hostname == nullptr || !req->has_client_start) {
+ gpr_log(GPR_ERROR,
+ "Invalid nullptr arguments to "
+ "grpc_gcp_handshaker_req_set_local_identity_hostname().");
+ return false;
+ }
+ req->client_start.has_local_identity = true;
+ set_identity_hostname(&req->client_start.local_identity, hostname);
+ return true;
+}
+
+bool grpc_gcp_handshaker_req_set_local_identity_service_account(
+ grpc_gcp_handshaker_req* req, const char* service_account) {
+ if (req == nullptr || service_account == nullptr || !req->has_client_start) {
+ gpr_log(GPR_ERROR,
+ "Invalid nullptr arguments to "
+ "grpc_gcp_handshaker_req_set_local_identity_service_account().");
+ return false;
+ }
+ req->client_start.has_local_identity = true;
+ set_identity_service_account(&req->client_start.local_identity,
+ service_account);
+ return true;
+}
+
+static void set_endpoint(grpc_gcp_endpoint* endpoint, const char* ip_address,
+ size_t port, grpc_gcp_network_protocol protocol) {
+ grpc_slice* slice = create_slice(ip_address, strlen(ip_address));
+ endpoint->ip_address.arg = slice;
+ endpoint->ip_address.funcs.encode = encode_string_or_bytes_cb;
+ endpoint->has_port = true;
+ endpoint->port = static_cast<int32_t>(port);
+ endpoint->has_protocol = true;
+ endpoint->protocol = protocol;
+}
+
+bool grpc_gcp_handshaker_req_set_rpc_versions(grpc_gcp_handshaker_req* req,
+ uint32_t max_major,
+ uint32_t max_minor,
+ uint32_t min_major,
+ uint32_t min_minor) {
+ if (req == nullptr || req->has_next) {
+ gpr_log(GPR_ERROR,
+ "Invalid arguments to "
+ "grpc_gcp_handshaker_req_set_rpc_versions().");
+ return false;
+ }
+ if (req->has_client_start) {
+ req->client_start.has_rpc_versions = true;
+ grpc_gcp_rpc_protocol_versions_set_max(&req->client_start.rpc_versions,
+ max_major, max_minor);
+ grpc_gcp_rpc_protocol_versions_set_min(&req->client_start.rpc_versions,
+ min_major, min_minor);
+ } else {
+ req->server_start.has_rpc_versions = true;
+ grpc_gcp_rpc_protocol_versions_set_max(&req->server_start.rpc_versions,
+ max_major, max_minor);
+ grpc_gcp_rpc_protocol_versions_set_min(&req->server_start.rpc_versions,
+ min_major, min_minor);
+ }
+ return true;
+}
+
+bool grpc_gcp_handshaker_req_set_local_endpoint(
+ grpc_gcp_handshaker_req* req, const char* ip_address, size_t port,
+ grpc_gcp_network_protocol protocol) {
+ if (req == nullptr || ip_address == nullptr || port > 65535 ||
+ req->has_next) {
+ gpr_log(GPR_ERROR,
+ "Invalid arguments to "
+ "grpc_gcp_handshaker_req_set_local_endpoint().");
+ return false;
+ }
+ if (req->has_client_start) {
+ req->client_start.has_local_endpoint = true;
+ set_endpoint(&req->client_start.local_endpoint, ip_address, port, protocol);
+ } else {
+ req->server_start.has_local_endpoint = true;
+ set_endpoint(&req->server_start.local_endpoint, ip_address, port, protocol);
+ }
+ return true;
+}
+
+bool grpc_gcp_handshaker_req_set_remote_endpoint(
+ grpc_gcp_handshaker_req* req, const char* ip_address, size_t port,
+ grpc_gcp_network_protocol protocol) {
+ if (req == nullptr || ip_address == nullptr || port > 65535 ||
+ req->has_next) {
+ gpr_log(GPR_ERROR,
+ "Invalid arguments to "
+ "grpc_gcp_handshaker_req_set_remote_endpoint().");
+ return false;
+ }
+ if (req->has_client_start) {
+ req->client_start.has_remote_endpoint = true;
+ set_endpoint(&req->client_start.remote_endpoint, ip_address, port,
+ protocol);
+ } else {
+ req->server_start.has_remote_endpoint = true;
+ set_endpoint(&req->server_start.remote_endpoint, ip_address, port,
+ protocol);
+ }
+ return true;
+}
+
+bool grpc_gcp_handshaker_req_set_in_bytes(grpc_gcp_handshaker_req* req,
+ const char* in_bytes, size_t size) {
+ if (req == nullptr || in_bytes == nullptr || req->has_client_start) {
+ gpr_log(GPR_ERROR,
+ "Invalid arguments to "
+ "grpc_gcp_handshaker_req_set_in_bytes().");
+ return false;
+ }
+ grpc_slice* slice = create_slice(in_bytes, size);
+ if (req->has_next) {
+ req->next.in_bytes.arg = slice;
+ req->next.in_bytes.funcs.encode = &encode_string_or_bytes_cb;
+ } else {
+ req->server_start.in_bytes.arg = slice;
+ req->server_start.in_bytes.funcs.encode = &encode_string_or_bytes_cb;
+ }
+ return true;
+}
+
+static grpc_gcp_server_handshake_parameters* server_start_find_param(
+ grpc_gcp_handshaker_req* req, int32_t key) {
+ size_t i = 0;
+ for (i = 0; i < req->server_start.handshake_parameters_count; i++) {
+ if (req->server_start.handshake_parameters[i].key == key) {
+ return &req->server_start.handshake_parameters[i].value;
+ }
+ }
+ req->server_start
+ .handshake_parameters[req->server_start.handshake_parameters_count]
+ .has_key = true;
+ req->server_start
+ .handshake_parameters[req->server_start.handshake_parameters_count]
+ .has_value = true;
+ req->server_start
+ .handshake_parameters[req->server_start.handshake_parameters_count++]
+ .key = key;
+ return &req->server_start
+ .handshake_parameters
+ [req->server_start.handshake_parameters_count - 1]
+ .value;
+}
+
+bool grpc_gcp_handshaker_req_param_add_record_protocol(
+ grpc_gcp_handshaker_req* req, grpc_gcp_handshake_protocol key,
+ const char* record_protocol) {
+ if (req == nullptr || record_protocol == nullptr || !req->has_server_start) {
+ gpr_log(GPR_ERROR,
+ "Invalid arguments to "
+ "grpc_gcp_handshaker_req_param_add_record_protocol().");
+ return false;
+ }
+ grpc_gcp_server_handshake_parameters* param =
+ server_start_find_param(req, key);
+ grpc_slice* slice = create_slice(record_protocol, strlen(record_protocol));
+ add_repeated_field(
+ reinterpret_cast<repeated_field**>(&param->record_protocols.arg), slice);
+ param->record_protocols.funcs.encode = &encode_repeated_string_cb;
+ return true;
+}
+
+bool grpc_gcp_handshaker_req_param_add_local_identity_hostname(
+ grpc_gcp_handshaker_req* req, grpc_gcp_handshake_protocol key,
+ const char* hostname) {
+ if (req == nullptr || hostname == nullptr || !req->has_server_start) {
+ gpr_log(GPR_ERROR,
+ "Invalid arguments to "
+ "grpc_gcp_handshaker_req_param_add_local_identity_hostname().");
+ return false;
+ }
+ grpc_gcp_server_handshake_parameters* param =
+ server_start_find_param(req, key);
+ grpc_gcp_identity* local_identity =
+ static_cast<grpc_gcp_identity*>(gpr_zalloc(sizeof(*local_identity)));
+ set_identity_hostname(local_identity, hostname);
+ add_repeated_field(
+ reinterpret_cast<repeated_field**>(&param->local_identities.arg),
+ local_identity);
+ param->local_identities.funcs.encode = &encode_repeated_identity_cb;
+ return true;
+}
+
+bool grpc_gcp_handshaker_req_param_add_local_identity_service_account(
+ grpc_gcp_handshaker_req* req, grpc_gcp_handshake_protocol key,
+ const char* service_account) {
+ if (req == nullptr || service_account == nullptr || !req->has_server_start) {
+ gpr_log(
+ GPR_ERROR,
+ "Invalid arguments to "
+ "grpc_gcp_handshaker_req_param_add_local_identity_service_account().");
+ return false;
+ }
+ grpc_gcp_server_handshake_parameters* param =
+ server_start_find_param(req, key);
+ grpc_gcp_identity* local_identity =
+ static_cast<grpc_gcp_identity*>(gpr_zalloc(sizeof(*local_identity)));
+ set_identity_service_account(local_identity, service_account);
+ add_repeated_field(
+ reinterpret_cast<repeated_field**>(&param->local_identities.arg),
+ local_identity);
+ param->local_identities.funcs.encode = &encode_repeated_identity_cb;
+ return true;
+}
+
+bool grpc_gcp_handshaker_req_encode(grpc_gcp_handshaker_req* req,
+ grpc_slice* slice) {
+ if (req == nullptr || slice == nullptr) {
+ gpr_log(GPR_ERROR,
+ "Invalid nullptr arguments to grpc_gcp_handshaker_req_encode().");
+ return false;
+ }
+ pb_ostream_t size_stream;
+ memset(&size_stream, 0, sizeof(pb_ostream_t));
+ if (!pb_encode(&size_stream, grpc_gcp_HandshakerReq_fields, req)) {
+ gpr_log(GPR_ERROR, "nanopb error: %s", PB_GET_ERROR(&size_stream));
+ return false;
+ }
+ size_t encoded_length = size_stream.bytes_written;
+ *slice = grpc_slice_malloc(encoded_length);
+ pb_ostream_t output_stream =
+ pb_ostream_from_buffer(GRPC_SLICE_START_PTR(*slice), encoded_length);
+ if (!pb_encode(&output_stream, grpc_gcp_HandshakerReq_fields, req) != 0) {
+ gpr_log(GPR_ERROR, "nanopb error: %s", PB_GET_ERROR(&output_stream));
+ return false;
+ }
+ return true;
+}
+
+/* HandshakerResp. */
+grpc_gcp_handshaker_resp* grpc_gcp_handshaker_resp_create(void) {
+ grpc_gcp_handshaker_resp* resp =
+ static_cast<grpc_gcp_handshaker_resp*>(gpr_zalloc(sizeof(*resp)));
+ return resp;
+}
+
+void grpc_gcp_handshaker_resp_destroy(grpc_gcp_handshaker_resp* resp) {
+ if (resp != nullptr) {
+ destroy_slice(static_cast<grpc_slice*>(resp->out_frames.arg));
+ if (resp->has_status) {
+ destroy_slice(static_cast<grpc_slice*>(resp->status.details.arg));
+ }
+ if (resp->has_result) {
+ destroy_slice(
+ static_cast<grpc_slice*>(resp->result.application_protocol.arg));
+ destroy_slice(static_cast<grpc_slice*>(resp->result.record_protocol.arg));
+ destroy_slice(static_cast<grpc_slice*>(resp->result.key_data.arg));
+ if (resp->result.has_local_identity) {
+ destroy_slice(
+ static_cast<grpc_slice*>(resp->result.local_identity.hostname.arg));
+ destroy_slice(static_cast<grpc_slice*>(
+ resp->result.local_identity.service_account.arg));
+ }
+ if (resp->result.has_peer_identity) {
+ destroy_slice(
+ static_cast<grpc_slice*>(resp->result.peer_identity.hostname.arg));
+ destroy_slice(static_cast<grpc_slice*>(
+ resp->result.peer_identity.service_account.arg));
+ }
+ }
+ gpr_free(resp);
+ }
+}
+
+bool grpc_gcp_handshaker_resp_decode(grpc_slice encoded_handshaker_resp,
+ grpc_gcp_handshaker_resp* resp) {
+ if (resp == nullptr) {
+ gpr_log(GPR_ERROR,
+ "Invalid nullptr argument to grpc_gcp_handshaker_resp_decode().");
+ return false;
+ }
+ pb_istream_t stream =
+ pb_istream_from_buffer(GRPC_SLICE_START_PTR(encoded_handshaker_resp),
+ GRPC_SLICE_LENGTH(encoded_handshaker_resp));
+ resp->out_frames.funcs.decode = decode_string_or_bytes_cb;
+ resp->status.details.funcs.decode = decode_string_or_bytes_cb;
+ resp->result.application_protocol.funcs.decode = decode_string_or_bytes_cb;
+ resp->result.record_protocol.funcs.decode = decode_string_or_bytes_cb;
+ resp->result.key_data.funcs.decode = decode_string_or_bytes_cb;
+ resp->result.peer_identity.hostname.funcs.decode = decode_string_or_bytes_cb;
+ resp->result.peer_identity.service_account.funcs.decode =
+ decode_string_or_bytes_cb;
+ resp->result.local_identity.hostname.funcs.decode = decode_string_or_bytes_cb;
+ resp->result.local_identity.service_account.funcs.decode =
+ decode_string_or_bytes_cb;
+ if (!pb_decode(&stream, grpc_gcp_HandshakerResp_fields, resp)) {
+ gpr_log(GPR_ERROR, "nanopb error: %s", PB_GET_ERROR(&stream));
+ return false;
+ }
+ return true;
+}