diff --git a/include/istio/utils/BUILD b/include/istio/utils/BUILD index 3a5045b8486..788c4e8a8c1 100644 --- a/include/istio/utils/BUILD +++ b/include/istio/utils/BUILD @@ -18,8 +18,8 @@ cc_library( name = "headers_lib", hdrs = [ "attributes_builder.h", + "concat_hash.h", "local_attributes.h", - "md5.h", "protobuf.h", "status.h", ], diff --git a/include/istio/utils/concat_hash.h b/include/istio/utils/concat_hash.h new file mode 100644 index 00000000000..8906f07089d --- /dev/null +++ b/include/istio/utils/concat_hash.h @@ -0,0 +1,65 @@ +/* Copyright 2017 Istio Authors. All Rights Reserved. + * + * 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. + */ + +#ifndef ISTIO_UTILS_CONCAT_HASH_H_ +#define ISTIO_UTILS_CONCAT_HASH_H_ + +#include +#include +#include + +namespace istio { +namespace utils { + +// The hash type for Check cache. +typedef std::size_t HashType; + +// This class concatenates multiple values into a string as hash +class ConcatHash { + public: + ConcatHash(size_t reserve_size) { hash_.reserve(reserve_size); } + + // Updates the context with data. + ConcatHash& Update(const void* data, size_t size) { + hash_.append(static_cast(data), size); + return *this; + } + + // A helper function for int + ConcatHash& Update(int d) { return Update(&d, sizeof(d)); } + + // A helper function for const char* + ConcatHash& Update(const char* str) { + hash_.append(str); + return *this; + } + + // A helper function for const string + ConcatHash& Update(const std::string& str) { + hash_.append(str); + return *this; + } + + // Returns the hash of the concated string. + HashType getHash() const { return std::hash{}(hash_); } + + private: + std::string hash_; +}; + +} // namespace utils +} // namespace istio + +#endif // ISTIO_UTILS_CONCAT_HASH_H_ diff --git a/include/istio/utils/md5.h b/include/istio/utils/md5.h deleted file mode 100644 index 19b1c9dbe8f..00000000000 --- a/include/istio/utils/md5.h +++ /dev/null @@ -1,68 +0,0 @@ -/* Copyright 2017 Istio Authors. All Rights Reserved. - * - * 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. - */ - -#ifndef ISTIO_UTILS_MD5_H_ -#define ISTIO_UTILS_MD5_H_ - -#include -#include -#include "openssl/md5.h" - -namespace istio { -namespace utils { - -// Define a MD5 Digest by calling OpenSSL -class MD5 { - public: - MD5(); - - // Updates the context with data. - MD5& Update(const void* data, size_t size); - - // A helper function for const char* - MD5& Update(const char* str) { return Update(str, strlen(str)); } - - // A helper function for const string - MD5& Update(const std::string& str) { return Update(str.data(), str.size()); } - - // A helper function for int - MD5& Update(int d) { return Update(&d, sizeof(d)); } - - // The MD5 digest is always 128 bits = 16 bytes - static const int kDigestLength = 16; - - // Returns the digest as string. - std::string Digest(); - - // A short form of generating MD5 for a string - std::string operator()(const void* data, size_t size); - - // Converts a binary digest string to a printable string. - // It is for debugging and unit-test only. - static std::string DebugString(const std::string& digest); - - private: - // MD5 context. - MD5_CTX ctx_; - // The final MD5 digest. - unsigned char digest_[kDigestLength]; - // A flag to indicate if MD5_final is called or not. - bool finalized_; -}; - -} // namespace utils -} // namespace istio - -#endif // ISTIO_UTILS_MD5_H_ diff --git a/src/envoy/BUILD b/src/envoy/BUILD index 43abb6b554f..c6eeb279f2e 100644 --- a/src/envoy/BUILD +++ b/src/envoy/BUILD @@ -29,7 +29,6 @@ envoy_cc_binary( "//src/envoy/http/jwt_auth:http_filter_factory", "//src/envoy/http/mixer:filter_lib", "//src/envoy/tcp/mixer:filter_lib", - "//src/envoy/alts:alts_socket_factory", "@envoy//source/exe:envoy_main_entry_lib", ], ) diff --git a/src/envoy/alts/BUILD b/src/envoy/alts/BUILD deleted file mode 100644 index 0076e57d8e6..00000000000 --- a/src/envoy/alts/BUILD +++ /dev/null @@ -1,111 +0,0 @@ -# Copyright 2018 Istio Authors. All Rights Reserved. -# -# 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. -# -################################################################################ -# -load( - "@envoy//bazel:envoy_build_system.bzl", - "envoy_cc_library", -) - -load( - "@envoy_api//bazel:api_build_system.bzl", - "api_proto_library", -) - -api_proto_library( - name = "alts_socket_proto", - srcs = [":alts_socket.proto"], - visibility = ["//visibility:public"], - require_py = 0, -) - -envoy_cc_library( - name = "grpc_tsi_wrapper", - repository = "@envoy", - visibility = ["//visibility:private"], - hdrs = [ - "transport_security_interface_wrapper.h", - ], - external_deps = [ - "grpc", - ], -) - -envoy_cc_library( - name = "tsi_handshaker", - repository = "@envoy", - visibility = ["//visibility:public"], - srcs = [ - "tsi_handshaker.cc", - ], - hdrs = [ - "tsi_handshaker.h", - ], - deps = [ - ":grpc_tsi_wrapper", - "@envoy//source/exe:envoy_common_lib", - ], -) - -envoy_cc_library( - name = "tsi_frame_protector", - repository = "@envoy", - visibility = ["//visibility:public"], - srcs = [ - "tsi_frame_protector.cc", - ], - hdrs = [ - "tsi_frame_protector.h", - ], - deps = [ - ":grpc_tsi_wrapper", - "@envoy//source/exe:envoy_common_lib", - ], -) - -envoy_cc_library( - name = "tsi_transport_socket", - repository = "@envoy", - visibility = ["//visibility:public"], - srcs = [ - "tsi_transport_socket.cc", - ], - hdrs = [ - "tsi_transport_socket.h", - ], - deps = [ - ":tsi_frame_protector", - ":tsi_handshaker", - "@envoy//source/exe:envoy_common_lib", - ], -) - -envoy_cc_library( - name = "alts_socket_factory", - repository = "@envoy", - visibility = ["//visibility:public"], - srcs = [ - "alts_socket_factory.cc", - ], - hdrs = [ - "alts_socket_factory.h", - ], - deps = [ - ":grpc_tsi_wrapper", - ":tsi_transport_socket", - ":alts_socket_proto_cc", - "@envoy//source/exe:envoy_common_lib", - ], -) diff --git a/src/envoy/alts/README.md b/src/envoy/alts/README.md deleted file mode 100644 index 5eeaa79bb60..00000000000 --- a/src/envoy/alts/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# ALTS support (experimental) - -*The code in this directory is experimental. Do not use in production* - -A prototype of -[ALTS](https://cloud.google.com/security/encryption-in-transit/application-layer-transport-security/) -support for Istio/Envoy. It depends on ALTS stack in gRPC library and implemented as Envoy's -[transport socket](https://www.envoyproxy.io/docs/envoy/latest/api-v2/api/v2/core/base.proto#core-transportsocket). - -An example config is in `example.yaml`. Note: If you want to enable the peer validation, please -uncomment and replace the content of `peer_service_accounts` with the actual service account in your -environment. Please make sure the service account is correct otherwise the ALTS connection will be -closed due to validation failure. diff --git a/src/envoy/alts/alts_socket.proto b/src/envoy/alts/alts_socket.proto deleted file mode 100644 index 7f7bf7a6c5e..00000000000 --- a/src/envoy/alts/alts_socket.proto +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2018 Istio 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. - -syntax = "proto3"; - -package envoy.security.v2; - -import "google/protobuf/duration.proto"; -import "validate/validate.proto"; - -message AltsSocket { - // The location of a handshaker service, this is usually 169.254.169.254:8080 - // on GCE - string handshaker_service = 1 [(validate.rules).string.min_bytes = 1]; - - // The acceptable service accounts from peer, peers not in the list will be - // rejected in the handshake validation step. - // If empty, no validation will be performed. - repeated string peer_service_accounts = 2; -} diff --git a/src/envoy/alts/alts_socket_factory.cc b/src/envoy/alts/alts_socket_factory.cc deleted file mode 100644 index a4e24ab43d8..00000000000 --- a/src/envoy/alts/alts_socket_factory.cc +++ /dev/null @@ -1,158 +0,0 @@ -/* Copyright 2018 Istio Authors. All Rights Reserved. - * - * 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 "src/envoy/alts/alts_socket_factory.h" -#include "absl/strings/str_join.h" -#include "common/common/assert.h" -#include "common/protobuf/protobuf.h" -#include "common/protobuf/utility.h" -#include "envoy/registry/registry.h" -#include "envoy/server/transport_socket_config.h" -#include "src/envoy/alts/alts_socket.pb.h" -#include "src/envoy/alts/alts_socket.pb.validate.h" -#include "src/envoy/alts/transport_security_interface_wrapper.h" -#include "src/envoy/alts/tsi_handshaker.h" -#include "src/envoy/alts/tsi_transport_socket.h" - -namespace Envoy { -namespace Server { -namespace Configuration { - -using ::google::protobuf::RepeatedPtrField; - -// Returns true if the peer's service account is found in peers, otherwise -// returns false and fills out err with an error message. -static bool doValidate(const tsi_peer &peer, - const std::unordered_set &peers, - std::string &err) { - for (size_t i = 0; i < peer.property_count; ++i) { - std::string name = std::string(peer.properties[i].name); - std::string value = std::string(peer.properties[i].value.data, - peer.properties[i].value.length); - if (name.compare(TSI_ALTS_SERVICE_ACCOUNT_PEER_PROPERTY) == 0 && - peers.find(value) != peers.end()) { - return true; - } - } - - err = "Couldn't find peer's service account in peer_service_accounts: " + - absl::StrJoin(peers, ","); - return false; -} - -ProtobufTypes::MessagePtr -AltsTransportSocketConfigFactory::createEmptyConfigProto() { - return std::make_unique(); -} - -std::string -Envoy::Server::Configuration::AltsTransportSocketConfigFactory::name() const { - return "alts"; -} - -Network::TransportSocketFactoryPtr -UpstreamAltsTransportSocketConfigFactory::createTransportSocketFactory( - const Protobuf::Message &message, TransportSocketFactoryContext &) { - auto config = - MessageUtil::downcastAndValidate( - message); - - std::string handshaker_service = config.handshaker_service(); - const auto &peer_service_accounts = config.peer_service_accounts(); - std::unordered_set peers(peer_service_accounts.cbegin(), - peer_service_accounts.cend()); - - Security::HandshakeValidator validator; - // Skip validation if peers is empty. - if (!peers.empty()) { - validator = [peers](const tsi_peer &peer, std::string &err) { - return doValidate(peer, peers, err); - }; - } - - return std::make_unique( - [handshaker_service](Event::Dispatcher &dispatcher) { - grpc_alts_credentials_options *options = - grpc_alts_credentials_client_options_create(); - - tsi_handshaker *handshaker = nullptr; - - // Specifying target name as empty since TSI won't take care of - // validating peer identity in this use case. The validation will be - // implemented in TsiSocket later. - alts_tsi_handshaker_create(options, "", handshaker_service.c_str(), - true /* is_client */, &handshaker); - - ASSERT(handshaker != nullptr); - - grpc_alts_credentials_options_destroy(options); - - return std::make_unique(handshaker, - dispatcher); - }, - validator); -} - -Network::TransportSocketFactoryPtr -DownstreamAltsTransportSocketConfigFactory::createTransportSocketFactory( - const Protobuf::Message &message, TransportSocketFactoryContext &, - const std::vector &) { - auto config = - MessageUtil::downcastAndValidate( - message); - - std::string handshaker_service = config.handshaker_service(); - const auto &peer_service_accounts = config.peer_service_accounts(); - std::unordered_set peers(peer_service_accounts.cbegin(), - peer_service_accounts.cend()); - - Security::HandshakeValidator validator; - // Skip validation if peers is empty. - if (!peers.empty()) { - validator = [peers](const tsi_peer &peer, std::string &err) { - return doValidate(peer, peers, err); - }; - } - - return std::make_unique( - [handshaker_service](Event::Dispatcher &dispatcher) { - grpc_alts_credentials_options *options = - grpc_alts_credentials_server_options_create(); - - tsi_handshaker *handshaker = nullptr; - - alts_tsi_handshaker_create(options, nullptr, handshaker_service.c_str(), - false /* is_client */, &handshaker); - - ASSERT(handshaker != nullptr); - - grpc_alts_credentials_options_destroy(options); - - return std::make_unique(handshaker, - dispatcher); - }, - validator); -} - -static Registry::RegisterFactory - upstream_registered_; - -static Registry::RegisterFactory - downstream_registered_; -} // namespace Configuration -} // namespace Server -} // namespace Envoy diff --git a/src/envoy/alts/alts_socket_factory.h b/src/envoy/alts/alts_socket_factory.h deleted file mode 100644 index 797f5d87787..00000000000 --- a/src/envoy/alts/alts_socket_factory.h +++ /dev/null @@ -1,47 +0,0 @@ -/* Copyright 2018 Istio Authors. All Rights Reserved. - * - * 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 "envoy/server/transport_socket_config.h" - -namespace Envoy { -namespace Server { -namespace Configuration { - -// ALTS config registry -class AltsTransportSocketConfigFactory - : public virtual TransportSocketConfigFactory { - public: - ProtobufTypes::MessagePtr createEmptyConfigProto() override; - std::string name() const override; -}; - -class UpstreamAltsTransportSocketConfigFactory - : public AltsTransportSocketConfigFactory, - public UpstreamTransportSocketConfigFactory { - public: - Network::TransportSocketFactoryPtr createTransportSocketFactory( - const Protobuf::Message &, TransportSocketFactoryContext &) override; -}; - -class DownstreamAltsTransportSocketConfigFactory - : public AltsTransportSocketConfigFactory, - public DownstreamTransportSocketConfigFactory { - public: - Network::TransportSocketFactoryPtr createTransportSocketFactory( - const Protobuf::Message &, TransportSocketFactoryContext &, - const std::vector &) override; -}; -} // namespace Configuration -} // namespace Server -} // namespace Envoy diff --git a/src/envoy/alts/example.yaml b/src/envoy/alts/example.yaml deleted file mode 100644 index d157684969b..00000000000 --- a/src/envoy/alts/example.yaml +++ /dev/null @@ -1,59 +0,0 @@ -static_resources: - listeners: - - address: - socket_address: - address: 127.0.0.1 - port_value: 5000 - filter_chains: - - filters: - - name: envoy.tcp_proxy - config: - stat_prefix: client_tcp - cluster: server_envoy - - address: - socket_address: - address: 127.0.0.1 - port_value: 5005 - filter_chains: - - transport_socket: - name: alts - config: - handshaker_service: "169.254.169.254:8080" - # If you want to enable the peer validation, please uncomment peer_service_accounts and - # replace it with the actual service account used in your environment. - # peer_service_accounts: ["test-service-account"] - filters: - - name: envoy.tcp_proxy - config: - stat_prefix: server_tcp - cluster: tcp_backend - clusters: - - name: server_envoy - transport_socket: - name: alts - config: - handshaker_service: "169.254.169.254:8080" - # If you want to enable the peer validation, please uncomment peer_service_accounts and - # replace it with the actual service account used in your environment. - # peer_service_accounts: ["test-service-account"] - connect_timeout: 0.25s - type: strict_dns - lb_policy: round_robin - hosts: - - socket_address: - address: 127.0.0.1 - port_value: 5005 - - name: tcp_backend - connect_timeout: 0.25s - type: strict_dns - lb_policy: round_robin - hosts: - - socket_address: - address: 127.0.0.1 - port_value: 5050 -admin: - access_log_path: "/dev/null" - address: - socket_address: - address: 0.0.0.0 - port_value: 8001 diff --git a/src/envoy/alts/transport_security_interface_wrapper.h b/src/envoy/alts/transport_security_interface_wrapper.h deleted file mode 100644 index 9e6c60e60b2..00000000000 --- a/src/envoy/alts/transport_security_interface_wrapper.h +++ /dev/null @@ -1,26 +0,0 @@ -/* Copyright 2018 Istio Authors. All Rights Reserved. - * - * 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. - */ - -// Some gRPC headers contains old style cast and unused parameter which doesn't -// compile with -Werror, ignoring those compiler warning since we don't have -// control on those source codes. This works with GCC and Clang. - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-parameter" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#include "grpc/grpc_security.h" -#include "src/core/tsi/alts/handshaker/alts_tsi_handshaker.h" -#include "src/core/tsi/transport_security_interface.h" -#pragma GCC diagnostic pop diff --git a/src/envoy/alts/tsi_frame_protector.cc b/src/envoy/alts/tsi_frame_protector.cc deleted file mode 100644 index a4454e5e614..00000000000 --- a/src/envoy/alts/tsi_frame_protector.cc +++ /dev/null @@ -1,94 +0,0 @@ -/* Copyright 2018 Istio Authors. All Rights Reserved. - * - * 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 "src/envoy/alts/tsi_frame_protector.h" - -#include "common/common/assert.h" - -namespace Envoy { -namespace Security { - -TsiFrameProtector::TsiFrameProtector(tsi_frame_protector *frame_protector) - : frame_protector_(frame_protector) {} - -tsi_result TsiFrameProtector::protect(Buffer::Instance &input, - Buffer::Instance &output) { - ASSERT(frame_protector_); - - // TODO(lizan): tune size later - unsigned char protected_buffer[4096]; - size_t protected_buffer_size = sizeof(protected_buffer); - while (input.length() > 0) { - auto *message_bytes = - reinterpret_cast(input.linearize(input.length())); - size_t protected_buffer_size_to_send = protected_buffer_size; - size_t processed_message_size = input.length(); - tsi_result result = tsi_frame_protector_protect( - frame_protector_.get(), message_bytes, &processed_message_size, - protected_buffer, &protected_buffer_size_to_send); - if (result != TSI_OK) { - ASSERT(result != TSI_INVALID_ARGUMENT && result != TSI_UNIMPLEMENTED); - return result; - } - output.add(protected_buffer, protected_buffer_size_to_send); - input.drain(processed_message_size); - } - - ASSERT(input.length() == 0); - size_t still_pending_size; - do { - size_t protected_buffer_size_to_send = protected_buffer_size; - tsi_result result = tsi_frame_protector_protect_flush( - frame_protector_.get(), protected_buffer, - &protected_buffer_size_to_send, &still_pending_size); - if (result != TSI_OK) { - ASSERT(result != TSI_INVALID_ARGUMENT && result != TSI_UNIMPLEMENTED); - return result; - } - output.add(protected_buffer, protected_buffer_size_to_send); - } while (still_pending_size > 0); - - return TSI_OK; -} - -tsi_result TsiFrameProtector::unprotect(Buffer::Instance &input, - Buffer::Instance &output) { - ASSERT(frame_protector_); - - // TODO(lizan): Tune the buffer size. - unsigned char unprotected_buffer[4096]; - size_t unprotected_buffer_size = sizeof(unprotected_buffer); - - while (input.length() > 0) { - auto *message_bytes = - reinterpret_cast(input.linearize(input.length())); - size_t unprotected_buffer_size_to_send = unprotected_buffer_size; - size_t processed_message_size = input.length(); - tsi_result result = tsi_frame_protector_unprotect( - frame_protector_.get(), message_bytes, &processed_message_size, - unprotected_buffer, &unprotected_buffer_size_to_send); - if (result != TSI_OK) { - ASSERT(result != TSI_INVALID_ARGUMENT && result != TSI_UNIMPLEMENTED); - return result; - } - output.add(unprotected_buffer, unprotected_buffer_size_to_send); - input.drain(processed_message_size); - } - - return TSI_OK; -} - -} // namespace Security -} // namespace Envoy diff --git a/src/envoy/alts/tsi_frame_protector.h b/src/envoy/alts/tsi_frame_protector.h deleted file mode 100644 index ccd36a6a9e5..00000000000 --- a/src/envoy/alts/tsi_frame_protector.h +++ /dev/null @@ -1,65 +0,0 @@ -/* Copyright 2018 Istio Authors. All Rights Reserved. - * - * 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. - */ -#pragma once - -#include "common/common/c_smart_ptr.h" -#include "envoy/buffer/buffer.h" -#include "envoy/event/dispatcher.h" - -#include "src/envoy/alts/transport_security_interface_wrapper.h" - -namespace Envoy { -namespace Security { - -typedef CSmartPtr - CFrameProtectorPtr; - -/** - * A C++ wrapper for tsi_frame_protector interface. - * For detail of tsi_frame_protector, see - * https://github.com/grpc/grpc/blob/v1.10.0/src/core/tsi/transport_security_interface.h#L70 - * - * TODO(lizan): migrate to tsi_zero_copy_grpc_protector for further optimization - */ -class TsiFrameProtector final { - public: - explicit TsiFrameProtector(tsi_frame_protector* frame_protector); - - /** - * Wrapper for tsi_frame_protector_protect - * @param input supplies the input buffer, the method will drain it when it is - * protected. - * @param output supplies the output buffer - * @return tsi_result the status. - */ - tsi_result protect(Buffer::Instance& input, Buffer::Instance& output); - - /** - * Wrapper for tsi_frame_protector_unprotect - * @param input supplies the input buffer, the method will drain it when it is - * protected. - * @param output supplies the output buffer - * @return tsi_result the status. - */ - tsi_result unprotect(Buffer::Instance& input, Buffer::Instance& output); - - private: - CFrameProtectorPtr frame_protector_; -}; - -typedef std::unique_ptr TsiFrameProtectorPtr; - -} // namespace Security -} // namespace Envoy diff --git a/src/envoy/alts/tsi_handshaker.cc b/src/envoy/alts/tsi_handshaker.cc deleted file mode 100644 index d5139470c39..00000000000 --- a/src/envoy/alts/tsi_handshaker.cc +++ /dev/null @@ -1,86 +0,0 @@ -/* Copyright 2018 Istio Authors. All Rights Reserved. - * - * 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 "src/envoy/alts/tsi_handshaker.h" -#include "common/buffer/buffer_impl.h" -#include "common/common/assert.h" - -namespace Envoy { -namespace Security { - -void TsiHandshaker::onNextDone(tsi_result status, void *user_data, - const unsigned char *bytes_to_send, - size_t bytes_to_send_size, - tsi_handshaker_result *handshaker_result) { - TsiHandshaker *handshaker = static_cast(user_data); - - Buffer::InstancePtr to_send = std::make_unique(); - if (bytes_to_send_size > 0) { - to_send->add(bytes_to_send, bytes_to_send_size); - } - - auto next_result = new TsiHandshakerCallbacks::NextResult{ - status, std::move(to_send), {handshaker_result}}; - - handshaker->dispatcher_.post([handshaker, next_result]() { - ASSERT(handshaker->calling_); - handshaker->calling_ = false; - - TsiHandshakerCallbacks::NextResultPtr next_result_ptr{next_result}; - - if (handshaker->delete_on_done_) { - handshaker->dispatcher_.deferredDelete( - Event::DeferredDeletablePtr{handshaker}); - return; - } - handshaker->callbacks_->onNextDone(std::move(next_result_ptr)); - }); -} - -TsiHandshaker::TsiHandshaker(tsi_handshaker *handshaker, - Event::Dispatcher &dispatcher) - : handshaker_(handshaker), dispatcher_(dispatcher) {} - -TsiHandshaker::~TsiHandshaker() { ASSERT(!calling_); } - -tsi_result TsiHandshaker::next(Envoy::Buffer::Instance &received) { - ASSERT(!calling_); - calling_ = true; - - uint64_t received_size = received.length(); - const unsigned char *bytes_to_send = nullptr; - size_t bytes_to_send_size = 0; - tsi_handshaker_result *result = nullptr; - tsi_result status = - tsi_handshaker_next(handshaker_.get(), - reinterpret_cast( - received.linearize(received_size)), - received_size, &bytes_to_send, &bytes_to_send_size, - &result, onNextDone, this); - - if (status != TSI_ASYNC) { - onNextDone(status, this, bytes_to_send, bytes_to_send_size, result); - } - return status; -} - -void TsiHandshaker::deferredDelete() { - if (calling_) { - delete_on_done_ = true; - } else { - dispatcher_.deferredDelete(Event::DeferredDeletablePtr{this}); - } -} -} // namespace Security -} // namespace Envoy diff --git a/src/envoy/alts/tsi_handshaker.h b/src/envoy/alts/tsi_handshaker.h deleted file mode 100644 index 01e8310aba8..00000000000 --- a/src/envoy/alts/tsi_handshaker.h +++ /dev/null @@ -1,112 +0,0 @@ -/* Copyright 2018 Istio Authors. All Rights Reserved. - * - * 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. - */ -#pragma once - -#include -#include - -#include "common/common/c_smart_ptr.h" -#include "envoy/buffer/buffer.h" -#include "envoy/event/dispatcher.h" - -#include "src/envoy/alts/transport_security_interface_wrapper.h" - -namespace Envoy { -namespace Security { - -typedef CSmartPtr - TsiHandshakerResultPtr; -typedef CSmartPtr CHandshakerPtr; - -/** - * An interface to get callback from TsiHandshaker. - * TsiHandshaker will call this callback in the thread which its dispatcher - * posts. - */ -class TsiHandshakerCallbacks { - public: - virtual ~TsiHandshakerCallbacks() {} - - struct NextResult { - // A enum of the result - tsi_result status_; - - // The buffer to be sent to the peer - Buffer::InstancePtr to_send_; - - // A pointer to tsi_handshaker_result struct. Owned by instance. - TsiHandshakerResultPtr result_; - }; - - typedef std::unique_ptr NextResultPtr; - - /** - * Called when `next` is done, this may be called in line in `next` if the - * handshaker is not - * asynchronous. - * @param result - */ - virtual void onNextDone(NextResultPtr&& result) PURE; -}; - -/** - * A C++ wrapper for tsi_handshaker interface. - * For detail of tsi_handshaker, see - * https://github.com/grpc/grpc/blob/v1.10.0/src/core/tsi/transport_security_interface.h#L236 - */ -class TsiHandshaker final : public Event::DeferredDeletable { - public: - explicit TsiHandshaker(tsi_handshaker* handshaker, - Event::Dispatcher& dispatcher); - ~TsiHandshaker(); - - /** - * Conduct next step of handshake, see - * https://github.com/grpc/grpc/blob/v1.10.0/src/core/tsi/transport_security_interface.h#L416 - * @param received the buffer received from peer. - */ - tsi_result next(Buffer::Instance& received); - - /** - * Set handshaker callbacks, this must be called before calling next. - * @param callbacks supplies the callback instance. - */ - void setHandshakerCallbacks(TsiHandshakerCallbacks& callbacks) { - callbacks_ = &callbacks; - } - - /** - * Delete the handshaker when it is ready. This must be called after releasing - * from a smart - * pointer. The actual delete happens after ongoing next call are processed. - */ - void deferredDelete(); - - private: - static void onNextDone(tsi_result status, void* user_data, - const unsigned char* bytes_to_send, - size_t bytes_to_send_size, - tsi_handshaker_result* handshaker_result); - - CHandshakerPtr handshaker_; - TsiHandshakerCallbacks* callbacks_{nullptr}; - bool calling_{false}; - bool delete_on_done_{false}; - Event::Dispatcher& dispatcher_; -}; - -typedef std::unique_ptr TsiHandshakerPtr; -} // namespace Security -} // namespace Envoy diff --git a/src/envoy/alts/tsi_transport_socket.cc b/src/envoy/alts/tsi_transport_socket.cc deleted file mode 100644 index 9e61ce1efd9..00000000000 --- a/src/envoy/alts/tsi_transport_socket.cc +++ /dev/null @@ -1,228 +0,0 @@ -/* Copyright 2018 Istio Authors. All Rights Reserved. - * - * 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 "src/envoy/alts/tsi_transport_socket.h" - -#include "common/common/assert.h" -#include "common/common/enum_to_int.h" - -namespace Envoy { -namespace Security { - -TsiSocket::TsiSocket(HandshakerFactory handshaker_factory, - HandshakeValidator handshake_validator) - : handshaker_factory_(handshaker_factory), - handshake_validator_(handshake_validator), - raw_buffer_callbacks_(*this) { - raw_buffer_socket_.setTransportSocketCallbacks(raw_buffer_callbacks_); -} - -TsiSocket::~TsiSocket() { ASSERT(!handshaker_); } - -void TsiSocket::setTransportSocketCallbacks( - Envoy::Network::TransportSocketCallbacks &callbacks) { - callbacks_ = &callbacks; - - handshaker_ = handshaker_factory_(callbacks.connection().dispatcher()); - handshaker_->setHandshakerCallbacks(*this); -} - -std::string TsiSocket::protocol() const { return ""; } - -Network::PostIoAction TsiSocket::doHandshake() { - ASSERT(!handshake_complete_); - ENVOY_CONN_LOG(debug, "TSI: doHandshake", callbacks_->connection()); - - if (!handshaker_next_calling_) { - doHandshakeNext(); - } - return Network::PostIoAction::KeepOpen; -} - -void TsiSocket::doHandshakeNext() { - ENVOY_CONN_LOG(debug, "TSI: doHandshake next: received: {}", - callbacks_->connection(), raw_read_buffer_.length()); - handshaker_next_calling_ = true; - Buffer::OwnedImpl handshaker_buffer; - handshaker_buffer.move(raw_read_buffer_); - handshaker_->next(handshaker_buffer); -} - -Network::PostIoAction TsiSocket::doHandshakeNextDone( - NextResultPtr &&next_result) { - ASSERT(next_result); - - ENVOY_CONN_LOG(debug, "TSI: doHandshake next done: status: {} to_send: {}", - callbacks_->connection(), next_result->status_, - next_result->to_send_->length()); - - tsi_result status = next_result->status_; - tsi_handshaker_result *handshaker_result = next_result->result_.get(); - - if (status != TSI_INCOMPLETE_DATA && status != TSI_OK) { - ENVOY_CONN_LOG(debug, "TSI: Handshake failed: status: {}", - callbacks_->connection(), status); - return Network::PostIoAction::Close; - } - - if (next_result->to_send_->length() > 0) { - raw_write_buffer_.move(*next_result->to_send_); - } - - if (status == TSI_OK && handshaker_result != nullptr) { - tsi_peer peer; - tsi_handshaker_result_extract_peer(handshaker_result, &peer); - ENVOY_CONN_LOG(debug, "TSI: Handshake successful: peer properties: {}", - callbacks_->connection(), peer.property_count); - for (size_t i = 0; i < peer.property_count; ++i) { - ENVOY_CONN_LOG(debug, " {}: {}", callbacks_->connection(), - peer.properties[i].name, - std::string(peer.properties[i].value.data, - peer.properties[i].value.length)); - } - if (handshake_validator_) { - std::string err; - bool peer_validated = handshake_validator_(peer, err); - if (peer_validated) { - ENVOY_CONN_LOG(info, "TSI: Handshake validation succeeded.", - callbacks_->connection()); - } else { - ENVOY_CONN_LOG(warn, "TSI: Handshake validation failed: {}", - callbacks_->connection(), err); - tsi_peer_destruct(&peer); - return Network::PostIoAction::Close; - } - } else { - ENVOY_CONN_LOG(info, "TSI: Handshake validation skipped.", - callbacks_->connection()); - } - tsi_peer_destruct(&peer); - - const unsigned char *unused_bytes; - size_t unused_byte_size; - - status = tsi_handshaker_result_get_unused_bytes( - handshaker_result, &unused_bytes, &unused_byte_size); - ASSERT(status == TSI_OK); - if (unused_byte_size > 0) { - raw_read_buffer_.add(unused_bytes, unused_byte_size); - } - ENVOY_CONN_LOG(debug, "TSI: Handshake successful: unused_bytes: {}", - callbacks_->connection(), unused_byte_size); - - tsi_frame_protector *frame_protector; - status = tsi_handshaker_result_create_frame_protector( - handshaker_result, NULL, &frame_protector); - ASSERT(status == TSI_OK); - frame_protector_ = std::make_unique(frame_protector); - - handshake_complete_ = true; - callbacks_->raiseEvent(Network::ConnectionEvent::Connected); - } - - if (raw_read_buffer_.length() > 0) { - callbacks_->setReadBufferReady(); - } - return Network::PostIoAction::KeepOpen; -} - -Network::IoResult TsiSocket::doRead(Buffer::Instance &buffer) { - Network::IoResult result = raw_buffer_socket_.doRead(raw_read_buffer_); - ENVOY_CONN_LOG(debug, "TSI: raw read result action {} bytes {} end_stream {}", - callbacks_->connection(), enumToInt(result.action_), - result.bytes_processed_, result.end_stream_read_); - if (result.action_ == Network::PostIoAction::Close && - result.bytes_processed_ == 0) { - return result; - } - - if (!handshake_complete_) { - Network::PostIoAction action = doHandshake(); - if (action == Network::PostIoAction::Close || !handshake_complete_) { - return {action, 0, false}; - } - } - - if (handshake_complete_) { - ASSERT(frame_protector_); - - uint64_t read_size = raw_read_buffer_.length(); - ENVOY_CONN_LOG(debug, "TSI: unprotecting buffer size: {}", - callbacks_->connection(), raw_read_buffer_.length()); - tsi_result status = frame_protector_->unprotect(raw_read_buffer_, buffer); - ENVOY_CONN_LOG(debug, "TSI: unprotected buffer left: {} result: {}", - callbacks_->connection(), raw_read_buffer_.length(), - tsi_result_to_string(status)); - result.bytes_processed_ = read_size - raw_read_buffer_.length(); - } - - ENVOY_CONN_LOG(debug, "TSI: do read result action {} bytes {} end_stream {}", - callbacks_->connection(), enumToInt(result.action_), - result.bytes_processed_, result.end_stream_read_); - return result; -} - -Network::IoResult TsiSocket::doWrite(Buffer::Instance &buffer, - bool end_stream) { - if (!handshake_complete_) { - Network::PostIoAction action = doHandshake(); - if (action == Network::PostIoAction::Close) { - return {action, 0, false}; - } - } - - if (handshake_complete_) { - ASSERT(frame_protector_); - ENVOY_CONN_LOG(debug, "TSI: protecting buffer size: {}", - callbacks_->connection(), buffer.length()); - tsi_result status = frame_protector_->protect(buffer, raw_write_buffer_); - ENVOY_CONN_LOG(debug, "TSI: protected buffer left: {} result: {}", - callbacks_->connection(), buffer.length(), - tsi_result_to_string(status)); - } - - ENVOY_CONN_LOG(debug, "TSI: raw_write length {} end_stream {}", - callbacks_->connection(), raw_write_buffer_.length(), - end_stream); - return raw_buffer_socket_.doWrite(raw_write_buffer_, - end_stream && (buffer.length() == 0)); -} - -void TsiSocket::closeSocket(Network::ConnectionEvent) { - handshaker_.release()->deferredDelete(); -} - -void TsiSocket::onConnected() { ASSERT(!handshake_complete_); } - -void TsiSocket::onNextDone(NextResultPtr &&result) { - handshaker_next_calling_ = false; - - Network::PostIoAction action = doHandshakeNextDone(std::move(result)); - if (action == Network::PostIoAction::Close) { - callbacks_->connection().close(Network::ConnectionCloseType::NoFlush); - } -} - -TsiSocketFactory::TsiSocketFactory(HandshakerFactory handshaker_factory, - HandshakeValidator handshake_validator) - : handshaker_factory_(std::move(handshaker_factory)), - handshake_validator_(std::move(handshake_validator)) {} - -bool TsiSocketFactory::implementsSecureTransport() const { return true; } - -Network::TransportSocketPtr TsiSocketFactory::createTransportSocket() const { - return std::make_unique(handshaker_factory_, handshake_validator_); -} -} // namespace Security -} // namespace Envoy diff --git a/src/envoy/alts/tsi_transport_socket.h b/src/envoy/alts/tsi_transport_socket.h deleted file mode 100644 index 629cb6f9e5b..00000000000 --- a/src/envoy/alts/tsi_transport_socket.h +++ /dev/null @@ -1,127 +0,0 @@ -/* Copyright 2018 Istio Authors. All Rights Reserved. - * - * 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. - */ -#pragma once - -#include "common/buffer/buffer_impl.h" -#include "common/network/raw_buffer_socket.h" -#include "envoy/network/transport_socket.h" -#include "src/envoy/alts/tsi_frame_protector.h" -#include "src/envoy/alts/tsi_handshaker.h" - -namespace Envoy { -namespace Security { - -typedef std::function HandshakerFactory; - -/** - * A function to validate the peer of the connection. - * @param peer the detail peer information of the connection. - * @param err an error message to indicate why the peer is invalid. This is an - * output param that should be populated by the function implementation. - * @return true if the peer is valid or false if the peer is invalid. - */ -typedef std::function - HandshakeValidator; - -/** - * A implementation of Network::TransportSocket based on gRPC TSI - */ -class TsiSocket : public Network::TransportSocket, - public TsiHandshakerCallbacks, - public Logger::Loggable { - public: - /** - * @param handshaker_factory a function to initiate a TsiHandshaker - * @param handshake_validator a function to validate the peer. Called right - * after the handshake completed with peer data to do the peer validation. - * The connection will be closed immediately if it returns false. - */ - TsiSocket(HandshakerFactory handshaker_factory, - HandshakeValidator handshake_validator); - virtual ~TsiSocket(); - - // Network::TransportSocket - void setTransportSocketCallbacks( - Envoy::Network::TransportSocketCallbacks& callbacks) override; - std::string protocol() const override; - bool canFlushClose() override { return handshake_complete_; } - const Envoy::Ssl::Connection* ssl() const override { return nullptr; } - Network::IoResult doWrite(Buffer::Instance& buffer, bool end_stream) override; - void closeSocket(Network::ConnectionEvent event) override; - Network::IoResult doRead(Buffer::Instance& buffer) override; - void onConnected() override; - - // TsiHandshakerCallbacks - void onNextDone(NextResultPtr&& result) override; - - private: - /** - * Callbacks for underlying RawBufferSocket, it proxies fd() and connection() - * but not raising event or flow control since they have to be handled in - * TsiSocket. - */ - class RawBufferCallbacks : public Network::TransportSocketCallbacks { - public: - explicit RawBufferCallbacks(TsiSocket& parent) : parent_(parent) {} - - int fd() const override { return parent_.callbacks_->fd(); } - Network::Connection& connection() override { - return parent_.callbacks_->connection(); - } - bool shouldDrainReadBuffer() override { return false; } - void setReadBufferReady() override {} - void raiseEvent(Network::ConnectionEvent) override {} - - private: - TsiSocket& parent_; - }; - - Network::PostIoAction doHandshake(); - void doHandshakeNext(); - Network::PostIoAction doHandshakeNextDone(NextResultPtr&& next_result); - - HandshakerFactory handshaker_factory_; - HandshakeValidator handshake_validator_; - TsiHandshakerPtr handshaker_{}; - bool handshaker_next_calling_{}; - // TODO(lizan): wrap frame protector in a C++ class - TsiFrameProtectorPtr frame_protector_; - - Envoy::Network::TransportSocketCallbacks* callbacks_{}; - RawBufferCallbacks raw_buffer_callbacks_; - Network::RawBufferSocket raw_buffer_socket_; - - Envoy::Buffer::OwnedImpl raw_read_buffer_; - Envoy::Buffer::OwnedImpl raw_write_buffer_; - bool handshake_complete_{}; -}; - -/** - * An implementation of Network::TransportSocketFactory for TsiSocket - */ -class TsiSocketFactory : public Network::TransportSocketFactory { - public: - TsiSocketFactory(HandshakerFactory handshaker_factory, - HandshakeValidator handshake_validator); - - bool implementsSecureTransport() const override; - Network::TransportSocketPtr createTransportSocket() const override; - - private: - HandshakerFactory handshaker_factory_; - HandshakeValidator handshake_validator_; -}; -} // namespace Security -} // namespace Envoy diff --git a/src/istio/mixerclient/BUILD b/src/istio/mixerclient/BUILD index eb589cf22d5..6d5d8010b38 100644 --- a/src/istio/mixerclient/BUILD +++ b/src/istio/mixerclient/BUILD @@ -58,7 +58,6 @@ cc_library( "//include/istio/quota_config:requirement_header", "//include/istio/utils:simple_lru_cache", "//src/istio/prefetch:quota_prefetch_lib", - "//src/istio/utils:md5_lib", "//src/istio/utils:utils_lib", ], ) diff --git a/src/istio/mixerclient/check_cache.cc b/src/istio/mixerclient/check_cache.cc index 0e3407fc58e..2f10557ce2a 100644 --- a/src/istio/mixerclient/check_cache.cc +++ b/src/istio/mixerclient/check_cache.cc @@ -106,7 +106,7 @@ Status CheckCache::Check(const Attributes &attributes, Tick time_now, std::lock_guard lock(cache_mutex_); for (const auto &it : referenced_map_) { const Referenced &reference = it.second; - std::string signature; + utils::HashType signature; if (!reference.Signature(attributes, "", &signature)) { continue; } @@ -145,7 +145,7 @@ Status CheckCache::CacheResponse(const Attributes &attributes, // Failed to decode referenced_attributes, not to cache this result. return ConvertRpcStatus(response.precondition().status()); } - std::string signature; + utils::HashType signature; if (!referenced.Signature(attributes, "", &signature)) { GOOGLE_LOG(ERROR) << "Response referenced mismatchs with request"; GOOGLE_LOG(ERROR) << "Request attributes: " << attributes.DebugString(); @@ -154,7 +154,7 @@ Status CheckCache::CacheResponse(const Attributes &attributes, } std::lock_guard lock(cache_mutex_); - std::string hash = referenced.Hash(); + utils::HashType hash = referenced.Hash(); if (referenced_map_.find(hash) == referenced_map_.end()) { referenced_map_[hash] = referenced; GOOGLE_LOG(INFO) << "Add a new Referenced for check cache: " diff --git a/src/istio/mixerclient/check_cache.h b/src/istio/mixerclient/check_cache.h index 36e9080f5cd..e5aa7ea934d 100644 --- a/src/istio/mixerclient/check_cache.h +++ b/src/istio/mixerclient/check_cache.h @@ -155,13 +155,13 @@ class CheckCache { // Key is the signature of the Attributes. Value is the CacheElem. // It is a LRU cache with maximum size. // When the maximum size is reached, oldest idle items will be removed. - using CheckLRUCache = utils::SimpleLRUCache; + using CheckLRUCache = utils::SimpleLRUCache; // The check options. CheckOptions options_; // Referenced map keyed with their hashes - std::unordered_map referenced_map_; + std::unordered_map referenced_map_; // Mutex guarding the access of cache_; std::mutex cache_mutex_; diff --git a/src/istio/mixerclient/quota_cache.cc b/src/istio/mixerclient/quota_cache.cc index cfd97385d6c..4d77a038fff 100644 --- a/src/istio/mixerclient/quota_cache.cc +++ b/src/istio/mixerclient/quota_cache.cc @@ -174,7 +174,7 @@ void QuotaCache::CheckCache(const Attributes& request, bool check_use_cache, PerQuotaReferenced& quota_ref = quota_referenced_map_[quota->name]; for (const auto& it : quota_ref.referenced_map) { const Referenced& referenced = it.second; - std::string signature; + utils::HashType signature; if (!referenced.Signature(request, quota->name, &signature)) { continue; } @@ -216,7 +216,7 @@ void QuotaCache::SetResponse(const Attributes& attributes, return; } - std::string signature; + utils::HashType signature; if (!referenced.Signature(attributes, quota_name, &signature)) { GOOGLE_LOG(ERROR) << "Quota response referenced mismatchs with request"; GOOGLE_LOG(ERROR) << "Request attributes: " << attributes.DebugString(); @@ -232,7 +232,7 @@ void QuotaCache::SetResponse(const Attributes& attributes, } PerQuotaReferenced& quota_ref = quota_referenced_map_[quota_name]; - std::string hash = referenced.Hash(); + utils::HashType hash = referenced.Hash(); if (quota_ref.referenced_map.find(hash) == quota_ref.referenced_map.end()) { quota_ref.referenced_map[hash] = referenced; GOOGLE_LOG(INFO) << "Add a new Referenced for quota cache: " << quota_name diff --git a/src/istio/mixerclient/quota_cache.h b/src/istio/mixerclient/quota_cache.h index ce7d1025f9e..231e4324795 100644 --- a/src/istio/mixerclient/quota_cache.h +++ b/src/istio/mixerclient/quota_cache.h @@ -140,7 +140,7 @@ class QuotaCache { std::unique_ptr pending_item; // Referenced map keyed with their hashes - std::unordered_map referenced_map; + std::unordered_map referenced_map; }; // Set a quota response. @@ -154,7 +154,7 @@ class QuotaCache { // Key is the signature of the Attributes. Value is the CacheElem. // It is a LRU cache with MaxIdelTime as response_expiration_time. - using QuotaLRUCache = utils::SimpleLRUCache; + using QuotaLRUCache = utils::SimpleLRUCache; // The quota options. QuotaOptions options_; diff --git a/src/istio/mixerclient/referenced.cc b/src/istio/mixerclient/referenced.cc index afc51f72527..464e44a8611 100644 --- a/src/istio/mixerclient/referenced.cc +++ b/src/istio/mixerclient/referenced.cc @@ -31,6 +31,7 @@ namespace mixerclient { namespace { const char kDelimiter[] = "\0"; const int kDelimiterLength = 1; +const size_t kMaxConcatHashSize = 4096; const std::string kWordDelimiter = ":"; // Decode dereferences index into str using global and local word lists. @@ -63,7 +64,7 @@ bool Decode(int idx, const std::vector &global_words, // Updates hasher with keys void Referenced::UpdateHash(const std::vector &keys, - utils::MD5 *hasher) { + utils::ConcatHash *hasher) { // keys are already sorted during Fill for (const AttributeRef &key : keys) { hasher->Update(key.name); @@ -116,7 +117,7 @@ bool Referenced::Fill(const Attributes &attributes, bool Referenced::Signature(const Attributes &attributes, const std::string &extra_key, - std::string *signature) const { + utils::HashType *signature) const { if (!CheckAbsentKeys(attributes) || !CheckExactKeys(attributes)) { return false; } @@ -200,10 +201,10 @@ bool Referenced::CheckExactKeys(const Attributes &attributes) const { void Referenced::CalculateSignature(const Attributes &attributes, const std::string &extra_key, - std::string *signature) const { + utils::HashType *signature) const { const auto &attributes_map = attributes.attributes(); - utils::MD5 hasher; + utils::ConcatHash hasher(kMaxConcatHashSize); for (std::size_t i = 0; i < exact_keys_.size(); ++i) { const auto &key = exact_keys_[i]; const auto it = attributes_map.find(key.name); @@ -274,18 +275,18 @@ void Referenced::CalculateSignature(const Attributes &attributes, } hasher.Update(extra_key); - *signature = hasher.Digest(); + *signature = hasher.getHash(); } -std::string Referenced::Hash() const { - utils::MD5 hasher; +utils::HashType Referenced::Hash() const { + utils::ConcatHash hasher(kMaxConcatHashSize); // keys are sorted during Fill UpdateHash(absence_keys_, &hasher); hasher.Update(kWordDelimiter); UpdateHash(exact_keys_, &hasher); - return hasher.Digest(); + return hasher.getHash(); } std::string Referenced::DebugString() const { diff --git a/src/istio/mixerclient/referenced.h b/src/istio/mixerclient/referenced.h index ec95680dd7b..698c5bcbf32 100644 --- a/src/istio/mixerclient/referenced.h +++ b/src/istio/mixerclient/referenced.h @@ -18,7 +18,7 @@ #include -#include "include/istio/utils/md5.h" +#include "include/istio/utils/concat_hash.h" #include "mixer/v1/check.pb.h" namespace istio { @@ -37,13 +37,13 @@ class Referenced { // Calculate a cache signature for the attributes. // Return false if attributes are mismatched, such as "absence" attributes - // present - // or "exact" match attributes don't present. + // present or "exact" match attributes don't present. bool Signature(const ::istio::mixer::v1::Attributes &attributes, - const std::string &extra_key, std::string *signature) const; + const std::string &extra_key, + utils::HashType *signature) const; // A hash value to identify an instance. - std::string Hash() const; + utils::HashType Hash() const; // For debug logging only. std::string DebugString() const; @@ -58,7 +58,7 @@ class Referenced { // Do the actual signature calculation. void CalculateSignature(const ::istio::mixer::v1::Attributes &attributes, const std::string &extra_key, - std::string *signature) const; + utils::HashType *signature) const; // Holds reference to an attribute and potentially a map key struct AttributeRef { @@ -86,7 +86,7 @@ class Referenced { // Updates hasher with keys static void UpdateHash(const std::vector &keys, - utils::MD5 *hasher); + utils::ConcatHash *hasher); }; } // namespace mixerclient diff --git a/src/istio/mixerclient/referenced_test.cc b/src/istio/mixerclient/referenced_test.cc index 3eb934468a5..0ab99179c59 100644 --- a/src/istio/mixerclient/referenced_test.cc +++ b/src/istio/mixerclient/referenced_test.cc @@ -16,7 +16,7 @@ #include "src/istio/mixerclient/referenced.h" #include "include/istio/utils/attributes_builder.h" -#include "include/istio/utils/md5.h" +#include "include/istio/utils/concat_hash.h" #include "google/protobuf/text_format.h" #include "gtest/gtest.h" @@ -177,8 +177,7 @@ TEST(ReferencedTest, FillSuccessTest) { "duration-key, int-key, string-key, string-map-key[If-Match], " "time-key, "); - EXPECT_EQ(utils::MD5::DebugString(referenced.Hash()), - "602d5bbd45b623c3560d2bdb6104f3ab"); + EXPECT_EQ(referenced.Hash(), 15726019709841724427U); } TEST(ReferencedTest, FillFail1Test) { @@ -207,7 +206,7 @@ TEST(ReferencedTest, NegativeSignature1Test) { Referenced referenced; EXPECT_TRUE(referenced.Fill(attrs, pb)); - std::string signature; + utils::HashType signature; Attributes attributes1; // "target.service" should be absence. @@ -246,11 +245,10 @@ TEST(ReferencedTest, OKSignature1Test) { Referenced referenced; EXPECT_TRUE(referenced.Fill(attributes, pb)); - std::string signature; + utils::HashType signature; EXPECT_TRUE(referenced.Signature(attributes, "extra", &signature)); - EXPECT_EQ(utils::MD5::DebugString(signature), - "751b028b2e2c230ef9c4e59ac556ca04"); + EXPECT_EQ(signature, 7485122822970549717U); } TEST(ReferencedTest, StringMapReferencedTest) { @@ -269,10 +267,9 @@ TEST(ReferencedTest, StringMapReferencedTest) { Referenced referenced; EXPECT_TRUE(referenced.Fill(attrs, pb)); - std::string signature; + utils::HashType signature; EXPECT_TRUE(referenced.Signature(attrs, "extra", &signature)); - EXPECT_EQ(utils::MD5::DebugString(signature), - "bc055468af1a0d4d03ec7f6fa2265b9b"); + EXPECT_EQ(signature, 5578853713114714386U); // negative test: map-key3 must absence ::istio::mixer::v1::Attributes attr1(attrs); diff --git a/src/istio/utils/BUILD b/src/istio/utils/BUILD index 0c815b43d6e..4cc7ff72413 100644 --- a/src/istio/utils/BUILD +++ b/src/istio/utils/BUILD @@ -45,16 +45,6 @@ cc_test( ], ) -cc_library( - name = "md5_lib", - srcs = ["md5.cc"], - visibility = ["//visibility:public"], - deps = [ - "//external:boringssl_crypto", - "//include/istio/utils:headers_lib", - ], -) - cc_test( name = "simple_lru_cache_test", size = "small", @@ -70,21 +60,6 @@ cc_test( ], ) -cc_test( - name = "md5_test", - size = "small", - srcs = ["md5_test.cc"], - linkopts = [ - "-lm", - "-lpthread", - ], - linkstatic = 1, - deps = [ - ":md5_lib", - "//external:googletest_main", - ], -) - cc_library( name = "attribute_names_lib", srcs = [ diff --git a/src/istio/utils/md5.cc b/src/istio/utils/md5.cc deleted file mode 100644 index e1c3b89d341..00000000000 --- a/src/istio/utils/md5.cc +++ /dev/null @@ -1,55 +0,0 @@ -/* Copyright 2017 Istio Authors. All Rights Reserved. - * - * 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 "include/istio/utils/md5.h" -#include - -namespace istio { -namespace utils { - -MD5::MD5() : finalized_(false) { MD5_Init(&ctx_); } - -MD5& MD5::Update(const void* data, size_t size) { - // Not update after finalized. - assert(!finalized_); - MD5_Update(&ctx_, data, size); - return *this; -} - -std::string MD5::Digest() { - if (!finalized_) { - MD5_Final(digest_, &ctx_); - finalized_ = true; - } - return std::string(reinterpret_cast(digest_), kDigestLength); -} - -std::string MD5::DebugString(const std::string& digest) { - assert(digest.size() == kDigestLength); - char buf[kDigestLength * 2 + 1]; - char* p = buf; - for (int i = 0; i < kDigestLength; i++, p += 2) { - sprintf(p, "%02x", (unsigned char)digest[i]); - } - *p = 0; - return std::string(buf, kDigestLength * 2); -} - -std::string MD5::operator()(const void* data, size_t size) { - return Update(data, size).Digest(); -} - -} // namespace utils -} // namespace istio diff --git a/src/istio/utils/md5_test.cc b/src/istio/utils/md5_test.cc deleted file mode 100644 index b8279217167..00000000000 --- a/src/istio/utils/md5_test.cc +++ /dev/null @@ -1,41 +0,0 @@ -/* Copyright 2017 Istio Authors. All Rights Reserved. - * - * 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 "include/istio/utils/md5.h" -#include "gtest/gtest.h" - -namespace istio { -namespace utils { -namespace { - -TEST(MD5Test, TestPriableGigest) { - static const char data[] = "Test Data"; - ASSERT_EQ("0a22b2ac9d829ff3605d81d5ae5e9d16", - MD5::DebugString(MD5()(data, sizeof(data)))); -} - -TEST(MD5Test, TestGigestEqual) { - static const char data1[] = "Test Data1"; - static const char data2[] = "Test Data2"; - auto d1 = MD5()(data1, sizeof(data1)); - auto d11 = MD5()(data1, sizeof(data1)); - auto d2 = MD5()(data2, sizeof(data2)); - ASSERT_EQ(d11, d1); - ASSERT_NE(d1, d2); -} - -} // namespace -} // namespace utils -} // namespace istio