Merge branch 'master' of https://github.com/grpc/grpc into channel-tracing

reviewable/pr13883/r14
ncteisen 7 years ago
commit 0c6024b94d
  1. 112
      BUILD
  2. 1081
      CMakeLists.txt
  3. 1329
      Makefile
  4. 19
      bazel/grpc_build_system.bzl
  5. 247
      build.yaml
  6. 62
      config.m4
  7. 63
      config.w32
  8. 41
      gRPC-C++.podspec
  9. 144
      gRPC-Core.podspec
  10. 106
      grpc.gemspec
  11. 74
      grpc.gyp
  12. 106
      package.xml
  13. 3
      setup.py
  14. 27
      src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc
  15. 4
      src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc
  16. 4
      src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc
  17. 2
      src/core/lib/gprpp/manual_constructor.h
  18. 6
      src/core/lib/iomgr/udp_server.cc
  19. 119
      src/core/lib/security/credentials/alts/alts_credentials.cc
  20. 102
      src/core/lib/security/credentials/alts/alts_credentials.h
  21. 72
      src/core/lib/security/credentials/alts/check_gcp_environment.cc
  22. 57
      src/core/lib/security/credentials/alts/check_gcp_environment.h
  23. 67
      src/core/lib/security/credentials/alts/check_gcp_environment_linux.cc
  24. 33
      src/core/lib/security/credentials/alts/check_gcp_environment_no_op.cc
  25. 114
      src/core/lib/security/credentials/alts/check_gcp_environment_windows.cc
  26. 126
      src/core/lib/security/credentials/alts/grpc_alts_credentials_client_options.cc
  27. 46
      src/core/lib/security/credentials/alts/grpc_alts_credentials_options.cc
  28. 112
      src/core/lib/security/credentials/alts/grpc_alts_credentials_options.h
  29. 58
      src/core/lib/security/credentials/alts/grpc_alts_credentials_server_options.cc
  30. 287
      src/core/lib/security/security_connector/alts_security_connector.cc
  31. 69
      src/core/lib/security/security_connector/alts_security_connector.h
  32. 10
      src/core/lib/surface/lame_client.cc
  33. 8
      src/core/plugin_registry/grpc_plugin_registry.cc
  34. 687
      src/core/tsi/alts/crypt/aes_gcm.cc
  35. 189
      src/core/tsi/alts/crypt/gsec.cc
  36. 454
      src/core/tsi/alts/crypt/gsec.h
  37. 118
      src/core/tsi/alts/frame_protector/alts_counter.cc
  38. 98
      src/core/tsi/alts/frame_protector/alts_counter.h
  39. 66
      src/core/tsi/alts/frame_protector/alts_crypter.cc
  40. 255
      src/core/tsi/alts/frame_protector/alts_crypter.h
  41. 407
      src/core/tsi/alts/frame_protector/alts_frame_protector.cc
  42. 55
      src/core/tsi/alts/frame_protector/alts_frame_protector.h
  43. 114
      src/core/tsi/alts/frame_protector/alts_record_protocol_crypter_common.cc
  44. 114
      src/core/tsi/alts/frame_protector/alts_record_protocol_crypter_common.h
  45. 105
      src/core/tsi/alts/frame_protector/alts_seal_privacy_integrity_crypter.cc
  46. 103
      src/core/tsi/alts/frame_protector/alts_unseal_privacy_integrity_crypter.cc
  47. 218
      src/core/tsi/alts/frame_protector/frame_handler.cc
  48. 236
      src/core/tsi/alts/frame_protector/frame_handler.h
  49. 316
      src/core/tsi/alts/handshaker/alts_handshaker_client.cc
  50. 137
      src/core/tsi/alts/handshaker/alts_handshaker_client.h
  51. 520
      src/core/tsi/alts/handshaker/alts_handshaker_service_api.cc
  52. 323
      src/core/tsi/alts/handshaker/alts_handshaker_service_api.h
  53. 143
      src/core/tsi/alts/handshaker/alts_handshaker_service_api_util.cc
  54. 149
      src/core/tsi/alts/handshaker/alts_handshaker_service_api_util.h
  55. 73
      src/core/tsi/alts/handshaker/alts_tsi_event.cc
  56. 93
      src/core/tsi/alts/handshaker/alts_tsi_event.h
  57. 483
      src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc
  58. 83
      src/core/tsi/alts/handshaker/alts_tsi_handshaker.h
  59. 52
      src/core/tsi/alts/handshaker/alts_tsi_handshaker_private.h
  60. 58
      src/core/tsi/alts/handshaker/alts_tsi_utils.cc
  61. 52
      src/core/tsi/alts/handshaker/alts_tsi_utils.h
  62. 48
      src/core/tsi/alts/handshaker/altscontext.pb.c
  63. 64
      src/core/tsi/alts/handshaker/altscontext.pb.h
  64. 123
      src/core/tsi/alts/handshaker/handshaker.pb.c
  65. 255
      src/core/tsi/alts/handshaker/handshaker.pb.h
  66. 41
      src/core/tsi/alts/handshaker/proto/altscontext.proto
  67. 2
      src/core/tsi/alts/handshaker/proto/handshaker.options
  68. 220
      src/core/tsi/alts/handshaker/proto/handshaker.proto
  69. 40
      src/core/tsi/alts/handshaker/proto/transport_security_common.proto
  70. 50
      src/core/tsi/alts/handshaker/transport_security_common.pb.c
  71. 78
      src/core/tsi/alts/handshaker/transport_security_common.pb.h
  72. 196
      src/core/tsi/alts/handshaker/transport_security_common_api.cc
  73. 163
      src/core/tsi/alts/handshaker/transport_security_common_api.h
  74. 180
      src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.cc
  75. 52
      src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.h
  76. 144
      src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.cc
  77. 49
      src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.h
  78. 91
      src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol.h
  79. 173
      src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_common.cc
  80. 100
      src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_common.h
  81. 476
      src/core/tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol.cc
  82. 199
      src/core/tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol.h
  83. 295
      src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc
  84. 52
      src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.h
  85. 4
      src/cpp/client/secure_credentials.cc
  86. 12
      src/cpp/common/channel_filter.h
  87. 5
      src/cpp/server/dynamic_thread_pool.cc
  88. 4
      src/cpp/server/secure_server_credentials.cc
  89. 6
      src/cpp/thread_manager/thread_manager.cc
  90. 8
      src/cpp/util/slice_cc.cc
  91. 0
      src/php/ext/grpc/call_credentials.h
  92. 0
      src/php/ext/grpc/channel.h
  93. 0
      src/php/ext/grpc/channel_credentials.h
  94. 0
      src/php/ext/grpc/server.h
  95. 0
      src/php/ext/grpc/server_credentials.h
  96. 0
      src/php/ext/grpc/timeval.h
  97. 57
      src/python/grpcio/grpc_core_dependencies.py
  98. 2
      templates/CMakeLists.txt.template
  99. 2
      templates/Makefile.template
  100. 2
      templates/gRPC-Core.podspec.template
  101. Some files were not shown because too many files have changed in this diff Show More

112
BUILD

@ -1330,6 +1330,8 @@ grpc_cc_library(
"src/core/lib/security/credentials/oauth2/oauth2_credentials.cc",
"src/core/lib/security/credentials/plugin/plugin_credentials.cc",
"src/core/lib/security/credentials/ssl/ssl_credentials.cc",
"src/core/lib/security/credentials/alts/alts_credentials.cc",
"src/core/lib/security/security_connector/alts_security_connector.cc",
"src/core/lib/security/security_connector/security_connector.cc",
"src/core/lib/security/transport/client_auth_filter.cc",
"src/core/lib/security/transport/secure_endpoint.cc",
@ -1353,6 +1355,8 @@ grpc_cc_library(
"src/core/lib/security/credentials/oauth2/oauth2_credentials.h",
"src/core/lib/security/credentials/plugin/plugin_credentials.h",
"src/core/lib/security/credentials/ssl/ssl_credentials.h",
"src/core/lib/security/credentials/alts/alts_credentials.h",
"src/core/lib/security/security_connector/alts_security_connector.h",
"src/core/lib/security/security_connector/security_connector.h",
"src/core/lib/security/transport/auth_filters.h",
"src/core/lib/security/transport/secure_endpoint.h",
@ -1364,6 +1368,7 @@ grpc_cc_library(
language = "c++",
public_hdrs = GRPC_SECURE_PUBLIC_HDRS,
deps = [
"alts_util",
"grpc_base",
"grpc_transport_chttp2_alpn",
"tsi",
@ -1586,16 +1591,119 @@ grpc_cc_library(
],
)
grpc_cc_library(
name = "alts_frame_protector",
srcs = [
"src/core/tsi/alts/crypt/aes_gcm.cc",
"src/core/tsi/alts/crypt/gsec.cc",
"src/core/tsi/alts/frame_protector/alts_counter.cc",
"src/core/tsi/alts/frame_protector/alts_crypter.cc",
"src/core/tsi/alts/frame_protector/alts_frame_protector.cc",
"src/core/tsi/alts/frame_protector/alts_record_protocol_crypter_common.cc",
"src/core/tsi/alts/frame_protector/alts_seal_privacy_integrity_crypter.cc",
"src/core/tsi/alts/frame_protector/alts_unseal_privacy_integrity_crypter.cc",
"src/core/tsi/alts/frame_protector/frame_handler.cc",
"src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.cc",
"src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.cc",
"src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_common.cc",
"src/core/tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol.cc",
"src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc",
],
hdrs = [
"src/core/tsi/alts/crypt/gsec.h",
"src/core/tsi/alts/frame_protector/alts_counter.h",
"src/core/tsi/alts/frame_protector/alts_crypter.h",
"src/core/tsi/alts/frame_protector/alts_frame_protector.h",
"src/core/tsi/alts/frame_protector/alts_record_protocol_crypter_common.h",
"src/core/tsi/alts/frame_protector/frame_handler.h",
"src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.h",
"src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.h",
"src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_common.h",
"src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol.h",
"src/core/tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol.h",
"src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.h",
"src/core/tsi/transport_security_grpc.h",
],
external_deps = [
"libssl",
],
language = "c++",
deps = [
"gpr",
"grpc_base",
"tsi_interface",
],
)
grpc_cc_library(
name = "alts_proto",
srcs = [
"src/core/tsi/alts/handshaker/altscontext.pb.c",
"src/core/tsi/alts/handshaker/handshaker.pb.c",
"src/core/tsi/alts/handshaker/transport_security_common.pb.c",
],
hdrs = [
"src/core/tsi/alts/handshaker/altscontext.pb.h",
"src/core/tsi/alts/handshaker/handshaker.pb.h",
"src/core/tsi/alts/handshaker/transport_security_common.pb.h",
],
external_deps = [
"nanopb",
],
language = "c++",
)
grpc_cc_library(
name = "alts_util",
srcs = [
"src/core/lib/security/credentials/alts/check_gcp_environment.cc",
"src/core/lib/security/credentials/alts/check_gcp_environment_linux.cc",
"src/core/lib/security/credentials/alts/check_gcp_environment_no_op.cc",
"src/core/lib/security/credentials/alts/check_gcp_environment_windows.cc",
"src/core/lib/security/credentials/alts/grpc_alts_credentials_client_options.cc",
"src/core/lib/security/credentials/alts/grpc_alts_credentials_options.cc",
"src/core/lib/security/credentials/alts/grpc_alts_credentials_server_options.cc",
"src/core/tsi/alts/handshaker/alts_handshaker_service_api.cc",
"src/core/tsi/alts/handshaker/alts_handshaker_service_api_util.cc",
"src/core/tsi/alts/handshaker/transport_security_common_api.cc",
],
hdrs = [
"src/core/lib/security/credentials/alts/check_gcp_environment.h",
"src/core/lib/security/credentials/alts/grpc_alts_credentials_options.h",
"src/core/tsi/alts/handshaker/alts_handshaker_service_api.h",
"src/core/tsi/alts/handshaker/alts_handshaker_service_api_util.h",
"src/core/tsi/alts/handshaker/transport_security_common_api.h",
],
external_deps = [
"nanopb",
],
language = "c++",
deps = [
"alts_proto",
"gpr",
"grpc_base",
],
)
grpc_cc_library(
name = "tsi",
srcs = [
"src/core/tsi/alts_transport_security.cc",
"src/core/tsi/alts/handshaker/alts_handshaker_client.cc",
"src/core/tsi/alts/handshaker/alts_tsi_event.cc",
"src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc",
"src/core/tsi/alts/handshaker/alts_tsi_utils.cc",
"src/core/tsi/fake_transport_security.cc",
"src/core/tsi/ssl_transport_security.cc",
"src/core/tsi/transport_security_grpc.cc",
],
hdrs = [
"src/core/tsi/alts_transport_security.h",
"src/core/tsi/alts/handshaker/alts_handshaker_client.h",
"src/core/tsi/alts/handshaker/alts_tsi_event.h",
"src/core/tsi/alts/handshaker/alts_tsi_handshaker.h",
"src/core/tsi/alts/handshaker/alts_tsi_handshaker_private.h",
"src/core/tsi/alts/handshaker/alts_tsi_utils.h",
"src/core/tsi/fake_transport_security.h",
"src/core/tsi/ssl_transport_security.h",
"src/core/tsi/ssl_types.h",
@ -1606,7 +1714,11 @@ grpc_cc_library(
],
language = "c++",
deps = [
"alts_frame_protector",
"alts_util",
"gpr",
"grpc_base",
"grpc_transport_chttp2_client_insecure",
"tsi_interface",
],
)

File diff suppressed because it is too large Load Diff

1329
Makefile

File diff suppressed because it is too large Load Diff

@ -57,6 +57,12 @@ def _maybe_update_cc_library_hdrs(hdrs):
ret.append(h)
return ret
def _maybe_update_cc_library_defines(name):
ret = []
if name == "alts_proto":
ret += ["PB_FIELD_16BIT=1"]
return ret
def grpc_cc_library(name, srcs = [], public_hdrs = [], hdrs = [],
external_deps = [], deps = [], standalone = False,
language = "C++", testonly = False, visibility = None,
@ -64,10 +70,11 @@ def grpc_cc_library(name, srcs = [], public_hdrs = [], hdrs = [],
copts = []
if language.upper() == "C":
copts = if_not_windows(["-std=c99"])
defines = _maybe_update_cc_library_defines(name)
native.cc_library(
name = name,
srcs = srcs,
defines = select({"//:grpc_no_ares": ["GRPC_ARES=0"],
defines = defines + select({"//:grpc_no_ares": ["GRPC_ARES=0"],
"//conditions:default": [],}) +
select({"//:remote_execution": ["GRPC_PORT_ISOLATED_RUNTIME=1"],
"//conditions:default": [],}) +
@ -170,17 +177,13 @@ def grpc_sh_binary(name, srcs, data = []):
srcs = srcs,
data = data)
def grpc_py_binary(name, srcs, data = [], deps = []):
if name == "test_dns_server":
deps = _get_external_deps([
"twisted",
"yaml",
])
def grpc_py_binary(name, srcs, data = [], deps = [], external_deps = [], testonly = False):
native.py_binary(
name = name,
srcs = srcs,
data = data,
deps = deps)
deps = deps + _get_external_deps(external_deps)
)
def grpc_package(name, visibility = "private", features = []):
if visibility == "tests":

@ -16,6 +16,84 @@ settings:
g_stands_for: gorgeous
version: 1.11.0-dev
filegroups:
- name: alts_proto
headers:
- src/core/tsi/alts/handshaker/altscontext.pb.h
- src/core/tsi/alts/handshaker/handshaker.pb.h
- src/core/tsi/alts/handshaker/transport_security_common.pb.h
src:
- src/core/tsi/alts/handshaker/altscontext.pb.c
- src/core/tsi/alts/handshaker/handshaker.pb.c
- src/core/tsi/alts/handshaker/transport_security_common.pb.c
uses:
- nanopb
- name: alts_tsi
headers:
- src/core/tsi/alts/crypt/gsec.h
- src/core/tsi/alts/frame_protector/alts_counter.h
- src/core/tsi/alts/frame_protector/alts_crypter.h
- src/core/tsi/alts/frame_protector/alts_frame_protector.h
- src/core/tsi/alts/frame_protector/alts_record_protocol_crypter_common.h
- src/core/tsi/alts/frame_protector/frame_handler.h
- src/core/tsi/alts/handshaker/alts_handshaker_client.h
- src/core/tsi/alts/handshaker/alts_tsi_event.h
- src/core/tsi/alts/handshaker/alts_tsi_handshaker.h
- src/core/tsi/alts/handshaker/alts_tsi_handshaker_private.h
- src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.h
- src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.h
- src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol.h
- src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_common.h
- src/core/tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol.h
- src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.h
src:
- src/core/tsi/alts/crypt/aes_gcm.cc
- src/core/tsi/alts/crypt/gsec.cc
- src/core/tsi/alts/frame_protector/alts_counter.cc
- src/core/tsi/alts/frame_protector/alts_crypter.cc
- src/core/tsi/alts/frame_protector/alts_frame_protector.cc
- src/core/tsi/alts/frame_protector/alts_record_protocol_crypter_common.cc
- src/core/tsi/alts/frame_protector/alts_seal_privacy_integrity_crypter.cc
- src/core/tsi/alts/frame_protector/alts_unseal_privacy_integrity_crypter.cc
- src/core/tsi/alts/frame_protector/frame_handler.cc
- src/core/tsi/alts/handshaker/alts_handshaker_client.cc
- src/core/tsi/alts/handshaker/alts_tsi_event.cc
- src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc
- src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.cc
- src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.cc
- src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_common.cc
- src/core/tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol.cc
- src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc
uses:
- alts_util
- grpc_base
- grpc_transport_chttp2_client_insecure
- tsi_interface
- tsi
- name: alts_util
headers:
- src/core/lib/security/credentials/alts/check_gcp_environment.h
- src/core/lib/security/credentials/alts/grpc_alts_credentials_options.h
- src/core/tsi/alts/handshaker/alts_handshaker_service_api.h
- src/core/tsi/alts/handshaker/alts_handshaker_service_api_util.h
- src/core/tsi/alts/handshaker/alts_tsi_utils.h
- src/core/tsi/alts/handshaker/transport_security_common_api.h
src:
- src/core/lib/security/credentials/alts/check_gcp_environment.cc
- src/core/lib/security/credentials/alts/check_gcp_environment_linux.cc
- src/core/lib/security/credentials/alts/check_gcp_environment_no_op.cc
- src/core/lib/security/credentials/alts/check_gcp_environment_windows.cc
- src/core/lib/security/credentials/alts/grpc_alts_credentials_client_options.cc
- src/core/lib/security/credentials/alts/grpc_alts_credentials_options.cc
- src/core/lib/security/credentials/alts/grpc_alts_credentials_server_options.cc
- src/core/tsi/alts/handshaker/alts_handshaker_service_api.cc
- src/core/tsi/alts/handshaker/alts_handshaker_service_api_util.cc
- src/core/tsi/alts/handshaker/alts_tsi_utils.cc
- src/core/tsi/alts/handshaker/transport_security_common_api.cc
uses:
- alts_proto
- grpc_base
- tsi_interface
- nanopb
- name: census
public_headers:
- include/grpc/census.h
@ -646,6 +724,7 @@ filegroups:
- include/grpc/grpc_security.h
headers:
- src/core/lib/security/context/security_context.h
- src/core/lib/security/credentials/alts/alts_credentials.h
- src/core/lib/security/credentials/composite/composite_credentials.h
- src/core/lib/security/credentials/credentials.h
- src/core/lib/security/credentials/fake/fake_credentials.h
@ -657,6 +736,7 @@ filegroups:
- src/core/lib/security/credentials/oauth2/oauth2_credentials.h
- src/core/lib/security/credentials/plugin/plugin_credentials.h
- src/core/lib/security/credentials/ssl/ssl_credentials.h
- src/core/lib/security/security_connector/alts_security_connector.h
- src/core/lib/security/security_connector/security_connector.h
- src/core/lib/security/transport/auth_filters.h
- src/core/lib/security/transport/secure_endpoint.h
@ -667,6 +747,7 @@ filegroups:
src:
- src/core/lib/http/httpcli_security_connector.cc
- src/core/lib/security/context/security_context.cc
- src/core/lib/security/credentials/alts/alts_credentials.cc
- src/core/lib/security/credentials/composite/composite_credentials.cc
- src/core/lib/security/credentials/credentials.cc
- src/core/lib/security/credentials/credentials_metadata.cc
@ -680,6 +761,7 @@ filegroups:
- src/core/lib/security/credentials/oauth2/oauth2_credentials.cc
- src/core/lib/security/credentials/plugin/plugin_credentials.cc
- src/core/lib/security/credentials/ssl/ssl_credentials.cc
- src/core/lib/security/security_connector/alts_security_connector.cc
- src/core/lib/security/security_connector/security_connector.cc
- src/core/lib/security/transport/client_auth_filter.cc
- src/core/lib/security/transport/secure_endpoint.cc
@ -691,6 +773,7 @@ filegroups:
- src/core/lib/surface/init_secure.cc
secure: true
uses:
- alts_tsi
- grpc_base
- grpc_transport_chttp2_alpn
- tsi
@ -1219,6 +1302,18 @@ filegroups:
- grpc++
- grpc
libs:
- name: alts_test_util
build: private
language: c
headers:
- test/core/tsi/alts/crypt/gsec_test_util.h
- test/core/tsi/alts/handshaker/alts_handshaker_service_api_test_lib.h
src:
- test/core/tsi/alts/crypt/gsec_test_util.cc
- test/core/tsi/alts/handshaker/alts_handshaker_service_api_test_lib.cc
deps:
- grpc
secure: true
- name: gpr
build: all
language: c
@ -3507,6 +3602,125 @@ targets:
- grpc_unsecure
- gpr_test_util
- gpr
- name: alts_counter_test
build: test
language: c++
src:
- test/core/tsi/alts/frame_protector/alts_counter_test.cc
deps:
- alts_test_util
- gpr
- grpc
- name: alts_crypt_test
build: test
language: c++
src:
- test/core/tsi/alts/crypt/aes_gcm_test.cc
deps:
- alts_test_util
- gpr_test_util
- gpr
- grpc
- name: alts_crypter_test
build: test
language: c++
src:
- test/core/tsi/alts/frame_protector/alts_crypter_test.cc
deps:
- alts_test_util
- gpr
- grpc
- name: alts_frame_handler_test
build: test
language: c++
src:
- test/core/tsi/alts/frame_protector/frame_handler_test.cc
deps:
- alts_test_util
- gpr
- grpc
- name: alts_frame_protector_test
build: test
language: c++
src:
- test/core/tsi/alts/frame_protector/alts_frame_protector_test.cc
deps:
- alts_test_util
- gpr
- grpc
filegroups:
- transport_security_test_lib
- name: alts_grpc_record_protocol_test
build: test
language: c++
src:
- test/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_test.cc
deps:
- alts_test_util
- gpr
- grpc
- name: alts_handshaker_client_test
build: test
language: c++
src:
- test/core/tsi/alts/handshaker/alts_handshaker_client_test.cc
deps:
- alts_test_util
- gpr
- grpc
- name: alts_handshaker_service_api_test
build: test
language: c++
src:
- test/core/tsi/alts/handshaker/alts_handshaker_service_api_test.cc
deps:
- alts_test_util
- gpr
- grpc
- name: alts_iovec_record_protocol_test
build: test
language: c++
src:
- test/core/tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol_test.cc
deps:
- alts_test_util
- gpr
- grpc
- name: alts_security_connector_test
build: test
language: c++
src:
- test/core/security/alts_security_connector_test.cc
deps:
- gpr
- grpc
- name: alts_tsi_handshaker_test
build: test
language: c++
src:
- test/core/tsi/alts/handshaker/alts_tsi_handshaker_test.cc
deps:
- alts_test_util
- gpr
- grpc
- name: alts_tsi_utils_test
build: test
language: c++
src:
- test/core/tsi/alts/handshaker/alts_tsi_utils_test.cc
deps:
- alts_test_util
- gpr
- grpc
- name: alts_zero_copy_grpc_protector_test
build: test
language: c++
src:
- test/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector_test.cc
deps:
- alts_test_util
- gpr
- grpc
- name: async_end2end_test
gtest: true
build: test
@ -3908,6 +4122,22 @@ targets:
uses:
- grpc++_test
uses_polling: false
- name: check_gcp_environment_linux_test
build: test
language: c++
src:
- test/core/security/check_gcp_environment_linux_test.cc
deps:
- grpc
- gpr
- name: check_gcp_environment_windows_test
build: test
language: c++
src:
- test/core/security/check_gcp_environment_windows_test.cc
deps:
- grpc
- gpr
- name: chttp2_settings_timeout_test
gtest: true
build: test
@ -4166,6 +4396,14 @@ targets:
args:
- --generated_file_path=gens/src/proto/grpc/testing/
uses_polling: false
- name: grpc_alts_credentials_options_test
build: test
language: c++
src:
- test/core/security/grpc_alts_credentials_options_test.cc
deps:
- grpc
- gpr
- name: grpc_cli
build: test
run: false
@ -5001,6 +5239,15 @@ targets:
- grpc
- gpr_test_util
- gpr
- name: transport_security_common_api_test
build: test
language: c++
src:
- test/core/tsi/alts/handshaker/transport_security_common_api_test.cc
deps:
- alts_test_util
- gpr
- grpc
- name: writes_per_rpc_test
gtest: true
cpu_cost: 0.5

@ -247,6 +247,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/ext/filters/http/server/http_server_filter.cc \
src/core/lib/http/httpcli_security_connector.cc \
src/core/lib/security/context/security_context.cc \
src/core/lib/security/credentials/alts/alts_credentials.cc \
src/core/lib/security/credentials/composite/composite_credentials.cc \
src/core/lib/security/credentials/credentials.cc \
src/core/lib/security/credentials/credentials_metadata.cc \
@ -260,6 +261,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/security/credentials/oauth2/oauth2_credentials.cc \
src/core/lib/security/credentials/plugin/plugin_credentials.cc \
src/core/lib/security/credentials/ssl/ssl_credentials.cc \
src/core/lib/security/security_connector/alts_security_connector.cc \
src/core/lib/security/security_connector/security_connector.cc \
src/core/lib/security/transport/client_auth_filter.cc \
src/core/lib/security/transport/secure_endpoint.cc \
@ -269,14 +271,45 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/security/transport/tsi_error.cc \
src/core/lib/security/util/json_util.cc \
src/core/lib/surface/init_secure.cc \
src/core/tsi/alts_transport_security.cc \
src/core/tsi/fake_transport_security.cc \
src/core/tsi/ssl_transport_security.cc \
src/core/tsi/transport_security_grpc.cc \
src/core/tsi/alts/crypt/aes_gcm.cc \
src/core/tsi/alts/crypt/gsec.cc \
src/core/tsi/alts/frame_protector/alts_counter.cc \
src/core/tsi/alts/frame_protector/alts_crypter.cc \
src/core/tsi/alts/frame_protector/alts_frame_protector.cc \
src/core/tsi/alts/frame_protector/alts_record_protocol_crypter_common.cc \
src/core/tsi/alts/frame_protector/alts_seal_privacy_integrity_crypter.cc \
src/core/tsi/alts/frame_protector/alts_unseal_privacy_integrity_crypter.cc \
src/core/tsi/alts/frame_protector/frame_handler.cc \
src/core/tsi/alts/handshaker/alts_handshaker_client.cc \
src/core/tsi/alts/handshaker/alts_tsi_event.cc \
src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc \
src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.cc \
src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.cc \
src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_common.cc \
src/core/tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol.cc \
src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc \
src/core/lib/security/credentials/alts/check_gcp_environment.cc \
src/core/lib/security/credentials/alts/check_gcp_environment_linux.cc \
src/core/lib/security/credentials/alts/check_gcp_environment_no_op.cc \
src/core/lib/security/credentials/alts/check_gcp_environment_windows.cc \
src/core/lib/security/credentials/alts/grpc_alts_credentials_client_options.cc \
src/core/lib/security/credentials/alts/grpc_alts_credentials_options.cc \
src/core/lib/security/credentials/alts/grpc_alts_credentials_server_options.cc \
src/core/tsi/alts/handshaker/alts_handshaker_service_api.cc \
src/core/tsi/alts/handshaker/alts_handshaker_service_api_util.cc \
src/core/tsi/alts/handshaker/alts_tsi_utils.cc \
src/core/tsi/alts/handshaker/transport_security_common_api.cc \
src/core/tsi/alts/handshaker/altscontext.pb.c \
src/core/tsi/alts/handshaker/handshaker.pb.c \
src/core/tsi/alts/handshaker/transport_security_common.pb.c \
third_party/nanopb/pb_common.c \
third_party/nanopb/pb_decode.c \
third_party/nanopb/pb_encode.c \
src/core/tsi/transport_security.cc \
src/core/tsi/transport_security_adapter.cc \
src/core/ext/transport/chttp2/server/chttp2_server.cc \
src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc \
src/core/ext/transport/chttp2/client/insecure/channel_create.cc \
src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc \
src/core/ext/transport/chttp2/client/chttp2_connector.cc \
src/core/ext/filters/client_channel/backup_poller.cc \
src/core/ext/filters/client_channel/channel_connectivity.cc \
src/core/ext/filters/client_channel/client_channel.cc \
@ -299,11 +332,14 @@ if test "$PHP_GRPC" != "no"; then
src/core/ext/filters/client_channel/subchannel_index.cc \
src/core/ext/filters/client_channel/uri_parser.cc \
src/core/ext/filters/deadline/deadline_filter.cc \
src/core/ext/transport/chttp2/client/chttp2_connector.cc \
src/core/tsi/alts_transport_security.cc \
src/core/tsi/fake_transport_security.cc \
src/core/tsi/ssl_transport_security.cc \
src/core/tsi/transport_security_grpc.cc \
src/core/ext/transport/chttp2/server/chttp2_server.cc \
src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc \
src/core/ext/transport/chttp2/server/insecure/server_chttp2.cc \
src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc \
src/core/ext/transport/chttp2/client/insecure/channel_create.cc \
src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc \
src/core/ext/transport/inproc/inproc_plugin.cc \
src/core/ext/transport/inproc/inproc_transport.cc \
src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc \
@ -312,9 +348,6 @@ if test "$PHP_GRPC" != "no"; then
src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc \
src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc \
src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c \
third_party/nanopb/pb_common.c \
third_party/nanopb/pb_decode.c \
third_party/nanopb/pb_encode.c \
src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc \
src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc \
src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc \
@ -637,6 +670,7 @@ if test "$PHP_GRPC" != "no"; then
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/profiling)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/context)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/credentials)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/credentials/alts)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/credentials/composite)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/credentials/fake)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/credentials/google_default)
@ -653,6 +687,10 @@ if test "$PHP_GRPC" != "no"; then
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/transport)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/plugin_registry)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/tsi)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/tsi/alts/crypt)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/tsi/alts/frame_protector)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/tsi/alts/handshaker)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/tsi/alts/zero_copy_frame_protector)
PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto)
PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/asn1)
PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/base64)

@ -224,6 +224,7 @@ if (PHP_GRPC != "no") {
"src\\core\\ext\\filters\\http\\server\\http_server_filter.cc " +
"src\\core\\lib\\http\\httpcli_security_connector.cc " +
"src\\core\\lib\\security\\context\\security_context.cc " +
"src\\core\\lib\\security\\credentials\\alts\\alts_credentials.cc " +
"src\\core\\lib\\security\\credentials\\composite\\composite_credentials.cc " +
"src\\core\\lib\\security\\credentials\\credentials.cc " +
"src\\core\\lib\\security\\credentials\\credentials_metadata.cc " +
@ -237,6 +238,7 @@ if (PHP_GRPC != "no") {
"src\\core\\lib\\security\\credentials\\oauth2\\oauth2_credentials.cc " +
"src\\core\\lib\\security\\credentials\\plugin\\plugin_credentials.cc " +
"src\\core\\lib\\security\\credentials\\ssl\\ssl_credentials.cc " +
"src\\core\\lib\\security\\security_connector\\alts_security_connector.cc " +
"src\\core\\lib\\security\\security_connector\\security_connector.cc " +
"src\\core\\lib\\security\\transport\\client_auth_filter.cc " +
"src\\core\\lib\\security\\transport\\secure_endpoint.cc " +
@ -246,14 +248,45 @@ if (PHP_GRPC != "no") {
"src\\core\\lib\\security\\transport\\tsi_error.cc " +
"src\\core\\lib\\security\\util\\json_util.cc " +
"src\\core\\lib\\surface\\init_secure.cc " +
"src\\core\\tsi\\alts_transport_security.cc " +
"src\\core\\tsi\\fake_transport_security.cc " +
"src\\core\\tsi\\ssl_transport_security.cc " +
"src\\core\\tsi\\transport_security_grpc.cc " +
"src\\core\\tsi\\alts\\crypt\\aes_gcm.cc " +
"src\\core\\tsi\\alts\\crypt\\gsec.cc " +
"src\\core\\tsi\\alts\\frame_protector\\alts_counter.cc " +
"src\\core\\tsi\\alts\\frame_protector\\alts_crypter.cc " +
"src\\core\\tsi\\alts\\frame_protector\\alts_frame_protector.cc " +
"src\\core\\tsi\\alts\\frame_protector\\alts_record_protocol_crypter_common.cc " +
"src\\core\\tsi\\alts\\frame_protector\\alts_seal_privacy_integrity_crypter.cc " +
"src\\core\\tsi\\alts\\frame_protector\\alts_unseal_privacy_integrity_crypter.cc " +
"src\\core\\tsi\\alts\\frame_protector\\frame_handler.cc " +
"src\\core\\tsi\\alts\\handshaker\\alts_handshaker_client.cc " +
"src\\core\\tsi\\alts\\handshaker\\alts_tsi_event.cc " +
"src\\core\\tsi\\alts\\handshaker\\alts_tsi_handshaker.cc " +
"src\\core\\tsi\\alts\\zero_copy_frame_protector\\alts_grpc_integrity_only_record_protocol.cc " +
"src\\core\\tsi\\alts\\zero_copy_frame_protector\\alts_grpc_privacy_integrity_record_protocol.cc " +
"src\\core\\tsi\\alts\\zero_copy_frame_protector\\alts_grpc_record_protocol_common.cc " +
"src\\core\\tsi\\alts\\zero_copy_frame_protector\\alts_iovec_record_protocol.cc " +
"src\\core\\tsi\\alts\\zero_copy_frame_protector\\alts_zero_copy_grpc_protector.cc " +
"src\\core\\lib\\security\\credentials\\alts\\check_gcp_environment.cc " +
"src\\core\\lib\\security\\credentials\\alts\\check_gcp_environment_linux.cc " +
"src\\core\\lib\\security\\credentials\\alts\\check_gcp_environment_no_op.cc " +
"src\\core\\lib\\security\\credentials\\alts\\check_gcp_environment_windows.cc " +
"src\\core\\lib\\security\\credentials\\alts\\grpc_alts_credentials_client_options.cc " +
"src\\core\\lib\\security\\credentials\\alts\\grpc_alts_credentials_options.cc " +
"src\\core\\lib\\security\\credentials\\alts\\grpc_alts_credentials_server_options.cc " +
"src\\core\\tsi\\alts\\handshaker\\alts_handshaker_service_api.cc " +
"src\\core\\tsi\\alts\\handshaker\\alts_handshaker_service_api_util.cc " +
"src\\core\\tsi\\alts\\handshaker\\alts_tsi_utils.cc " +
"src\\core\\tsi\\alts\\handshaker\\transport_security_common_api.cc " +
"src\\core\\tsi\\alts\\handshaker\\altscontext.pb.c " +
"src\\core\\tsi\\alts\\handshaker\\handshaker.pb.c " +
"src\\core\\tsi\\alts\\handshaker\\transport_security_common.pb.c " +
"third_party\\nanopb\\pb_common.c " +
"third_party\\nanopb\\pb_decode.c " +
"third_party\\nanopb\\pb_encode.c " +
"src\\core\\tsi\\transport_security.cc " +
"src\\core\\tsi\\transport_security_adapter.cc " +
"src\\core\\ext\\transport\\chttp2\\server\\chttp2_server.cc " +
"src\\core\\ext\\transport\\chttp2\\client\\secure\\secure_channel_create.cc " +
"src\\core\\ext\\transport\\chttp2\\client\\insecure\\channel_create.cc " +
"src\\core\\ext\\transport\\chttp2\\client\\insecure\\channel_create_posix.cc " +
"src\\core\\ext\\transport\\chttp2\\client\\chttp2_connector.cc " +
"src\\core\\ext\\filters\\client_channel\\backup_poller.cc " +
"src\\core\\ext\\filters\\client_channel\\channel_connectivity.cc " +
"src\\core\\ext\\filters\\client_channel\\client_channel.cc " +
@ -276,11 +309,14 @@ if (PHP_GRPC != "no") {
"src\\core\\ext\\filters\\client_channel\\subchannel_index.cc " +
"src\\core\\ext\\filters\\client_channel\\uri_parser.cc " +
"src\\core\\ext\\filters\\deadline\\deadline_filter.cc " +
"src\\core\\ext\\transport\\chttp2\\client\\chttp2_connector.cc " +
"src\\core\\tsi\\alts_transport_security.cc " +
"src\\core\\tsi\\fake_transport_security.cc " +
"src\\core\\tsi\\ssl_transport_security.cc " +
"src\\core\\tsi\\transport_security_grpc.cc " +
"src\\core\\ext\\transport\\chttp2\\server\\chttp2_server.cc " +
"src\\core\\ext\\transport\\chttp2\\client\\secure\\secure_channel_create.cc " +
"src\\core\\ext\\transport\\chttp2\\server\\insecure\\server_chttp2.cc " +
"src\\core\\ext\\transport\\chttp2\\server\\insecure\\server_chttp2_posix.cc " +
"src\\core\\ext\\transport\\chttp2\\client\\insecure\\channel_create.cc " +
"src\\core\\ext\\transport\\chttp2\\client\\insecure\\channel_create_posix.cc " +
"src\\core\\ext\\transport\\inproc\\inproc_plugin.cc " +
"src\\core\\ext\\transport\\inproc\\inproc_transport.cc " +
"src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\client_load_reporting_filter.cc " +
@ -289,9 +325,6 @@ if (PHP_GRPC != "no") {
"src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\grpclb_client_stats.cc " +
"src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\load_balancer_api.cc " +
"src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\proto\\grpc\\lb\\v1\\load_balancer.pb.c " +
"third_party\\nanopb\\pb_common.c " +
"third_party\\nanopb\\pb_decode.c " +
"third_party\\nanopb\\pb_encode.c " +
"src\\core\\ext\\filters\\client_channel\\resolver\\fake\\fake_resolver.cc " +
"src\\core\\ext\\filters\\client_channel\\lb_policy\\pick_first\\pick_first.cc " +
"src\\core\\ext\\filters\\client_channel\\lb_policy\\subchannel_list.cc " +
@ -650,6 +683,7 @@ if (PHP_GRPC != "no") {
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\context");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials\\alts");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials\\composite");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials\\fake");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials\\google_default");
@ -666,6 +700,11 @@ if (PHP_GRPC != "no") {
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\transport");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\plugin_registry");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\tsi");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\tsi\\alts");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\tsi\\alts\\crypt");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\tsi\\alts\\frame_protector");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\tsi\\alts\\handshaker");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\tsi\\alts\\zero_copy_frame_protector");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\php");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\php\\ext");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\php\\ext\\grpc");

@ -260,6 +260,7 @@ Pod::Spec.new do |s|
'src/core/ext/filters/http/message_compress/message_compress_filter.h',
'src/core/ext/filters/http/server/http_server_filter.h',
'src/core/lib/security/context/security_context.h',
'src/core/lib/security/credentials/alts/alts_credentials.h',
'src/core/lib/security/credentials/composite/composite_credentials.h',
'src/core/lib/security/credentials/credentials.h',
'src/core/lib/security/credentials/fake/fake_credentials.h',
@ -271,6 +272,7 @@ Pod::Spec.new do |s|
'src/core/lib/security/credentials/oauth2/oauth2_credentials.h',
'src/core/lib/security/credentials/plugin/plugin_credentials.h',
'src/core/lib/security/credentials/ssl/ssl_credentials.h',
'src/core/lib/security/security_connector/alts_security_connector.h',
'src/core/lib/security/security_connector/security_connector.h',
'src/core/lib/security/transport/auth_filters.h',
'src/core/lib/security/transport/secure_endpoint.h',
@ -278,15 +280,35 @@ Pod::Spec.new do |s|
'src/core/lib/security/transport/target_authority_table.h',
'src/core/lib/security/transport/tsi_error.h',
'src/core/lib/security/util/json_util.h',
'src/core/tsi/alts_transport_security.h',
'src/core/tsi/fake_transport_security.h',
'src/core/tsi/ssl_transport_security.h',
'src/core/tsi/ssl_types.h',
'src/core/tsi/transport_security_grpc.h',
'src/core/tsi/alts/crypt/gsec.h',
'src/core/tsi/alts/frame_protector/alts_counter.h',
'src/core/tsi/alts/frame_protector/alts_crypter.h',
'src/core/tsi/alts/frame_protector/alts_frame_protector.h',
'src/core/tsi/alts/frame_protector/alts_record_protocol_crypter_common.h',
'src/core/tsi/alts/frame_protector/frame_handler.h',
'src/core/tsi/alts/handshaker/alts_handshaker_client.h',
'src/core/tsi/alts/handshaker/alts_tsi_event.h',
'src/core/tsi/alts/handshaker/alts_tsi_handshaker.h',
'src/core/tsi/alts/handshaker/alts_tsi_handshaker_private.h',
'src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.h',
'src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.h',
'src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol.h',
'src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_common.h',
'src/core/tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol.h',
'src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.h',
'src/core/lib/security/credentials/alts/check_gcp_environment.h',
'src/core/lib/security/credentials/alts/grpc_alts_credentials_options.h',
'src/core/tsi/alts/handshaker/alts_handshaker_service_api.h',
'src/core/tsi/alts/handshaker/alts_handshaker_service_api_util.h',
'src/core/tsi/alts/handshaker/alts_tsi_utils.h',
'src/core/tsi/alts/handshaker/transport_security_common_api.h',
'src/core/tsi/alts/handshaker/altscontext.pb.h',
'src/core/tsi/alts/handshaker/handshaker.pb.h',
'src/core/tsi/alts/handshaker/transport_security_common.pb.h',
'src/core/tsi/transport_security.h',
'src/core/tsi/transport_security_adapter.h',
'src/core/tsi/transport_security_interface.h',
'src/core/ext/transport/chttp2/server/chttp2_server.h',
'src/core/ext/transport/chttp2/client/chttp2_connector.h',
'src/core/ext/filters/client_channel/backup_poller.h',
'src/core/ext/filters/client_channel/client_channel.h',
'src/core/ext/filters/client_channel/client_channel_factory.h',
@ -308,7 +330,12 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/subchannel_index.h',
'src/core/ext/filters/client_channel/uri_parser.h',
'src/core/ext/filters/deadline/deadline_filter.h',
'src/core/ext/transport/chttp2/client/chttp2_connector.h',
'src/core/tsi/alts_transport_security.h',
'src/core/tsi/fake_transport_security.h',
'src/core/tsi/ssl_transport_security.h',
'src/core/tsi/ssl_types.h',
'src/core/tsi/transport_security_grpc.h',
'src/core/ext/transport/chttp2/server/chttp2_server.h',
'src/core/ext/transport/inproc/inproc_transport.h',
'src/core/lib/avl/avl.h',
'src/core/lib/backoff/backoff.h',

@ -93,7 +93,7 @@ Pod::Spec.new do |s|
}
s.default_subspecs = 'Interface', 'Implementation'
s.compiler_flags = '-DGRPC_ARES=0'
s.compiler_flags = '-DGRPC_ARES=0', '-DPB_FIELD_16BIT'
s.libraries = 'c++'
# Like many other C libraries, gRPC-Core has its public headers under `include/<libname>/` and its
@ -271,6 +271,7 @@ Pod::Spec.new do |s|
'src/core/ext/filters/http/message_compress/message_compress_filter.h',
'src/core/ext/filters/http/server/http_server_filter.h',
'src/core/lib/security/context/security_context.h',
'src/core/lib/security/credentials/alts/alts_credentials.h',
'src/core/lib/security/credentials/composite/composite_credentials.h',
'src/core/lib/security/credentials/credentials.h',
'src/core/lib/security/credentials/fake/fake_credentials.h',
@ -282,6 +283,7 @@ Pod::Spec.new do |s|
'src/core/lib/security/credentials/oauth2/oauth2_credentials.h',
'src/core/lib/security/credentials/plugin/plugin_credentials.h',
'src/core/lib/security/credentials/ssl/ssl_credentials.h',
'src/core/lib/security/security_connector/alts_security_connector.h',
'src/core/lib/security/security_connector/security_connector.h',
'src/core/lib/security/transport/auth_filters.h',
'src/core/lib/security/transport/secure_endpoint.h',
@ -289,15 +291,35 @@ Pod::Spec.new do |s|
'src/core/lib/security/transport/target_authority_table.h',
'src/core/lib/security/transport/tsi_error.h',
'src/core/lib/security/util/json_util.h',
'src/core/tsi/alts_transport_security.h',
'src/core/tsi/fake_transport_security.h',
'src/core/tsi/ssl_transport_security.h',
'src/core/tsi/ssl_types.h',
'src/core/tsi/transport_security_grpc.h',
'src/core/tsi/alts/crypt/gsec.h',
'src/core/tsi/alts/frame_protector/alts_counter.h',
'src/core/tsi/alts/frame_protector/alts_crypter.h',
'src/core/tsi/alts/frame_protector/alts_frame_protector.h',
'src/core/tsi/alts/frame_protector/alts_record_protocol_crypter_common.h',
'src/core/tsi/alts/frame_protector/frame_handler.h',
'src/core/tsi/alts/handshaker/alts_handshaker_client.h',
'src/core/tsi/alts/handshaker/alts_tsi_event.h',
'src/core/tsi/alts/handshaker/alts_tsi_handshaker.h',
'src/core/tsi/alts/handshaker/alts_tsi_handshaker_private.h',
'src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.h',
'src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.h',
'src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol.h',
'src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_common.h',
'src/core/tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol.h',
'src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.h',
'src/core/lib/security/credentials/alts/check_gcp_environment.h',
'src/core/lib/security/credentials/alts/grpc_alts_credentials_options.h',
'src/core/tsi/alts/handshaker/alts_handshaker_service_api.h',
'src/core/tsi/alts/handshaker/alts_handshaker_service_api_util.h',
'src/core/tsi/alts/handshaker/alts_tsi_utils.h',
'src/core/tsi/alts/handshaker/transport_security_common_api.h',
'src/core/tsi/alts/handshaker/altscontext.pb.h',
'src/core/tsi/alts/handshaker/handshaker.pb.h',
'src/core/tsi/alts/handshaker/transport_security_common.pb.h',
'src/core/tsi/transport_security.h',
'src/core/tsi/transport_security_adapter.h',
'src/core/tsi/transport_security_interface.h',
'src/core/ext/transport/chttp2/server/chttp2_server.h',
'src/core/ext/transport/chttp2/client/chttp2_connector.h',
'src/core/ext/filters/client_channel/backup_poller.h',
'src/core/ext/filters/client_channel/client_channel.h',
'src/core/ext/filters/client_channel/client_channel_factory.h',
@ -319,7 +341,12 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/subchannel_index.h',
'src/core/ext/filters/client_channel/uri_parser.h',
'src/core/ext/filters/deadline/deadline_filter.h',
'src/core/ext/transport/chttp2/client/chttp2_connector.h',
'src/core/tsi/alts_transport_security.h',
'src/core/tsi/fake_transport_security.h',
'src/core/tsi/ssl_transport_security.h',
'src/core/tsi/ssl_types.h',
'src/core/tsi/transport_security_grpc.h',
'src/core/ext/transport/chttp2/server/chttp2_server.h',
'src/core/ext/transport/inproc/inproc_transport.h',
'src/core/lib/avl/avl.h',
'src/core/lib/backoff/backoff.h',
@ -636,6 +663,7 @@ Pod::Spec.new do |s|
'src/core/ext/filters/http/server/http_server_filter.cc',
'src/core/lib/http/httpcli_security_connector.cc',
'src/core/lib/security/context/security_context.cc',
'src/core/lib/security/credentials/alts/alts_credentials.cc',
'src/core/lib/security/credentials/composite/composite_credentials.cc',
'src/core/lib/security/credentials/credentials.cc',
'src/core/lib/security/credentials/credentials_metadata.cc',
@ -649,6 +677,7 @@ Pod::Spec.new do |s|
'src/core/lib/security/credentials/oauth2/oauth2_credentials.cc',
'src/core/lib/security/credentials/plugin/plugin_credentials.cc',
'src/core/lib/security/credentials/ssl/ssl_credentials.cc',
'src/core/lib/security/security_connector/alts_security_connector.cc',
'src/core/lib/security/security_connector/security_connector.cc',
'src/core/lib/security/transport/client_auth_filter.cc',
'src/core/lib/security/transport/secure_endpoint.cc',
@ -658,14 +687,42 @@ Pod::Spec.new do |s|
'src/core/lib/security/transport/tsi_error.cc',
'src/core/lib/security/util/json_util.cc',
'src/core/lib/surface/init_secure.cc',
'src/core/tsi/alts_transport_security.cc',
'src/core/tsi/fake_transport_security.cc',
'src/core/tsi/ssl_transport_security.cc',
'src/core/tsi/transport_security_grpc.cc',
'src/core/tsi/alts/crypt/aes_gcm.cc',
'src/core/tsi/alts/crypt/gsec.cc',
'src/core/tsi/alts/frame_protector/alts_counter.cc',
'src/core/tsi/alts/frame_protector/alts_crypter.cc',
'src/core/tsi/alts/frame_protector/alts_frame_protector.cc',
'src/core/tsi/alts/frame_protector/alts_record_protocol_crypter_common.cc',
'src/core/tsi/alts/frame_protector/alts_seal_privacy_integrity_crypter.cc',
'src/core/tsi/alts/frame_protector/alts_unseal_privacy_integrity_crypter.cc',
'src/core/tsi/alts/frame_protector/frame_handler.cc',
'src/core/tsi/alts/handshaker/alts_handshaker_client.cc',
'src/core/tsi/alts/handshaker/alts_tsi_event.cc',
'src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc',
'src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.cc',
'src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.cc',
'src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_common.cc',
'src/core/tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol.cc',
'src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc',
'src/core/lib/security/credentials/alts/check_gcp_environment.cc',
'src/core/lib/security/credentials/alts/check_gcp_environment_linux.cc',
'src/core/lib/security/credentials/alts/check_gcp_environment_no_op.cc',
'src/core/lib/security/credentials/alts/check_gcp_environment_windows.cc',
'src/core/lib/security/credentials/alts/grpc_alts_credentials_client_options.cc',
'src/core/lib/security/credentials/alts/grpc_alts_credentials_options.cc',
'src/core/lib/security/credentials/alts/grpc_alts_credentials_server_options.cc',
'src/core/tsi/alts/handshaker/alts_handshaker_service_api.cc',
'src/core/tsi/alts/handshaker/alts_handshaker_service_api_util.cc',
'src/core/tsi/alts/handshaker/alts_tsi_utils.cc',
'src/core/tsi/alts/handshaker/transport_security_common_api.cc',
'src/core/tsi/alts/handshaker/altscontext.pb.c',
'src/core/tsi/alts/handshaker/handshaker.pb.c',
'src/core/tsi/alts/handshaker/transport_security_common.pb.c',
'src/core/tsi/transport_security.cc',
'src/core/tsi/transport_security_adapter.cc',
'src/core/ext/transport/chttp2/server/chttp2_server.cc',
'src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc',
'src/core/ext/transport/chttp2/client/insecure/channel_create.cc',
'src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc',
'src/core/ext/transport/chttp2/client/chttp2_connector.cc',
'src/core/ext/filters/client_channel/backup_poller.cc',
'src/core/ext/filters/client_channel/channel_connectivity.cc',
'src/core/ext/filters/client_channel/client_channel.cc',
@ -688,11 +745,14 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/subchannel_index.cc',
'src/core/ext/filters/client_channel/uri_parser.cc',
'src/core/ext/filters/deadline/deadline_filter.cc',
'src/core/ext/transport/chttp2/client/chttp2_connector.cc',
'src/core/tsi/alts_transport_security.cc',
'src/core/tsi/fake_transport_security.cc',
'src/core/tsi/ssl_transport_security.cc',
'src/core/tsi/transport_security_grpc.cc',
'src/core/ext/transport/chttp2/server/chttp2_server.cc',
'src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc',
'src/core/ext/transport/chttp2/server/insecure/server_chttp2.cc',
'src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc',
'src/core/ext/transport/chttp2/client/insecure/channel_create.cc',
'src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc',
'src/core/ext/transport/inproc/inproc_plugin.cc',
'src/core/ext/transport/inproc/inproc_transport.cc',
'src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc',
@ -769,6 +829,7 @@ Pod::Spec.new do |s|
'src/core/ext/filters/http/message_compress/message_compress_filter.h',
'src/core/ext/filters/http/server/http_server_filter.h',
'src/core/lib/security/context/security_context.h',
'src/core/lib/security/credentials/alts/alts_credentials.h',
'src/core/lib/security/credentials/composite/composite_credentials.h',
'src/core/lib/security/credentials/credentials.h',
'src/core/lib/security/credentials/fake/fake_credentials.h',
@ -780,6 +841,7 @@ Pod::Spec.new do |s|
'src/core/lib/security/credentials/oauth2/oauth2_credentials.h',
'src/core/lib/security/credentials/plugin/plugin_credentials.h',
'src/core/lib/security/credentials/ssl/ssl_credentials.h',
'src/core/lib/security/security_connector/alts_security_connector.h',
'src/core/lib/security/security_connector/security_connector.h',
'src/core/lib/security/transport/auth_filters.h',
'src/core/lib/security/transport/secure_endpoint.h',
@ -787,15 +849,35 @@ Pod::Spec.new do |s|
'src/core/lib/security/transport/target_authority_table.h',
'src/core/lib/security/transport/tsi_error.h',
'src/core/lib/security/util/json_util.h',
'src/core/tsi/alts_transport_security.h',
'src/core/tsi/fake_transport_security.h',
'src/core/tsi/ssl_transport_security.h',
'src/core/tsi/ssl_types.h',
'src/core/tsi/transport_security_grpc.h',
'src/core/tsi/alts/crypt/gsec.h',
'src/core/tsi/alts/frame_protector/alts_counter.h',
'src/core/tsi/alts/frame_protector/alts_crypter.h',
'src/core/tsi/alts/frame_protector/alts_frame_protector.h',
'src/core/tsi/alts/frame_protector/alts_record_protocol_crypter_common.h',
'src/core/tsi/alts/frame_protector/frame_handler.h',
'src/core/tsi/alts/handshaker/alts_handshaker_client.h',
'src/core/tsi/alts/handshaker/alts_tsi_event.h',
'src/core/tsi/alts/handshaker/alts_tsi_handshaker.h',
'src/core/tsi/alts/handshaker/alts_tsi_handshaker_private.h',
'src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.h',
'src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.h',
'src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol.h',
'src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_common.h',
'src/core/tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol.h',
'src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.h',
'src/core/lib/security/credentials/alts/check_gcp_environment.h',
'src/core/lib/security/credentials/alts/grpc_alts_credentials_options.h',
'src/core/tsi/alts/handshaker/alts_handshaker_service_api.h',
'src/core/tsi/alts/handshaker/alts_handshaker_service_api_util.h',
'src/core/tsi/alts/handshaker/alts_tsi_utils.h',
'src/core/tsi/alts/handshaker/transport_security_common_api.h',
'src/core/tsi/alts/handshaker/altscontext.pb.h',
'src/core/tsi/alts/handshaker/handshaker.pb.h',
'src/core/tsi/alts/handshaker/transport_security_common.pb.h',
'src/core/tsi/transport_security.h',
'src/core/tsi/transport_security_adapter.h',
'src/core/tsi/transport_security_interface.h',
'src/core/ext/transport/chttp2/server/chttp2_server.h',
'src/core/ext/transport/chttp2/client/chttp2_connector.h',
'src/core/ext/filters/client_channel/backup_poller.h',
'src/core/ext/filters/client_channel/client_channel.h',
'src/core/ext/filters/client_channel/client_channel_factory.h',
@ -817,7 +899,12 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/subchannel_index.h',
'src/core/ext/filters/client_channel/uri_parser.h',
'src/core/ext/filters/deadline/deadline_filter.h',
'src/core/ext/transport/chttp2/client/chttp2_connector.h',
'src/core/tsi/alts_transport_security.h',
'src/core/tsi/fake_transport_security.h',
'src/core/tsi/ssl_transport_security.h',
'src/core/tsi/ssl_types.h',
'src/core/tsi/transport_security_grpc.h',
'src/core/ext/transport/chttp2/server/chttp2_server.h',
'src/core/ext/transport/inproc/inproc_transport.h',
'src/core/lib/avl/avl.h',
'src/core/lib/backoff/backoff.h',
@ -981,8 +1068,15 @@ Pod::Spec.new do |s|
ss.source_files = 'src/core/ext/transport/cronet/client/secure/cronet_channel_create.cc',
'src/core/ext/transport/cronet/transport/cronet_transport.cc',
'third_party/nanopb/pb_common.c',
'third_party/nanopb/pb_decode.c',
'third_party/nanopb/pb_encode.c',
'src/core/ext/transport/cronet/transport/cronet_transport.h',
'third_party/objective_c/Cronet/bidirectional_stream_c.h'
'third_party/objective_c/Cronet/bidirectional_stream_c.h',
'third_party/nanopb/pb.h',
'third_party/nanopb/pb_common.h',
'third_party/nanopb/pb_decode.h',
'third_party/nanopb/pb_encode.h'
end
s.subspec 'Tests' do |ss|

@ -197,6 +197,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/filters/http/message_compress/message_compress_filter.h )
s.files += %w( src/core/ext/filters/http/server/http_server_filter.h )
s.files += %w( src/core/lib/security/context/security_context.h )
s.files += %w( src/core/lib/security/credentials/alts/alts_credentials.h )
s.files += %w( src/core/lib/security/credentials/composite/composite_credentials.h )
s.files += %w( src/core/lib/security/credentials/credentials.h )
s.files += %w( src/core/lib/security/credentials/fake/fake_credentials.h )
@ -208,6 +209,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/security/credentials/oauth2/oauth2_credentials.h )
s.files += %w( src/core/lib/security/credentials/plugin/plugin_credentials.h )
s.files += %w( src/core/lib/security/credentials/ssl/ssl_credentials.h )
s.files += %w( src/core/lib/security/security_connector/alts_security_connector.h )
s.files += %w( src/core/lib/security/security_connector/security_connector.h )
s.files += %w( src/core/lib/security/transport/auth_filters.h )
s.files += %w( src/core/lib/security/transport/secure_endpoint.h )
@ -215,15 +217,39 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/security/transport/target_authority_table.h )
s.files += %w( src/core/lib/security/transport/tsi_error.h )
s.files += %w( src/core/lib/security/util/json_util.h )
s.files += %w( src/core/tsi/alts_transport_security.h )
s.files += %w( src/core/tsi/fake_transport_security.h )
s.files += %w( src/core/tsi/ssl_transport_security.h )
s.files += %w( src/core/tsi/ssl_types.h )
s.files += %w( src/core/tsi/transport_security_grpc.h )
s.files += %w( src/core/tsi/alts/crypt/gsec.h )
s.files += %w( src/core/tsi/alts/frame_protector/alts_counter.h )
s.files += %w( src/core/tsi/alts/frame_protector/alts_crypter.h )
s.files += %w( src/core/tsi/alts/frame_protector/alts_frame_protector.h )
s.files += %w( src/core/tsi/alts/frame_protector/alts_record_protocol_crypter_common.h )
s.files += %w( src/core/tsi/alts/frame_protector/frame_handler.h )
s.files += %w( src/core/tsi/alts/handshaker/alts_handshaker_client.h )
s.files += %w( src/core/tsi/alts/handshaker/alts_tsi_event.h )
s.files += %w( src/core/tsi/alts/handshaker/alts_tsi_handshaker.h )
s.files += %w( src/core/tsi/alts/handshaker/alts_tsi_handshaker_private.h )
s.files += %w( src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.h )
s.files += %w( src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.h )
s.files += %w( src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol.h )
s.files += %w( src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_common.h )
s.files += %w( src/core/tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol.h )
s.files += %w( src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.h )
s.files += %w( src/core/lib/security/credentials/alts/check_gcp_environment.h )
s.files += %w( src/core/lib/security/credentials/alts/grpc_alts_credentials_options.h )
s.files += %w( src/core/tsi/alts/handshaker/alts_handshaker_service_api.h )
s.files += %w( src/core/tsi/alts/handshaker/alts_handshaker_service_api_util.h )
s.files += %w( src/core/tsi/alts/handshaker/alts_tsi_utils.h )
s.files += %w( src/core/tsi/alts/handshaker/transport_security_common_api.h )
s.files += %w( src/core/tsi/alts/handshaker/altscontext.pb.h )
s.files += %w( src/core/tsi/alts/handshaker/handshaker.pb.h )
s.files += %w( src/core/tsi/alts/handshaker/transport_security_common.pb.h )
s.files += %w( third_party/nanopb/pb.h )
s.files += %w( third_party/nanopb/pb_common.h )
s.files += %w( third_party/nanopb/pb_decode.h )
s.files += %w( third_party/nanopb/pb_encode.h )
s.files += %w( src/core/tsi/transport_security.h )
s.files += %w( src/core/tsi/transport_security_adapter.h )
s.files += %w( src/core/tsi/transport_security_interface.h )
s.files += %w( src/core/ext/transport/chttp2/server/chttp2_server.h )
s.files += %w( src/core/ext/transport/chttp2/client/chttp2_connector.h )
s.files += %w( src/core/ext/filters/client_channel/backup_poller.h )
s.files += %w( src/core/ext/filters/client_channel/client_channel.h )
s.files += %w( src/core/ext/filters/client_channel/client_channel_factory.h )
@ -245,7 +271,12 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/filters/client_channel/subchannel_index.h )
s.files += %w( src/core/ext/filters/client_channel/uri_parser.h )
s.files += %w( src/core/ext/filters/deadline/deadline_filter.h )
s.files += %w( src/core/ext/transport/chttp2/client/chttp2_connector.h )
s.files += %w( src/core/tsi/alts_transport_security.h )
s.files += %w( src/core/tsi/fake_transport_security.h )
s.files += %w( src/core/tsi/ssl_transport_security.h )
s.files += %w( src/core/tsi/ssl_types.h )
s.files += %w( src/core/tsi/transport_security_grpc.h )
s.files += %w( src/core/ext/transport/chttp2/server/chttp2_server.h )
s.files += %w( src/core/ext/transport/inproc/inproc_transport.h )
s.files += %w( src/core/lib/avl/avl.h )
s.files += %w( src/core/lib/backoff/backoff.h )
@ -383,10 +414,6 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h )
s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h )
s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h )
s.files += %w( third_party/nanopb/pb.h )
s.files += %w( third_party/nanopb/pb_common.h )
s.files += %w( third_party/nanopb/pb_decode.h )
s.files += %w( third_party/nanopb/pb_encode.h )
s.files += %w( src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h )
s.files += %w( src/core/ext/filters/client_channel/lb_policy/subchannel_list.h )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h )
@ -566,6 +593,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/filters/http/server/http_server_filter.cc )
s.files += %w( src/core/lib/http/httpcli_security_connector.cc )
s.files += %w( src/core/lib/security/context/security_context.cc )
s.files += %w( src/core/lib/security/credentials/alts/alts_credentials.cc )
s.files += %w( src/core/lib/security/credentials/composite/composite_credentials.cc )
s.files += %w( src/core/lib/security/credentials/credentials.cc )
s.files += %w( src/core/lib/security/credentials/credentials_metadata.cc )
@ -579,6 +607,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/security/credentials/oauth2/oauth2_credentials.cc )
s.files += %w( src/core/lib/security/credentials/plugin/plugin_credentials.cc )
s.files += %w( src/core/lib/security/credentials/ssl/ssl_credentials.cc )
s.files += %w( src/core/lib/security/security_connector/alts_security_connector.cc )
s.files += %w( src/core/lib/security/security_connector/security_connector.cc )
s.files += %w( src/core/lib/security/transport/client_auth_filter.cc )
s.files += %w( src/core/lib/security/transport/secure_endpoint.cc )
@ -588,14 +617,45 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/security/transport/tsi_error.cc )
s.files += %w( src/core/lib/security/util/json_util.cc )
s.files += %w( src/core/lib/surface/init_secure.cc )
s.files += %w( src/core/tsi/alts_transport_security.cc )
s.files += %w( src/core/tsi/fake_transport_security.cc )
s.files += %w( src/core/tsi/ssl_transport_security.cc )
s.files += %w( src/core/tsi/transport_security_grpc.cc )
s.files += %w( src/core/tsi/alts/crypt/aes_gcm.cc )
s.files += %w( src/core/tsi/alts/crypt/gsec.cc )
s.files += %w( src/core/tsi/alts/frame_protector/alts_counter.cc )
s.files += %w( src/core/tsi/alts/frame_protector/alts_crypter.cc )
s.files += %w( src/core/tsi/alts/frame_protector/alts_frame_protector.cc )
s.files += %w( src/core/tsi/alts/frame_protector/alts_record_protocol_crypter_common.cc )
s.files += %w( src/core/tsi/alts/frame_protector/alts_seal_privacy_integrity_crypter.cc )
s.files += %w( src/core/tsi/alts/frame_protector/alts_unseal_privacy_integrity_crypter.cc )
s.files += %w( src/core/tsi/alts/frame_protector/frame_handler.cc )
s.files += %w( src/core/tsi/alts/handshaker/alts_handshaker_client.cc )
s.files += %w( src/core/tsi/alts/handshaker/alts_tsi_event.cc )
s.files += %w( src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc )
s.files += %w( src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.cc )
s.files += %w( src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.cc )
s.files += %w( src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_common.cc )
s.files += %w( src/core/tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol.cc )
s.files += %w( src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc )
s.files += %w( src/core/lib/security/credentials/alts/check_gcp_environment.cc )
s.files += %w( src/core/lib/security/credentials/alts/check_gcp_environment_linux.cc )
s.files += %w( src/core/lib/security/credentials/alts/check_gcp_environment_no_op.cc )
s.files += %w( src/core/lib/security/credentials/alts/check_gcp_environment_windows.cc )
s.files += %w( src/core/lib/security/credentials/alts/grpc_alts_credentials_client_options.cc )
s.files += %w( src/core/lib/security/credentials/alts/grpc_alts_credentials_options.cc )
s.files += %w( src/core/lib/security/credentials/alts/grpc_alts_credentials_server_options.cc )
s.files += %w( src/core/tsi/alts/handshaker/alts_handshaker_service_api.cc )
s.files += %w( src/core/tsi/alts/handshaker/alts_handshaker_service_api_util.cc )
s.files += %w( src/core/tsi/alts/handshaker/alts_tsi_utils.cc )
s.files += %w( src/core/tsi/alts/handshaker/transport_security_common_api.cc )
s.files += %w( src/core/tsi/alts/handshaker/altscontext.pb.c )
s.files += %w( src/core/tsi/alts/handshaker/handshaker.pb.c )
s.files += %w( src/core/tsi/alts/handshaker/transport_security_common.pb.c )
s.files += %w( third_party/nanopb/pb_common.c )
s.files += %w( third_party/nanopb/pb_decode.c )
s.files += %w( third_party/nanopb/pb_encode.c )
s.files += %w( src/core/tsi/transport_security.cc )
s.files += %w( src/core/tsi/transport_security_adapter.cc )
s.files += %w( src/core/ext/transport/chttp2/server/chttp2_server.cc )
s.files += %w( src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc )
s.files += %w( src/core/ext/transport/chttp2/client/insecure/channel_create.cc )
s.files += %w( src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc )
s.files += %w( src/core/ext/transport/chttp2/client/chttp2_connector.cc )
s.files += %w( src/core/ext/filters/client_channel/backup_poller.cc )
s.files += %w( src/core/ext/filters/client_channel/channel_connectivity.cc )
s.files += %w( src/core/ext/filters/client_channel/client_channel.cc )
@ -618,11 +678,14 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/filters/client_channel/subchannel_index.cc )
s.files += %w( src/core/ext/filters/client_channel/uri_parser.cc )
s.files += %w( src/core/ext/filters/deadline/deadline_filter.cc )
s.files += %w( src/core/ext/transport/chttp2/client/chttp2_connector.cc )
s.files += %w( src/core/tsi/alts_transport_security.cc )
s.files += %w( src/core/tsi/fake_transport_security.cc )
s.files += %w( src/core/tsi/ssl_transport_security.cc )
s.files += %w( src/core/tsi/transport_security_grpc.cc )
s.files += %w( src/core/ext/transport/chttp2/server/chttp2_server.cc )
s.files += %w( src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc )
s.files += %w( src/core/ext/transport/chttp2/server/insecure/server_chttp2.cc )
s.files += %w( src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc )
s.files += %w( src/core/ext/transport/chttp2/client/insecure/channel_create.cc )
s.files += %w( src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc )
s.files += %w( src/core/ext/transport/inproc/inproc_plugin.cc )
s.files += %w( src/core/ext/transport/inproc/inproc_transport.cc )
s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc )
@ -631,9 +694,6 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc )
s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc )
s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c )
s.files += %w( third_party/nanopb/pb_common.c )
s.files += %w( third_party/nanopb/pb_decode.c )
s.files += %w( third_party/nanopb/pb_encode.c )
s.files += %w( src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc )
s.files += %w( src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc )
s.files += %w( src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc )

@ -64,11 +64,11 @@
],
'cflags_c': [
'-Werror',
'-std=c99'
'-std=c99',
],
'cflags_cc': [
'-Werror',
'-std=c++11'
'-std=c++11',
],
'include_dirs': [
'.',
@ -148,13 +148,24 @@
'-Wno-deprecated-declarations',
'-stdlib=libc++',
'-std=c++11',
'-Wno-error=deprecated-declarations'
'-Wno-error=deprecated-declarations',
],
},
}]
]
},
'targets': [
{
'target_name': 'alts_test_util',
'type': 'static_library',
'dependencies': [
'grpc',
],
'sources': [
'test/core/tsi/alts/crypt/gsec_test_util.cc',
'test/core/tsi/alts/handshaker/alts_handshaker_service_api_test_lib.cc',
],
},
{
'target_name': 'gpr',
'type': 'static_library',
@ -388,6 +399,7 @@
'src/core/ext/filters/http/server/http_server_filter.cc',
'src/core/lib/http/httpcli_security_connector.cc',
'src/core/lib/security/context/security_context.cc',
'src/core/lib/security/credentials/alts/alts_credentials.cc',
'src/core/lib/security/credentials/composite/composite_credentials.cc',
'src/core/lib/security/credentials/credentials.cc',
'src/core/lib/security/credentials/credentials_metadata.cc',
@ -401,6 +413,7 @@
'src/core/lib/security/credentials/oauth2/oauth2_credentials.cc',
'src/core/lib/security/credentials/plugin/plugin_credentials.cc',
'src/core/lib/security/credentials/ssl/ssl_credentials.cc',
'src/core/lib/security/security_connector/alts_security_connector.cc',
'src/core/lib/security/security_connector/security_connector.cc',
'src/core/lib/security/transport/client_auth_filter.cc',
'src/core/lib/security/transport/secure_endpoint.cc',
@ -410,14 +423,45 @@
'src/core/lib/security/transport/tsi_error.cc',
'src/core/lib/security/util/json_util.cc',
'src/core/lib/surface/init_secure.cc',
'src/core/tsi/alts_transport_security.cc',
'src/core/tsi/fake_transport_security.cc',
'src/core/tsi/ssl_transport_security.cc',
'src/core/tsi/transport_security_grpc.cc',
'src/core/tsi/alts/crypt/aes_gcm.cc',
'src/core/tsi/alts/crypt/gsec.cc',
'src/core/tsi/alts/frame_protector/alts_counter.cc',
'src/core/tsi/alts/frame_protector/alts_crypter.cc',
'src/core/tsi/alts/frame_protector/alts_frame_protector.cc',
'src/core/tsi/alts/frame_protector/alts_record_protocol_crypter_common.cc',
'src/core/tsi/alts/frame_protector/alts_seal_privacy_integrity_crypter.cc',
'src/core/tsi/alts/frame_protector/alts_unseal_privacy_integrity_crypter.cc',
'src/core/tsi/alts/frame_protector/frame_handler.cc',
'src/core/tsi/alts/handshaker/alts_handshaker_client.cc',
'src/core/tsi/alts/handshaker/alts_tsi_event.cc',
'src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc',
'src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.cc',
'src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.cc',
'src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_common.cc',
'src/core/tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol.cc',
'src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc',
'src/core/lib/security/credentials/alts/check_gcp_environment.cc',
'src/core/lib/security/credentials/alts/check_gcp_environment_linux.cc',
'src/core/lib/security/credentials/alts/check_gcp_environment_no_op.cc',
'src/core/lib/security/credentials/alts/check_gcp_environment_windows.cc',
'src/core/lib/security/credentials/alts/grpc_alts_credentials_client_options.cc',
'src/core/lib/security/credentials/alts/grpc_alts_credentials_options.cc',
'src/core/lib/security/credentials/alts/grpc_alts_credentials_server_options.cc',
'src/core/tsi/alts/handshaker/alts_handshaker_service_api.cc',
'src/core/tsi/alts/handshaker/alts_handshaker_service_api_util.cc',
'src/core/tsi/alts/handshaker/alts_tsi_utils.cc',
'src/core/tsi/alts/handshaker/transport_security_common_api.cc',
'src/core/tsi/alts/handshaker/altscontext.pb.c',
'src/core/tsi/alts/handshaker/handshaker.pb.c',
'src/core/tsi/alts/handshaker/transport_security_common.pb.c',
'third_party/nanopb/pb_common.c',
'third_party/nanopb/pb_decode.c',
'third_party/nanopb/pb_encode.c',
'src/core/tsi/transport_security.cc',
'src/core/tsi/transport_security_adapter.cc',
'src/core/ext/transport/chttp2/server/chttp2_server.cc',
'src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc',
'src/core/ext/transport/chttp2/client/insecure/channel_create.cc',
'src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc',
'src/core/ext/transport/chttp2/client/chttp2_connector.cc',
'src/core/ext/filters/client_channel/backup_poller.cc',
'src/core/ext/filters/client_channel/channel_connectivity.cc',
'src/core/ext/filters/client_channel/client_channel.cc',
@ -440,11 +484,14 @@
'src/core/ext/filters/client_channel/subchannel_index.cc',
'src/core/ext/filters/client_channel/uri_parser.cc',
'src/core/ext/filters/deadline/deadline_filter.cc',
'src/core/ext/transport/chttp2/client/chttp2_connector.cc',
'src/core/tsi/alts_transport_security.cc',
'src/core/tsi/fake_transport_security.cc',
'src/core/tsi/ssl_transport_security.cc',
'src/core/tsi/transport_security_grpc.cc',
'src/core/ext/transport/chttp2/server/chttp2_server.cc',
'src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc',
'src/core/ext/transport/chttp2/server/insecure/server_chttp2.cc',
'src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc',
'src/core/ext/transport/chttp2/client/insecure/channel_create.cc',
'src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc',
'src/core/ext/transport/inproc/inproc_plugin.cc',
'src/core/ext/transport/inproc/inproc_transport.cc',
'src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc',
@ -453,9 +500,6 @@
'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc',
'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc',
'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c',
'third_party/nanopb/pb_common.c',
'third_party/nanopb/pb_decode.c',
'third_party/nanopb/pb_encode.c',
'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc',
'src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc',
'src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc',

@ -204,6 +204,7 @@
<file baseinstalldir="/" name="src/core/ext/filters/http/message_compress/message_compress_filter.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/http/server/http_server_filter.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/context/security_context.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/credentials/alts/alts_credentials.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/credentials/composite/composite_credentials.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/credentials/credentials.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/credentials/fake/fake_credentials.h" role="src" />
@ -215,6 +216,7 @@
<file baseinstalldir="/" name="src/core/lib/security/credentials/oauth2/oauth2_credentials.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/credentials/plugin/plugin_credentials.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/credentials/ssl/ssl_credentials.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/security_connector/alts_security_connector.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/security_connector/security_connector.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/transport/auth_filters.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/transport/secure_endpoint.h" role="src" />
@ -222,15 +224,39 @@
<file baseinstalldir="/" name="src/core/lib/security/transport/target_authority_table.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/transport/tsi_error.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/util/json_util.h" role="src" />
<file baseinstalldir="/" name="src/core/tsi/alts_transport_security.h" role="src" />
<file baseinstalldir="/" name="src/core/tsi/fake_transport_security.h" role="src" />
<file baseinstalldir="/" name="src/core/tsi/ssl_transport_security.h" role="src" />
<file baseinstalldir="/" name="src/core/tsi/ssl_types.h" role="src" />
<file baseinstalldir="/" name="src/core/tsi/transport_security_grpc.h" role="src" />
<file baseinstalldir="/" name="src/core/tsi/alts/crypt/gsec.h" role="src" />
<file baseinstalldir="/" name="src/core/tsi/alts/frame_protector/alts_counter.h" role="src" />
<file baseinstalldir="/" name="src/core/tsi/alts/frame_protector/alts_crypter.h" role="src" />
<file baseinstalldir="/" name="src/core/tsi/alts/frame_protector/alts_frame_protector.h" role="src" />
<file baseinstalldir="/" name="src/core/tsi/alts/frame_protector/alts_record_protocol_crypter_common.h" role="src" />
<file baseinstalldir="/" name="src/core/tsi/alts/frame_protector/frame_handler.h" role="src" />
<file baseinstalldir="/" name="src/core/tsi/alts/handshaker/alts_handshaker_client.h" role="src" />
<file baseinstalldir="/" name="src/core/tsi/alts/handshaker/alts_tsi_event.h" role="src" />
<file baseinstalldir="/" name="src/core/tsi/alts/handshaker/alts_tsi_handshaker.h" role="src" />
<file baseinstalldir="/" name="src/core/tsi/alts/handshaker/alts_tsi_handshaker_private.h" role="src" />
<file baseinstalldir="/" name="src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.h" role="src" />
<file baseinstalldir="/" name="src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.h" role="src" />
<file baseinstalldir="/" name="src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol.h" role="src" />
<file baseinstalldir="/" name="src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_common.h" role="src" />
<file baseinstalldir="/" name="src/core/tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol.h" role="src" />
<file baseinstalldir="/" name="src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/credentials/alts/check_gcp_environment.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/credentials/alts/grpc_alts_credentials_options.h" role="src" />
<file baseinstalldir="/" name="src/core/tsi/alts/handshaker/alts_handshaker_service_api.h" role="src" />
<file baseinstalldir="/" name="src/core/tsi/alts/handshaker/alts_handshaker_service_api_util.h" role="src" />
<file baseinstalldir="/" name="src/core/tsi/alts/handshaker/alts_tsi_utils.h" role="src" />
<file baseinstalldir="/" name="src/core/tsi/alts/handshaker/transport_security_common_api.h" role="src" />
<file baseinstalldir="/" name="src/core/tsi/alts/handshaker/altscontext.pb.h" role="src" />
<file baseinstalldir="/" name="src/core/tsi/alts/handshaker/handshaker.pb.h" role="src" />
<file baseinstalldir="/" name="src/core/tsi/alts/handshaker/transport_security_common.pb.h" role="src" />
<file baseinstalldir="/" name="third_party/nanopb/pb.h" role="src" />
<file baseinstalldir="/" name="third_party/nanopb/pb_common.h" role="src" />
<file baseinstalldir="/" name="third_party/nanopb/pb_decode.h" role="src" />
<file baseinstalldir="/" name="third_party/nanopb/pb_encode.h" role="src" />
<file baseinstalldir="/" name="src/core/tsi/transport_security.h" role="src" />
<file baseinstalldir="/" name="src/core/tsi/transport_security_adapter.h" role="src" />
<file baseinstalldir="/" name="src/core/tsi/transport_security_interface.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/server/chttp2_server.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/client/chttp2_connector.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/backup_poller.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/client_channel.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/client_channel_factory.h" role="src" />
@ -252,7 +278,12 @@
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/subchannel_index.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/uri_parser.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/deadline/deadline_filter.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/client/chttp2_connector.h" role="src" />
<file baseinstalldir="/" name="src/core/tsi/alts_transport_security.h" role="src" />
<file baseinstalldir="/" name="src/core/tsi/fake_transport_security.h" role="src" />
<file baseinstalldir="/" name="src/core/tsi/ssl_transport_security.h" role="src" />
<file baseinstalldir="/" name="src/core/tsi/ssl_types.h" role="src" />
<file baseinstalldir="/" name="src/core/tsi/transport_security_grpc.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/server/chttp2_server.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/inproc/inproc_transport.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/avl/avl.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/backoff/backoff.h" role="src" />
@ -390,10 +421,6 @@
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h" role="src" />
<file baseinstalldir="/" name="third_party/nanopb/pb.h" role="src" />
<file baseinstalldir="/" name="third_party/nanopb/pb_common.h" role="src" />
<file baseinstalldir="/" name="third_party/nanopb/pb_decode.h" role="src" />
<file baseinstalldir="/" name="third_party/nanopb/pb_encode.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/subchannel_list.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h" role="src" />
@ -573,6 +600,7 @@
<file baseinstalldir="/" name="src/core/ext/filters/http/server/http_server_filter.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/http/httpcli_security_connector.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/context/security_context.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/credentials/alts/alts_credentials.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/credentials/composite/composite_credentials.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/credentials/credentials.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/credentials/credentials_metadata.cc" role="src" />
@ -586,6 +614,7 @@
<file baseinstalldir="/" name="src/core/lib/security/credentials/oauth2/oauth2_credentials.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/credentials/plugin/plugin_credentials.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/credentials/ssl/ssl_credentials.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/security_connector/alts_security_connector.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/security_connector/security_connector.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/transport/client_auth_filter.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/transport/secure_endpoint.cc" role="src" />
@ -595,14 +624,45 @@
<file baseinstalldir="/" name="src/core/lib/security/transport/tsi_error.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/util/json_util.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/surface/init_secure.cc" role="src" />
<file baseinstalldir="/" name="src/core/tsi/alts_transport_security.cc" role="src" />
<file baseinstalldir="/" name="src/core/tsi/fake_transport_security.cc" role="src" />
<file baseinstalldir="/" name="src/core/tsi/ssl_transport_security.cc" role="src" />
<file baseinstalldir="/" name="src/core/tsi/transport_security_grpc.cc" role="src" />
<file baseinstalldir="/" name="src/core/tsi/alts/crypt/aes_gcm.cc" role="src" />
<file baseinstalldir="/" name="src/core/tsi/alts/crypt/gsec.cc" role="src" />
<file baseinstalldir="/" name="src/core/tsi/alts/frame_protector/alts_counter.cc" role="src" />
<file baseinstalldir="/" name="src/core/tsi/alts/frame_protector/alts_crypter.cc" role="src" />
<file baseinstalldir="/" name="src/core/tsi/alts/frame_protector/alts_frame_protector.cc" role="src" />
<file baseinstalldir="/" name="src/core/tsi/alts/frame_protector/alts_record_protocol_crypter_common.cc" role="src" />
<file baseinstalldir="/" name="src/core/tsi/alts/frame_protector/alts_seal_privacy_integrity_crypter.cc" role="src" />
<file baseinstalldir="/" name="src/core/tsi/alts/frame_protector/alts_unseal_privacy_integrity_crypter.cc" role="src" />
<file baseinstalldir="/" name="src/core/tsi/alts/frame_protector/frame_handler.cc" role="src" />
<file baseinstalldir="/" name="src/core/tsi/alts/handshaker/alts_handshaker_client.cc" role="src" />
<file baseinstalldir="/" name="src/core/tsi/alts/handshaker/alts_tsi_event.cc" role="src" />
<file baseinstalldir="/" name="src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc" role="src" />
<file baseinstalldir="/" name="src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.cc" role="src" />
<file baseinstalldir="/" name="src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.cc" role="src" />
<file baseinstalldir="/" name="src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_common.cc" role="src" />
<file baseinstalldir="/" name="src/core/tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol.cc" role="src" />
<file baseinstalldir="/" name="src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/credentials/alts/check_gcp_environment.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/credentials/alts/check_gcp_environment_linux.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/credentials/alts/check_gcp_environment_no_op.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/credentials/alts/check_gcp_environment_windows.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/credentials/alts/grpc_alts_credentials_client_options.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/credentials/alts/grpc_alts_credentials_options.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/credentials/alts/grpc_alts_credentials_server_options.cc" role="src" />
<file baseinstalldir="/" name="src/core/tsi/alts/handshaker/alts_handshaker_service_api.cc" role="src" />
<file baseinstalldir="/" name="src/core/tsi/alts/handshaker/alts_handshaker_service_api_util.cc" role="src" />
<file baseinstalldir="/" name="src/core/tsi/alts/handshaker/alts_tsi_utils.cc" role="src" />
<file baseinstalldir="/" name="src/core/tsi/alts/handshaker/transport_security_common_api.cc" role="src" />
<file baseinstalldir="/" name="src/core/tsi/alts/handshaker/altscontext.pb.c" role="src" />
<file baseinstalldir="/" name="src/core/tsi/alts/handshaker/handshaker.pb.c" role="src" />
<file baseinstalldir="/" name="src/core/tsi/alts/handshaker/transport_security_common.pb.c" role="src" />
<file baseinstalldir="/" name="third_party/nanopb/pb_common.c" role="src" />
<file baseinstalldir="/" name="third_party/nanopb/pb_decode.c" role="src" />
<file baseinstalldir="/" name="third_party/nanopb/pb_encode.c" role="src" />
<file baseinstalldir="/" name="src/core/tsi/transport_security.cc" role="src" />
<file baseinstalldir="/" name="src/core/tsi/transport_security_adapter.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/server/chttp2_server.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/client/insecure/channel_create.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/client/chttp2_connector.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/backup_poller.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/channel_connectivity.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/client_channel.cc" role="src" />
@ -625,11 +685,14 @@
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/subchannel_index.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/uri_parser.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/deadline/deadline_filter.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/client/chttp2_connector.cc" role="src" />
<file baseinstalldir="/" name="src/core/tsi/alts_transport_security.cc" role="src" />
<file baseinstalldir="/" name="src/core/tsi/fake_transport_security.cc" role="src" />
<file baseinstalldir="/" name="src/core/tsi/ssl_transport_security.cc" role="src" />
<file baseinstalldir="/" name="src/core/tsi/transport_security_grpc.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/server/chttp2_server.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/server/insecure/server_chttp2.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/client/insecure/channel_create.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/inproc/inproc_plugin.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/inproc/inproc_transport.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc" role="src" />
@ -638,9 +701,6 @@
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c" role="src" />
<file baseinstalldir="/" name="third_party/nanopb/pb_common.c" role="src" />
<file baseinstalldir="/" name="third_party/nanopb/pb_decode.c" role="src" />
<file baseinstalldir="/" name="third_party/nanopb/pb_encode.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc" role="src" />

@ -118,6 +118,7 @@ if EXTRA_ENV_COMPILE_ARGS is None:
EXTRA_ENV_COMPILE_ARGS += ' -std=c++11 -std=gnu99 -fvisibility=hidden -fno-wrapv -fno-exceptions'
elif "darwin" in sys.platform:
EXTRA_ENV_COMPILE_ARGS += ' -fvisibility=hidden -fno-wrapv -fno-exceptions'
EXTRA_ENV_COMPILE_ARGS += ' -DPB_FIELD_16BIT'
if EXTRA_ENV_LINK_ARGS is None:
EXTRA_ENV_LINK_ARGS = ''
@ -160,7 +161,7 @@ if "win32" in sys.platform:
DEFINE_MACROS = (
('OPENSSL_NO_ASM', 1), ('_WIN32_WINNT', 0x600),
('GPR_BACKWARDS_COMPATIBILITY_MODE', 1),)
('GPR_BACKWARDS_COMPATIBILITY_MODE', 1))
if "win32" in sys.platform:
# TODO(zyc): Re-enble c-ares on x64 and x86 windows after fixing the
# ares_library_init compilation issue

@ -191,7 +191,7 @@ class GrpcLb : public LoadBalancingPolicy {
~BalancerCallState();
GrpcLb* grpclb_policy() const {
return reinterpret_cast<GrpcLb*>(grpclb_policy_.get());
return static_cast<GrpcLb*>(grpclb_policy_.get());
}
void ScheduleNextClientLoadReportLocked();
@ -651,7 +651,7 @@ void GrpcLb::BalancerCallState::ScheduleNextClientLoadReportLocked() {
void GrpcLb::BalancerCallState::MaybeSendClientLoadReportLocked(
void* arg, grpc_error* error) {
BalancerCallState* lb_calld = reinterpret_cast<BalancerCallState*>(arg);
BalancerCallState* lb_calld = static_cast<BalancerCallState*>(arg);
GrpcLb* grpclb_policy = lb_calld->grpclb_policy();
lb_calld->client_load_report_timer_callback_pending_ = false;
if (error != GRPC_ERROR_NONE || lb_calld != grpclb_policy->lb_calld_.get()) {
@ -721,7 +721,7 @@ void GrpcLb::BalancerCallState::SendClientLoadReportLocked() {
void GrpcLb::BalancerCallState::ClientLoadReportDoneLocked(void* arg,
grpc_error* error) {
BalancerCallState* lb_calld = reinterpret_cast<BalancerCallState*>(arg);
BalancerCallState* lb_calld = static_cast<BalancerCallState*>(arg);
GrpcLb* grpclb_policy = lb_calld->grpclb_policy();
grpc_byte_buffer_destroy(lb_calld->send_message_payload_);
lb_calld->send_message_payload_ = nullptr;
@ -734,7 +734,7 @@ void GrpcLb::BalancerCallState::ClientLoadReportDoneLocked(void* arg,
void GrpcLb::BalancerCallState::OnInitialRequestSentLocked(void* arg,
grpc_error* error) {
BalancerCallState* lb_calld = reinterpret_cast<BalancerCallState*>(arg);
BalancerCallState* lb_calld = static_cast<BalancerCallState*>(arg);
grpc_byte_buffer_destroy(lb_calld->send_message_payload_);
lb_calld->send_message_payload_ = nullptr;
// If we attempted to send a client load report before the initial request was
@ -749,7 +749,7 @@ void GrpcLb::BalancerCallState::OnInitialRequestSentLocked(void* arg,
void GrpcLb::BalancerCallState::OnBalancerMessageReceivedLocked(
void* arg, grpc_error* error) {
BalancerCallState* lb_calld = reinterpret_cast<BalancerCallState*>(arg);
BalancerCallState* lb_calld = static_cast<BalancerCallState*>(arg);
GrpcLb* grpclb_policy = lb_calld->grpclb_policy();
// Empty payload means the LB call was cancelled.
if (lb_calld != grpclb_policy->lb_calld_.get() ||
@ -882,7 +882,7 @@ void GrpcLb::BalancerCallState::OnBalancerMessageReceivedLocked(
void GrpcLb::BalancerCallState::OnBalancerStatusReceivedLocked(
void* arg, grpc_error* error) {
BalancerCallState* lb_calld = reinterpret_cast<BalancerCallState*>(arg);
BalancerCallState* lb_calld = static_cast<BalancerCallState*>(arg);
GrpcLb* grpclb_policy = lb_calld->grpclb_policy();
GPR_ASSERT(lb_calld->lb_call_ != nullptr);
if (grpc_lb_glb_trace.enabled()) {
@ -1283,7 +1283,7 @@ void GrpcLb::ProcessChannelArgsLocked(const grpc_channel_args& args) {
return;
}
const grpc_lb_addresses* addresses =
reinterpret_cast<const grpc_lb_addresses*>(arg->value.pointer.p);
static_cast<const grpc_lb_addresses*>(arg->value.pointer.p);
// Update fallback address list.
if (fallback_backend_addresses_ != nullptr) {
grpc_lb_addresses_destroy(fallback_backend_addresses_);
@ -1426,7 +1426,7 @@ void GrpcLb::StartBalancerCallRetryTimerLocked() {
}
void GrpcLb::OnBalancerCallRetryTimerLocked(void* arg, grpc_error* error) {
GrpcLb* grpclb_policy = reinterpret_cast<GrpcLb*>(arg);
GrpcLb* grpclb_policy = static_cast<GrpcLb*>(arg);
grpclb_policy->retry_timer_callback_pending_ = false;
if (!grpclb_policy->shutting_down_ && error == GRPC_ERROR_NONE &&
grpclb_policy->lb_calld_ == nullptr) {
@ -1503,8 +1503,7 @@ grpc_error* AddLbTokenToInitialMetadata(
// Destroy function used when embedding client stats in call context.
void DestroyClientStats(void* arg) {
grpc_grpclb_client_stats_unref(
reinterpret_cast<grpc_grpclb_client_stats*>(arg));
grpc_grpclb_client_stats_unref(static_cast<grpc_grpclb_client_stats*>(arg));
}
void GrpcLb::PendingPickSetMetadataAndContext(PendingPick* pp) {
@ -1540,7 +1539,7 @@ void GrpcLb::PendingPickSetMetadataAndContext(PendingPick* pp) {
* reference to its associated round robin instance. We wrap this closure in
* order to unref the round robin instance upon its invocation */
void GrpcLb::OnPendingPickComplete(void* arg, grpc_error* error) {
PendingPick* pp = reinterpret_cast<PendingPick*>(arg);
PendingPick* pp = static_cast<PendingPick*>(arg);
PendingPickSetMetadataAndContext(pp);
GRPC_CLOSURE_SCHED(pp->original_on_complete, GRPC_ERROR_REF(error));
Delete(pp);
@ -1739,7 +1738,7 @@ void GrpcLb::CreateOrUpdateRoundRobinPolicyLocked() {
void GrpcLb::OnRoundRobinRequestReresolutionLocked(void* arg,
grpc_error* error) {
GrpcLb* grpclb_policy = reinterpret_cast<GrpcLb*>(arg);
GrpcLb* grpclb_policy = static_cast<GrpcLb*>(arg);
if (grpclb_policy->shutting_down_ || error != GRPC_ERROR_NONE) {
grpclb_policy->Unref(DEBUG_LOCATION, "on_rr_reresolution_requested");
return;
@ -1820,7 +1819,7 @@ void GrpcLb::UpdateConnectivityStateFromRoundRobinPolicyLocked(
void GrpcLb::OnRoundRobinConnectivityChangedLocked(void* arg,
grpc_error* error) {
GrpcLb* grpclb_policy = reinterpret_cast<GrpcLb*>(arg);
GrpcLb* grpclb_policy = static_cast<GrpcLb*>(arg);
if (grpclb_policy->shutting_down_) {
grpclb_policy->Unref(DEBUG_LOCATION, "on_rr_connectivity_changed");
return;
@ -1848,7 +1847,7 @@ class GrpcLbFactory : public LoadBalancingPolicyFactory {
return nullptr;
}
grpc_lb_addresses* addresses =
reinterpret_cast<grpc_lb_addresses*>(arg->value.pointer.p);
static_cast<grpc_lb_addresses*>(arg->value.pointer.p);
size_t num_grpclb_addrs = 0;
for (size_t i = 0; i < addresses->num_addresses; ++i) {
if (addresses->addresses[i].is_balancer) ++num_grpclb_addrs;

@ -393,8 +393,8 @@ void PickFirst::UpdateLocked(const grpc_channel_args& args) {
}
void PickFirst::OnConnectivityChangedLocked(void* arg, grpc_error* error) {
grpc_lb_subchannel_data* sd = reinterpret_cast<grpc_lb_subchannel_data*>(arg);
PickFirst* p = reinterpret_cast<PickFirst*>(sd->subchannel_list->policy);
grpc_lb_subchannel_data* sd = static_cast<grpc_lb_subchannel_data*>(arg);
PickFirst* p = static_cast<PickFirst*>(sd->subchannel_list->policy);
if (grpc_lb_pick_first_trace.enabled()) {
gpr_log(GPR_DEBUG,
"Pick First %p connectivity changed for subchannel %p (%" PRIuPTR

@ -412,8 +412,8 @@ void RoundRobin::UpdateConnectivityStatusLocked(grpc_lb_subchannel_data* sd,
}
void RoundRobin::OnConnectivityChangedLocked(void* arg, grpc_error* error) {
grpc_lb_subchannel_data* sd = reinterpret_cast<grpc_lb_subchannel_data*>(arg);
RoundRobin* p = reinterpret_cast<RoundRobin*>(sd->subchannel_list->policy);
grpc_lb_subchannel_data* sd = static_cast<grpc_lb_subchannel_data*>(arg);
RoundRobin* p = static_cast<RoundRobin*>(sd->subchannel_list->policy);
if (grpc_lb_round_robin_trace.enabled()) {
gpr_log(
GPR_DEBUG,

@ -156,7 +156,7 @@ class PolymorphicManualConstructor {
static_assert(
manual_ctor_impl::is_one_of<DerivedType, DerivedTypes...>::value,
"DerivedType must be one of the predeclared DerivedTypes");
GPR_ASSERT(reinterpret_cast<BaseType*>(static_cast<DerivedType*>(p)) == p);
GPR_ASSERT(static_cast<BaseType*>(p) == p);
}
typename std::aligned_storage<

@ -365,7 +365,7 @@ error:
}
static void do_read(void* arg, grpc_error* error) {
grpc_udp_listener* sp = reinterpret_cast<grpc_udp_listener*>(arg);
grpc_udp_listener* sp = static_cast<grpc_udp_listener*>(arg);
GPR_ASSERT(sp->read_cb && error == GRPC_ERROR_NONE);
/* TODO: the reason we hold server->mu here is merely to prevent fd
* shutdown while we are reading. However, it blocks do_write(). Switch to
@ -419,7 +419,7 @@ static void on_read(void* arg, grpc_error* error) {
// Wrapper of grpc_fd_notify_on_write() with a grpc_closure callback interface.
void fd_notify_on_write_wrapper(void* arg, grpc_error* error) {
grpc_udp_listener* sp = reinterpret_cast<grpc_udp_listener*>(arg);
grpc_udp_listener* sp = static_cast<grpc_udp_listener*>(arg);
gpr_mu_lock(&sp->server->mu);
if (!sp->notify_on_write_armed) {
grpc_fd_notify_on_write(sp->emfd, &sp->write_closure);
@ -429,7 +429,7 @@ void fd_notify_on_write_wrapper(void* arg, grpc_error* error) {
}
static void do_write(void* arg, grpc_error* error) {
grpc_udp_listener* sp = reinterpret_cast<grpc_udp_listener*>(arg);
grpc_udp_listener* sp = static_cast<grpc_udp_listener*>(arg);
gpr_mu_lock(&sp->server->mu);
if (sp->already_shutdown) {
// If fd has been shutdown, don't write any more and re-arm notification.

@ -0,0 +1,119 @@
/*
*
* 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/lib/security/credentials/alts/alts_credentials.h"
#include <cstring>
#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include "src/core/lib/security/credentials/alts/check_gcp_environment.h"
#include "src/core/lib/security/security_connector/alts_security_connector.h"
#define GRPC_CREDENTIALS_TYPE_ALTS "Alts"
#define GRPC_ALTS_HANDSHAKER_SERVICE_URL "metadata.google.internal:8080"
static void alts_credentials_destruct(grpc_channel_credentials* creds) {
grpc_alts_credentials* alts_creds =
reinterpret_cast<grpc_alts_credentials*>(creds);
grpc_alts_credentials_options_destroy(alts_creds->options);
gpr_free(alts_creds->handshaker_service_url);
}
static void alts_server_credentials_destruct(grpc_server_credentials* creds) {
grpc_alts_server_credentials* alts_creds =
reinterpret_cast<grpc_alts_server_credentials*>(creds);
grpc_alts_credentials_options_destroy(alts_creds->options);
gpr_free(alts_creds->handshaker_service_url);
}
static grpc_security_status alts_create_security_connector(
grpc_channel_credentials* creds,
grpc_call_credentials* request_metadata_creds, const char* target_name,
const grpc_channel_args* args, grpc_channel_security_connector** sc,
grpc_channel_args** new_args) {
return grpc_alts_channel_security_connector_create(
creds, request_metadata_creds, target_name, sc);
}
static grpc_security_status alts_server_create_security_connector(
grpc_server_credentials* creds, grpc_server_security_connector** sc) {
return grpc_alts_server_security_connector_create(creds, sc);
}
static const grpc_channel_credentials_vtable alts_credentials_vtable = {
alts_credentials_destruct, alts_create_security_connector,
/*duplicate_without_call_credentials=*/nullptr};
static const grpc_server_credentials_vtable alts_server_credentials_vtable = {
alts_server_credentials_destruct, alts_server_create_security_connector};
grpc_channel_credentials* grpc_alts_credentials_create_customized(
const grpc_alts_credentials_options* options,
const char* handshaker_service_url, bool enable_untrusted_alts) {
if (!enable_untrusted_alts && !grpc_alts_is_running_on_gcp()) {
return nullptr;
}
auto creds = static_cast<grpc_alts_credentials*>(
gpr_zalloc(sizeof(grpc_alts_credentials)));
creds->options = grpc_alts_credentials_options_copy(options);
creds->handshaker_service_url =
handshaker_service_url == nullptr
? gpr_strdup(GRPC_ALTS_HANDSHAKER_SERVICE_URL)
: gpr_strdup(handshaker_service_url);
creds->base.type = GRPC_CREDENTIALS_TYPE_ALTS;
creds->base.vtable = &alts_credentials_vtable;
gpr_ref_init(&creds->base.refcount, 1);
return &creds->base;
}
grpc_server_credentials* grpc_alts_server_credentials_create_customized(
const grpc_alts_credentials_options* options,
const char* handshaker_service_url, bool enable_untrusted_alts) {
if (!enable_untrusted_alts && !grpc_alts_is_running_on_gcp()) {
return nullptr;
}
auto creds = static_cast<grpc_alts_server_credentials*>(
gpr_zalloc(sizeof(grpc_alts_server_credentials)));
creds->options = grpc_alts_credentials_options_copy(options);
creds->handshaker_service_url =
handshaker_service_url == nullptr
? gpr_strdup(GRPC_ALTS_HANDSHAKER_SERVICE_URL)
: gpr_strdup(handshaker_service_url);
creds->base.type = GRPC_CREDENTIALS_TYPE_ALTS;
creds->base.vtable = &alts_server_credentials_vtable;
gpr_ref_init(&creds->base.refcount, 1);
return &creds->base;
}
grpc_channel_credentials* grpc_alts_credentials_create(
const grpc_alts_credentials_options* options) {
return grpc_alts_credentials_create_customized(
options, GRPC_ALTS_HANDSHAKER_SERVICE_URL, false);
}
grpc_server_credentials* grpc_alts_server_credentials_create(
const grpc_alts_credentials_options* options) {
return grpc_alts_server_credentials_create_customized(
options, GRPC_ALTS_HANDSHAKER_SERVICE_URL, false);
}

@ -0,0 +1,102 @@
/*
*
* 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.
*
*/
#ifndef GRPC_CORE_LIB_SECURITY_CREDENTIALS_ALTS_ALTS_CREDENTIALS_H
#define GRPC_CORE_LIB_SECURITY_CREDENTIALS_ALTS_ALTS_CREDENTIALS_H
#include <grpc/support/port_platform.h>
#include <grpc/grpc_security.h>
#include "src/core/lib/security/credentials/alts/grpc_alts_credentials_options.h"
#include "src/core/lib/security/credentials/credentials.h"
/* Main struct for grpc ALTS channel credential. */
typedef struct grpc_alts_credentials {
grpc_channel_credentials base;
grpc_alts_credentials_options* options;
char* handshaker_service_url;
} grpc_alts_credentials;
/* Main struct for grpc ALTS server credential. */
typedef struct grpc_alts_server_credentials {
grpc_server_credentials base;
grpc_alts_credentials_options* options;
char* handshaker_service_url;
} grpc_alts_server_credentials;
/**
* This method creates an ALTS channel credential object.
*
* - options: grpc ALTS credentials options instance for client.
*
* It returns the created ALTS channel credential object.
*/
grpc_channel_credentials* grpc_alts_credentials_create(
const grpc_alts_credentials_options* options);
/**
* This method creates an ALTS server credential object.
*
* - options: grpc ALTS credentials options instance for server.
*
* It returns the created ALTS server credential object.
*/
grpc_server_credentials* grpc_alts_server_credentials_create(
const grpc_alts_credentials_options* options);
/**
* This method creates an ALTS channel credential object with customized
* information provided by caller.
*
* - options: grpc ALTS credentials options instance for client.
* - handshaker_service_url: address of ALTS handshaker service in the format of
* "host:port". If it's nullptr, the address of default metadata server will
* be used.
* - enable_untrusted_alts: a boolean flag used to enable ALTS in untrusted
* mode. This mode can be enabled when we are sure ALTS is running on GCP or
* for testing purpose.
*
* It returns nullptr if the flag is disabled AND ALTS is not running on GCP.
* Otherwise, it returns the created credential object.
*/
grpc_channel_credentials* grpc_alts_credentials_create_customized(
const grpc_alts_credentials_options* options,
const char* handshaker_service_url, bool enable_untrusted_alts);
/**
* This method creates an ALTS server credential object with customized
* information provided by caller.
*
* - options: grpc ALTS credentials options instance for server.
* - handshaker_service_url: address of ALTS handshaker service in the format of
* "host:port". If it's nullptr, the address of default metadata server will
* be used.
* - enable_untrusted_alts: a boolean flag used to enable ALTS in untrusted
* mode. This mode can be enabled when we are sure ALTS is running on GCP or
* for testing purpose.
*
* It returns nullptr if the flag is disabled and ALTS is not running on GCP.
* Otherwise, it returns the created credential object.
*/
grpc_server_credentials* grpc_alts_server_credentials_create_customized(
const grpc_alts_credentials_options* options,
const char* handshaker_service_url, bool enable_untrusted_alts);
#endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_ALTS_ALTS_CREDENTIALS_H */

@ -0,0 +1,72 @@
/*
*
* 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/lib/security/credentials/alts/check_gcp_environment.h"
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
const size_t kBiosDataBufferSize = 256;
static char* trim(const char* src) {
if (src == nullptr) {
return nullptr;
}
char* des = nullptr;
size_t start = 0, end = strlen(src) - 1;
/* find the last character that is not a whitespace. */
while (end != 0 && isspace(src[end])) {
end--;
}
/* find the first character that is not a whitespace. */
while (start < strlen(src) && isspace(src[start])) {
start++;
}
if (start <= end) {
des = static_cast<char*>(
gpr_zalloc(sizeof(char) * (end - start + 2 /* '\0' */)));
memcpy(des, src + start, end - start + 1);
}
return des;
}
namespace grpc_core {
namespace internal {
char* read_bios_file(const char* bios_file) {
FILE* fp = fopen(bios_file, "r");
if (!fp) {
gpr_log(GPR_ERROR, "BIOS data file cannot be opened.");
return nullptr;
}
char buf[kBiosDataBufferSize + 1];
size_t ret = fread(buf, sizeof(char), kBiosDataBufferSize, fp);
buf[ret] = '\0';
char* trimmed_buf = trim(buf);
fclose(fp);
return trimmed_buf;
}
} // namespace internal
} // namespace grpc_core

@ -0,0 +1,57 @@
/*
*
* 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.
*
*/
#ifndef GRPC_CORE_LIB_SECURITY_CREDENTIALS_ALTS_CHECK_GCP_ENVIRONMENT_H
#define GRPC_CORE_LIB_SECURITY_CREDENTIALS_ALTS_CHECK_GCP_ENVIRONMENT_H
namespace grpc_core {
namespace internal {
/**
* This method is a helper function that reads a file containing system bios
* data. Exposed for testing only.
*
* - bios_file: a file containing BIOS data used to determine GCE tenancy
* information.
*
* It returns a buffer containing the data read from the file.
*/
char* read_bios_file(const char* bios_file);
/**
* This method checks if system BIOS data contains Google-specific phrases.
* Exposed for testing only.
*
* - bios_data: a buffer containing system BIOS data.
*
* It returns true if the BIOS data contains Google-specific phrases, and false
* otherwise.
*/
bool check_bios_data(const char* bios_data);
} // namespace internal
} // namespace grpc_core
/**
* This method checks if a VM (Windows or Linux) is running within Google
* compute Engine (GCE) or not. It returns true if the VM is running in GCE and
* false otherwise.
*/
bool grpc_alts_is_running_on_gcp();
#endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_ALTS_CHECK_GCP_ENVIRONMENT_H */

@ -0,0 +1,67 @@
/*
*
* 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>
#ifdef GPR_LINUX
#include "src/core/lib/security/credentials/alts/check_gcp_environment.h"
#include <grpc/support/alloc.h>
#include <grpc/support/sync.h>
#include <string.h>
#define GRPC_ALTS_EXPECT_NAME_GOOGLE "Google"
#define GRPC_ALTS_EXPECT_NAME_GCE "Google Compute Engine"
#define GRPC_ALTS_PRODUCT_NAME_FILE "/sys/class/dmi/id/product_name"
static bool g_compute_engine_detection_done = false;
static bool g_is_on_compute_engine = false;
static gpr_mu g_mu;
static gpr_once g_once = GPR_ONCE_INIT;
namespace grpc_core {
namespace internal {
bool check_bios_data(const char* bios_data_file) {
char* bios_data = read_bios_file(bios_data_file);
bool result = (!strcmp(bios_data, GRPC_ALTS_EXPECT_NAME_GOOGLE)) ||
(!strcmp(bios_data, GRPC_ALTS_EXPECT_NAME_GCE));
gpr_free(bios_data);
return result;
}
} // namespace internal
} // namespace grpc_core
static void init_mu(void) { gpr_mu_init(&g_mu); }
bool grpc_alts_is_running_on_gcp() {
gpr_once_init(&g_once, init_mu);
gpr_mu_lock(&g_mu);
if (!g_compute_engine_detection_done) {
g_is_on_compute_engine =
grpc_core::internal::check_bios_data(GRPC_ALTS_PRODUCT_NAME_FILE);
g_compute_engine_detection_done = true;
}
gpr_mu_unlock(&g_mu);
return g_is_on_compute_engine;
}
#endif // GPR_LINUX

@ -0,0 +1,33 @@
/*
*
* 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>
#if !defined(GPR_LINUX) && !defined(GPR_WINDOWS)
#include "src/core/lib/security/credentials/alts/check_gcp_environment.h"
#include <grpc/support/log.h>
bool grpc_alts_is_running_on_gcp() {
gpr_log(GPR_ERROR,
"Platforms other than Linux and Windows are not supported");
return false;
}
#endif // !defined(LINUX) && !defined(GPR_WINDOWS)

@ -0,0 +1,114 @@
/*
*
* 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>
#ifdef GPR_WINDOWS
#include "src/core/lib/security/credentials/alts/check_gcp_environment.h"
#include <shellapi.h>
#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
#define GRPC_ALTS_EXPECT_NAME_GOOGLE "Google"
#define GRPC_ALTS_WINDOWS_CHECK_COMMAND "powershell.exe"
#define GRPC_ALTS_WINDOWS_CHECK_COMMAND_ARGS \
"(Get-WmiObject -Class Win32_BIOS).Manufacturer"
#define GRPC_ALTS_WINDOWS_CHECK_BIOS_FILE "windows_bios.data"
const size_t kBiosDataBufferSize = 256;
static bool g_compute_engine_detection_done = false;
static bool g_is_on_compute_engine = false;
static gpr_mu g_mu;
static gpr_once g_once = GPR_ONCE_INIT;
namespace grpc_core {
namespace internal {
bool check_bios_data(const char* bios_data_file) {
char* bios_data = read_bios_file(bios_data_file);
bool result = !strcmp(bios_data, GRPC_ALTS_EXPECT_NAME_GOOGLE);
remove(GRPC_ALTS_WINDOWS_CHECK_BIOS_FILE);
gpr_free(bios_data);
return result;
}
} // namespace internal
} // namespace grpc_core
static void init_mu(void) { gpr_mu_init(&g_mu); }
static bool run_powershell() {
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(sa);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
HANDLE h = CreateFile(_T(GRPC_ALTS_WINDOWS_CHECK_BIOS_FILE), GENERIC_WRITE,
FILE_SHARE_WRITE | FILE_SHARE_READ, &sa, OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);
if (h == INVALID_HANDLE_VALUE) {
gpr_log(GPR_ERROR, "CreateFile failed (%d).", GetLastError());
return false;
}
PROCESS_INFORMATION pi;
STARTUPINFO si;
DWORD flags = CREATE_NO_WINDOW;
ZeroMemory(&pi, sizeof(pi));
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
si.dwFlags |= STARTF_USESTDHANDLES;
si.hStdInput = NULL;
si.hStdError = h;
si.hStdOutput = h;
TCHAR cmd[kBiosDataBufferSize];
_sntprintf(cmd, kBiosDataBufferSize, _T("%s %s"),
_T(GRPC_ALTS_WINDOWS_CHECK_COMMAND),
_T(GRPC_ALTS_WINDOWS_CHECK_COMMAND_ARGS));
if (!CreateProcess(NULL, cmd, NULL, NULL, TRUE, flags, NULL, NULL, &si,
&pi)) {
gpr_log(GPR_ERROR, "CreateProcess failed (%d).\n", GetLastError());
return false;
}
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
CloseHandle(h);
return true;
}
bool grpc_alts_is_running_on_gcp() {
gpr_once_init(&g_once, init_mu);
gpr_mu_lock(&g_mu);
if (!g_compute_engine_detection_done) {
g_is_on_compute_engine =
run_powershell() &&
grpc_core::internal::check_bios_data(GRPC_ALTS_WINDOWS_CHECK_BIOS_FILE);
g_compute_engine_detection_done = true;
}
gpr_mu_unlock(&g_mu);
return g_is_on_compute_engine;
}
#endif // GPR_WINDOWS

@ -0,0 +1,126 @@
/*
*
* 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 <stdlib.h>
#include <string.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include "src/core/lib/security/credentials/alts/grpc_alts_credentials_options.h"
#include "src/core/tsi/alts/handshaker/transport_security_common_api.h"
static grpc_alts_credentials_options* alts_client_options_copy(
const grpc_alts_credentials_options* options);
static void alts_client_options_destroy(grpc_alts_credentials_options* options);
static target_service_account* target_service_account_create(
const char* service_account) {
if (service_account == nullptr) {
return nullptr;
}
auto* sa = static_cast<target_service_account*>(
gpr_zalloc(sizeof(target_service_account)));
sa->data = gpr_strdup(service_account);
return sa;
}
bool grpc_alts_credentials_client_options_add_target_service_account(
grpc_alts_credentials_client_options* options,
const char* service_account) {
if (options == nullptr || service_account == nullptr) {
gpr_log(
GPR_ERROR,
"Invalid nullptr arguments to "
"grpc_alts_credentials_client_options_add_target_service_account()");
return false;
}
target_service_account* node = target_service_account_create(service_account);
node->next = options->target_account_list_head;
options->target_account_list_head = node;
return true;
}
static void target_service_account_destroy(
target_service_account* service_account) {
if (service_account == nullptr) {
return;
}
gpr_free(service_account->data);
gpr_free(service_account);
}
static const grpc_alts_credentials_options_vtable vtable = {
alts_client_options_copy, alts_client_options_destroy};
grpc_alts_credentials_options* grpc_alts_credentials_client_options_create() {
auto client_options = static_cast<grpc_alts_credentials_client_options*>(
gpr_zalloc(sizeof(grpc_alts_credentials_client_options)));
client_options->base.vtable = &vtable;
return &client_options->base;
}
static grpc_alts_credentials_options* alts_client_options_copy(
const grpc_alts_credentials_options* options) {
if (options == nullptr) {
return nullptr;
}
grpc_alts_credentials_options* new_options =
grpc_alts_credentials_client_options_create();
auto new_client_options =
reinterpret_cast<grpc_alts_credentials_client_options*>(new_options);
/* Copy target service accounts. */
target_service_account* prev = nullptr;
auto node =
(reinterpret_cast<const grpc_alts_credentials_client_options*>(options))
->target_account_list_head;
while (node != nullptr) {
target_service_account* new_node =
target_service_account_create(node->data);
if (prev == nullptr) {
new_client_options->target_account_list_head = new_node;
} else {
prev->next = new_node;
}
prev = new_node;
node = node->next;
}
/* Copy rpc protocol versions. */
grpc_gcp_rpc_protocol_versions_copy(&options->rpc_versions,
&new_options->rpc_versions);
return new_options;
}
static void alts_client_options_destroy(
grpc_alts_credentials_options* options) {
if (options == nullptr) {
return;
}
auto* client_options =
reinterpret_cast<grpc_alts_credentials_client_options*>(options);
target_service_account* node = client_options->target_account_list_head;
while (node != nullptr) {
target_service_account* next_node = node->next;
target_service_account_destroy(node);
node = next_node;
}
}

@ -0,0 +1,46 @@
/*
*
* 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/lib/security/credentials/alts/grpc_alts_credentials_options.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
grpc_alts_credentials_options* grpc_alts_credentials_options_copy(
const grpc_alts_credentials_options* options) {
if (options != nullptr && options->vtable != nullptr &&
options->vtable->copy != nullptr) {
return options->vtable->copy(options);
}
/* An error occurred. */
gpr_log(GPR_ERROR,
"Invalid arguments to grpc_alts_credentials_options_copy()");
return nullptr;
}
void grpc_alts_credentials_options_destroy(
grpc_alts_credentials_options* options) {
if (options != nullptr) {
if (options->vtable != nullptr && options->vtable->destruct != nullptr) {
options->vtable->destruct(options);
}
gpr_free(options);
}
}

@ -0,0 +1,112 @@
/*
*
* 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.
*
*/
#ifndef GRPC_CORE_LIB_SECURITY_CREDENTIALS_ALTS_GRPC_ALTS_CREDENTIALS_OPTIONS_H
#define GRPC_CORE_LIB_SECURITY_CREDENTIALS_ALTS_GRPC_ALTS_CREDENTIALS_OPTIONS_H
#include <grpc/support/port_platform.h>
#include <stdbool.h>
#include "src/core/tsi/alts/handshaker/transport_security_common_api.h"
/**
* Main interface for ALTS credentials options. The options will contain
* information that will be passed from grpc to TSI layer such as RPC protocol
* versions. ALTS client (channel) and server credentials will have their own
* implementation of this interface. The APIs listed in this header are
* thread-compatible.
*/
typedef struct grpc_alts_credentials_options grpc_alts_credentials_options;
/* V-table for grpc_alts_credentials_options */
typedef struct grpc_alts_credentials_options_vtable {
grpc_alts_credentials_options* (*copy)(
const grpc_alts_credentials_options* options);
void (*destruct)(grpc_alts_credentials_options* options);
} grpc_alts_credentials_options_vtable;
struct grpc_alts_credentials_options {
const struct grpc_alts_credentials_options_vtable* vtable;
grpc_gcp_rpc_protocol_versions rpc_versions;
};
typedef struct target_service_account {
struct target_service_account* next;
char* data;
} target_service_account;
/**
* Main struct for ALTS client credentials options. The options contain a
* a list of target service accounts (if specified) used for secure naming
* check.
*/
typedef struct grpc_alts_credentials_client_options {
grpc_alts_credentials_options base;
target_service_account* target_account_list_head;
} grpc_alts_credentials_client_options;
/**
* Main struct for ALTS server credentials options. The options currently
* do not contain any server-specific fields.
*/
typedef struct grpc_alts_credentials_server_options {
grpc_alts_credentials_options base;
} grpc_alts_credentials_server_options;
/**
* This method performs a deep copy on grpc_alts_credentials_options instance.
*
* - options: a grpc_alts_credentials_options instance that needs to be copied.
*
* It returns a new grpc_alts_credentials_options instance on success and NULL
* on failure.
*/
grpc_alts_credentials_options* grpc_alts_credentials_options_copy(
const grpc_alts_credentials_options* options);
/**
* This method destroys a grpc_alts_credentials_options instance by
* de-allocating all of its occupied memory.
*
* - options: a grpc_alts_credentials_options instance that needs to be
* destroyed.
*/
void grpc_alts_credentials_options_destroy(
grpc_alts_credentials_options* options);
/* This method creates a grpc ALTS credentials client options instance. */
grpc_alts_credentials_options* grpc_alts_credentials_client_options_create();
/* This method creates a grpc ALTS credentials server options instance. */
grpc_alts_credentials_options* grpc_alts_credentials_server_options_create();
/**
* This method adds a target service account to grpc ALTS credentials client
* options instance.
*
* - options: grpc ALTS credentials client options instance.
* - service_account: service account of target endpoint.
*
* It returns true on success and false on failure.
*/
bool grpc_alts_credentials_client_options_add_target_service_account(
grpc_alts_credentials_client_options* options, const char* service_account);
#endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_ALTS_GRPC_ALTS_CREDENTIALS_OPTIONS_H \
*/

@ -0,0 +1,58 @@
/*
*
* 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 <stdlib.h>
#include <string.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include "src/core/lib/security/credentials/alts/grpc_alts_credentials_options.h"
#include "src/core/tsi/alts/handshaker/transport_security_common_api.h"
static grpc_alts_credentials_options* alts_server_options_copy(
const grpc_alts_credentials_options* options);
static void alts_server_options_destroy(
grpc_alts_credentials_options* options) {}
static const grpc_alts_credentials_options_vtable vtable = {
alts_server_options_copy, alts_server_options_destroy};
grpc_alts_credentials_options* grpc_alts_credentials_server_options_create() {
grpc_alts_credentials_server_options* server_options =
static_cast<grpc_alts_credentials_server_options*>(
gpr_zalloc(sizeof(*server_options)));
server_options->base.vtable = &vtable;
return &server_options->base;
}
static grpc_alts_credentials_options* alts_server_options_copy(
const grpc_alts_credentials_options* options) {
if (options == nullptr) {
return nullptr;
}
grpc_alts_credentials_options* new_options =
grpc_alts_credentials_server_options_create();
/* Copy rpc protocol versions. */
grpc_gcp_rpc_protocol_versions_copy(&options->rpc_versions,
&new_options->rpc_versions);
return new_options;
}

@ -0,0 +1,287 @@
/*
*
* 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/lib/security/security_connector/alts_security_connector.h"
#include <stdbool.h>
#include <string.h>
#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include "src/core/lib/security/credentials/alts/alts_credentials.h"
#include "src/core/lib/security/transport/security_handshaker.h"
#include "src/core/lib/transport/transport.h"
#include "src/core/tsi/alts/handshaker/alts_tsi_handshaker.h"
typedef struct {
grpc_channel_security_connector base;
char* target_name;
} grpc_alts_channel_security_connector;
typedef struct {
grpc_server_security_connector base;
} grpc_alts_server_security_connector;
static void alts_channel_destroy(grpc_security_connector* sc) {
if (sc == nullptr) {
return;
}
auto c = reinterpret_cast<grpc_alts_channel_security_connector*>(sc);
grpc_call_credentials_unref(c->base.request_metadata_creds);
grpc_channel_credentials_unref(c->base.channel_creds);
gpr_free(c->target_name);
gpr_free(sc);
}
static void alts_server_destroy(grpc_security_connector* sc) {
if (sc == nullptr) {
return;
}
auto c = reinterpret_cast<grpc_alts_server_security_connector*>(sc);
grpc_server_credentials_unref(c->base.server_creds);
gpr_free(sc);
}
static void alts_channel_add_handshakers(
grpc_channel_security_connector* sc,
grpc_handshake_manager* handshake_manager) {
tsi_handshaker* handshaker = nullptr;
auto c = reinterpret_cast<grpc_alts_channel_security_connector*>(sc);
grpc_alts_credentials* creds =
reinterpret_cast<grpc_alts_credentials*>(c->base.channel_creds);
GPR_ASSERT(alts_tsi_handshaker_create(creds->options, c->target_name,
creds->handshaker_service_url, true,
&handshaker) == TSI_OK);
grpc_handshake_manager_add(handshake_manager, grpc_security_handshaker_create(
handshaker, &sc->base));
}
static void alts_server_add_handshakers(
grpc_server_security_connector* sc,
grpc_handshake_manager* handshake_manager) {
tsi_handshaker* handshaker = nullptr;
auto c = reinterpret_cast<grpc_alts_server_security_connector*>(sc);
grpc_alts_server_credentials* creds =
reinterpret_cast<grpc_alts_server_credentials*>(c->base.server_creds);
GPR_ASSERT(alts_tsi_handshaker_create(creds->options, nullptr,
creds->handshaker_service_url, false,
&handshaker) == TSI_OK);
grpc_handshake_manager_add(handshake_manager, grpc_security_handshaker_create(
handshaker, &sc->base));
}
static void alts_set_rpc_protocol_versions(
grpc_gcp_rpc_protocol_versions* rpc_versions) {
grpc_gcp_rpc_protocol_versions_set_max(rpc_versions,
GRPC_PROTOCOL_VERSION_MAX_MAJOR,
GRPC_PROTOCOL_VERSION_MAX_MINOR);
grpc_gcp_rpc_protocol_versions_set_min(rpc_versions,
GRPC_PROTOCOL_VERSION_MIN_MAJOR,
GRPC_PROTOCOL_VERSION_MIN_MINOR);
}
namespace grpc_core {
namespace internal {
grpc_security_status grpc_alts_auth_context_from_tsi_peer(
const tsi_peer* peer, grpc_auth_context** ctx) {
if (peer == nullptr || ctx == nullptr) {
gpr_log(GPR_ERROR,
"Invalid arguments to grpc_alts_auth_context_from_tsi_peer()");
return GRPC_SECURITY_ERROR;
}
*ctx = nullptr;
/* Validate certificate type. */
const tsi_peer_property* cert_type_prop =
tsi_peer_get_property_by_name(peer, TSI_CERTIFICATE_TYPE_PEER_PROPERTY);
if (cert_type_prop == nullptr ||
strncmp(cert_type_prop->value.data, TSI_ALTS_CERTIFICATE_TYPE,
cert_type_prop->value.length) != 0) {
gpr_log(GPR_ERROR, "Invalid or missing certificate type property.");
return GRPC_SECURITY_ERROR;
}
/* Validate RPC protocol versions. */
const tsi_peer_property* rpc_versions_prop =
tsi_peer_get_property_by_name(peer, TSI_ALTS_RPC_VERSIONS);
if (rpc_versions_prop == nullptr) {
gpr_log(GPR_ERROR, "Missing rpc protocol versions property.");
return GRPC_SECURITY_ERROR;
}
grpc_gcp_rpc_protocol_versions local_versions, peer_versions;
alts_set_rpc_protocol_versions(&local_versions);
grpc_slice slice = grpc_slice_from_copied_buffer(
rpc_versions_prop->value.data, rpc_versions_prop->value.length);
bool decode_result =
grpc_gcp_rpc_protocol_versions_decode(slice, &peer_versions);
grpc_slice_unref(slice);
if (!decode_result) {
gpr_log(GPR_ERROR, "Invalid peer rpc protocol versions.");
return GRPC_SECURITY_ERROR;
}
/* TODO: Pass highest common rpc protocol version to grpc caller. */
bool check_result = grpc_gcp_rpc_protocol_versions_check(
&local_versions, &peer_versions, nullptr);
if (!check_result) {
gpr_log(GPR_ERROR, "Mismatch of local and peer rpc protocol versions.");
return GRPC_SECURITY_ERROR;
}
/* Create auth context. */
*ctx = grpc_auth_context_create(nullptr);
grpc_auth_context_add_cstring_property(
*ctx, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME,
GRPC_ALTS_TRANSPORT_SECURITY_TYPE);
size_t i = 0;
for (i = 0; i < peer->property_count; i++) {
const tsi_peer_property* tsi_prop = &peer->properties[i];
/* Add service account to auth context. */
if (strcmp(tsi_prop->name, TSI_ALTS_SERVICE_ACCOUNT_PEER_PROPERTY) == 0) {
grpc_auth_context_add_property(
*ctx, TSI_ALTS_SERVICE_ACCOUNT_PEER_PROPERTY, tsi_prop->value.data,
tsi_prop->value.length);
GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name(
*ctx, TSI_ALTS_SERVICE_ACCOUNT_PEER_PROPERTY) == 1);
}
}
if (!grpc_auth_context_peer_is_authenticated(*ctx)) {
gpr_log(GPR_ERROR, "Invalid unauthenticated peer.");
GRPC_AUTH_CONTEXT_UNREF(*ctx, "test");
*ctx = nullptr;
return GRPC_SECURITY_ERROR;
}
return GRPC_SECURITY_OK;
}
} // namespace internal
} // namespace grpc_core
static void alts_check_peer(grpc_security_connector* sc, tsi_peer peer,
grpc_auth_context** auth_context,
grpc_closure* on_peer_checked) {
grpc_security_status status;
status = grpc_core::internal::grpc_alts_auth_context_from_tsi_peer(
&peer, auth_context);
tsi_peer_destruct(&peer);
grpc_error* error =
status == GRPC_SECURITY_OK
? GRPC_ERROR_NONE
: GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"Could not get ALTS auth context from TSI peer");
GRPC_CLOSURE_SCHED(on_peer_checked, error);
}
static int alts_channel_cmp(grpc_security_connector* sc1,
grpc_security_connector* sc2) {
grpc_alts_channel_security_connector* c1 =
reinterpret_cast<grpc_alts_channel_security_connector*>(sc1);
grpc_alts_channel_security_connector* c2 =
reinterpret_cast<grpc_alts_channel_security_connector*>(sc2);
int c = grpc_channel_security_connector_cmp(&c1->base, &c2->base);
if (c != 0) return c;
return strcmp(c1->target_name, c2->target_name);
}
static int alts_server_cmp(grpc_security_connector* sc1,
grpc_security_connector* sc2) {
grpc_alts_server_security_connector* c1 =
reinterpret_cast<grpc_alts_server_security_connector*>(sc1);
grpc_alts_server_security_connector* c2 =
reinterpret_cast<grpc_alts_server_security_connector*>(sc2);
return grpc_server_security_connector_cmp(&c1->base, &c2->base);
}
static grpc_security_connector_vtable alts_channel_vtable = {
alts_channel_destroy, alts_check_peer, alts_channel_cmp};
static grpc_security_connector_vtable alts_server_vtable = {
alts_server_destroy, alts_check_peer, alts_server_cmp};
static bool alts_check_call_host(grpc_channel_security_connector* sc,
const char* host,
grpc_auth_context* auth_context,
grpc_closure* on_call_host_checked,
grpc_error** error) {
grpc_alts_channel_security_connector* alts_sc =
reinterpret_cast<grpc_alts_channel_security_connector*>(sc);
if (host == nullptr || alts_sc == nullptr ||
strcmp(host, alts_sc->target_name) != 0) {
*error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"ALTS call host does not match target name");
}
return true;
}
static void alts_cancel_check_call_host(grpc_channel_security_connector* sc,
grpc_closure* on_call_host_checked,
grpc_error* error) {
GRPC_ERROR_UNREF(error);
}
grpc_security_status grpc_alts_channel_security_connector_create(
grpc_channel_credentials* channel_creds,
grpc_call_credentials* request_metadata_creds, const char* target_name,
grpc_channel_security_connector** sc) {
if (channel_creds == nullptr || sc == nullptr || target_name == nullptr) {
gpr_log(
GPR_ERROR,
"Invalid arguments to grpc_alts_channel_security_connector_create()");
return GRPC_SECURITY_ERROR;
}
auto c = static_cast<grpc_alts_channel_security_connector*>(
gpr_zalloc(sizeof(grpc_alts_channel_security_connector)));
gpr_ref_init(&c->base.base.refcount, 1);
c->base.base.vtable = &alts_channel_vtable;
c->base.add_handshakers = alts_channel_add_handshakers;
c->base.channel_creds = grpc_channel_credentials_ref(channel_creds);
c->base.request_metadata_creds =
grpc_call_credentials_ref(request_metadata_creds);
c->base.check_call_host = alts_check_call_host;
c->base.cancel_check_call_host = alts_cancel_check_call_host;
grpc_alts_credentials* creds =
reinterpret_cast<grpc_alts_credentials*>(c->base.channel_creds);
alts_set_rpc_protocol_versions(&creds->options->rpc_versions);
c->target_name = gpr_strdup(target_name);
*sc = &c->base;
return GRPC_SECURITY_OK;
}
grpc_security_status grpc_alts_server_security_connector_create(
grpc_server_credentials* server_creds,
grpc_server_security_connector** sc) {
if (server_creds == nullptr || sc == nullptr) {
gpr_log(
GPR_ERROR,
"Invalid arguments to grpc_alts_server_security_connector_create()");
return GRPC_SECURITY_ERROR;
}
auto c = static_cast<grpc_alts_server_security_connector*>(
gpr_zalloc(sizeof(grpc_alts_server_security_connector)));
gpr_ref_init(&c->base.base.refcount, 1);
c->base.base.vtable = &alts_server_vtable;
c->base.server_creds = grpc_server_credentials_ref(server_creds);
c->base.add_handshakers = alts_server_add_handshakers;
grpc_alts_server_credentials* creds =
reinterpret_cast<grpc_alts_server_credentials*>(c->base.server_creds);
alts_set_rpc_protocol_versions(&creds->options->rpc_versions);
*sc = &c->base;
return GRPC_SECURITY_OK;
}

@ -0,0 +1,69 @@
/*
*
* 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.
*
*/
#ifndef GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_ALTS_SECURITY_CONNECTOR_H
#define GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_ALTS_SECURITY_CONNECTOR_H
#include <grpc/support/port_platform.h>
#include "src/core/lib/security/context/security_context.h"
#include "src/core/lib/security/credentials/alts/grpc_alts_credentials_options.h"
#define GRPC_ALTS_TRANSPORT_SECURITY_TYPE "alts"
/**
* This method creates an ALTS channel security connector.
*
* - channel_creds: channel credential instance.
* - request_metadata_creds: credential object which will be sent with each
* request. This parameter can be nullptr.
* - target_name: the name of the endpoint that the channel is connecting to.
* - sc: address of ALTS channel security connector instance to be returned from
* the method.
*
* It returns GRPC_SECURITY_OK on success, and an error stauts code on failure.
*/
grpc_security_status grpc_alts_channel_security_connector_create(
grpc_channel_credentials* channel_creds,
grpc_call_credentials* request_metadata_creds, const char* target_name,
grpc_channel_security_connector** sc);
/**
* This method creates an ALTS server security connector.
*
* - server_creds: server credential instance.
* - sc: address of ALTS server security connector instance to be returned from
* the method.
*
* It returns GRPC_SECURITY_OK on success, and an error status code on failure.
*/
grpc_security_status grpc_alts_server_security_connector_create(
grpc_server_credentials* server_creds, grpc_server_security_connector** sc);
namespace grpc_core {
namespace internal {
/* Exposed only for testing. */
grpc_security_status grpc_alts_auth_context_from_tsi_peer(
const tsi_peer* peer, grpc_auth_context** ctx);
} // namespace internal
} // namespace grpc_core
#endif /* GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_ALTS_SECURITY_CONNECTOR_H \
*/

@ -52,14 +52,14 @@ struct ChannelData {
};
static void fill_metadata(grpc_call_element* elem, grpc_metadata_batch* mdb) {
CallData* calld = reinterpret_cast<CallData*>(elem->call_data);
CallData* calld = static_cast<CallData*>(elem->call_data);
bool expected = false;
if (!calld->filled_metadata.compare_exchange_strong(
expected, true, grpc_core::memory_order_relaxed,
grpc_core::memory_order_relaxed)) {
return;
}
ChannelData* chand = reinterpret_cast<ChannelData*>(elem->channel_data);
ChannelData* chand = static_cast<ChannelData*>(elem->channel_data);
char tmp[GPR_LTOA_MIN_BUFSIZE];
gpr_ltoa(chand->error_code, tmp);
calld->status.md = grpc_mdelem_from_slices(
@ -78,7 +78,7 @@ static void fill_metadata(grpc_call_element* elem, grpc_metadata_batch* mdb) {
static void lame_start_transport_stream_op_batch(
grpc_call_element* elem, grpc_transport_stream_op_batch* op) {
CallData* calld = reinterpret_cast<CallData*>(elem->call_data);
CallData* calld = static_cast<CallData*>(elem->call_data);
if (op->recv_initial_metadata) {
fill_metadata(elem,
op->payload->recv_initial_metadata.recv_initial_metadata);
@ -119,7 +119,7 @@ static void lame_start_transport_op(grpc_channel_element* elem,
static grpc_error* init_call_elem(grpc_call_element* elem,
const grpc_call_element_args* args) {
CallData* calld = reinterpret_cast<CallData*>(elem->call_data);
CallData* calld = static_cast<CallData*>(elem->call_data);
calld->call_combiner = args->call_combiner;
return GRPC_ERROR_NONE;
}
@ -172,7 +172,7 @@ grpc_channel* grpc_lame_client_channel_create(const char* target,
"error_message=%s)",
3, (target, (int)error_code, error_message));
GPR_ASSERT(elem->filter == &grpc_lame_filter);
auto chand = reinterpret_cast<grpc_core::ChannelData*>(elem->channel_data);
auto chand = static_cast<grpc_core::ChannelData*>(elem->channel_data);
chand->error_code = error_code;
chand->error_message = error_message;

@ -24,12 +24,12 @@ void grpc_http_filters_init(void);
void grpc_http_filters_shutdown(void);
void grpc_chttp2_plugin_init(void);
void grpc_chttp2_plugin_shutdown(void);
void grpc_tsi_alts_init(void);
void grpc_tsi_alts_shutdown(void);
void grpc_deadline_filter_init(void);
void grpc_deadline_filter_shutdown(void);
void grpc_client_channel_init(void);
void grpc_client_channel_shutdown(void);
void grpc_tsi_alts_init(void);
void grpc_tsi_alts_shutdown(void);
void grpc_inproc_plugin_init(void);
void grpc_inproc_plugin_shutdown(void);
void grpc_resolver_fake_init(void);
@ -60,12 +60,12 @@ void grpc_register_built_in_plugins(void) {
grpc_http_filters_shutdown);
grpc_register_plugin(grpc_chttp2_plugin_init,
grpc_chttp2_plugin_shutdown);
grpc_register_plugin(grpc_tsi_alts_init,
grpc_tsi_alts_shutdown);
grpc_register_plugin(grpc_deadline_filter_init,
grpc_deadline_filter_shutdown);
grpc_register_plugin(grpc_client_channel_init,
grpc_client_channel_shutdown);
grpc_register_plugin(grpc_tsi_alts_init,
grpc_tsi_alts_shutdown);
grpc_register_plugin(grpc_inproc_plugin_init,
grpc_inproc_plugin_shutdown);
grpc_register_plugin(grpc_resolver_fake_init,

@ -0,0 +1,687 @@
/*
*
* 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/crypt/gsec.h"
#include <openssl/bio.h>
#include <openssl/buffer.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <string.h>
#include <grpc/support/alloc.h>
constexpr size_t kKdfKeyLen = 32;
constexpr size_t kKdfCounterLen = 6;
constexpr size_t kKdfCounterOffset = 2;
constexpr size_t kRekeyAeadKeyLen = kAes128GcmKeyLength;
/* Struct for additional data required if rekeying is enabled. */
struct gsec_aes_gcm_aead_rekey_data {
uint8_t kdf_counter[kKdfCounterLen];
uint8_t nonce_mask[kAesGcmNonceLength];
};
/* Main struct for AES_GCM crypter interface. */
struct gsec_aes_gcm_aead_crypter {
gsec_aead_crypter crypter;
size_t key_length;
size_t nonce_length;
size_t tag_length;
uint8_t* key;
gsec_aes_gcm_aead_rekey_data* rekey_data;
EVP_CIPHER_CTX* ctx;
};
static char* aes_gcm_get_openssl_errors() {
BIO* bio = BIO_new(BIO_s_mem());
ERR_print_errors(bio);
BUF_MEM* mem = nullptr;
char* error_msg = nullptr;
BIO_get_mem_ptr(bio, &mem);
if (mem != nullptr) {
error_msg = static_cast<char*>(gpr_malloc(mem->length + 1));
memcpy(error_msg, mem->data, mem->length);
error_msg[mem->length] = '\0';
}
BIO_free_all(bio);
return error_msg;
}
static void aes_gcm_format_errors(const char* error_msg, char** error_details) {
if (error_details == nullptr) {
return;
}
unsigned long error = ERR_get_error();
if (error == 0 && error_msg != nullptr) {
*error_details = static_cast<char*>(gpr_malloc(strlen(error_msg) + 1));
memcpy(*error_details, error_msg, strlen(error_msg) + 1);
return;
}
char* openssl_errors = aes_gcm_get_openssl_errors();
if (openssl_errors != nullptr && error_msg != nullptr) {
size_t len = strlen(error_msg) + strlen(openssl_errors) + 2; /* ", " */
*error_details = static_cast<char*>(gpr_malloc(len + 1));
snprintf(*error_details, len + 1, "%s, %s", error_msg, openssl_errors);
gpr_free(openssl_errors);
}
}
static grpc_status_code gsec_aes_gcm_aead_crypter_max_ciphertext_and_tag_length(
const gsec_aead_crypter* crypter, size_t plaintext_length,
size_t* max_ciphertext_and_tag_length, char** error_details) {
if (max_ciphertext_and_tag_length == nullptr) {
aes_gcm_format_errors("max_ciphertext_and_tag_length is nullptr.",
error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
gsec_aes_gcm_aead_crypter* aes_gcm_crypter =
reinterpret_cast<gsec_aes_gcm_aead_crypter*>(
const_cast<gsec_aead_crypter*>(crypter));
*max_ciphertext_and_tag_length =
plaintext_length + aes_gcm_crypter->tag_length;
return GRPC_STATUS_OK;
}
static grpc_status_code gsec_aes_gcm_aead_crypter_max_plaintext_length(
const gsec_aead_crypter* crypter, size_t ciphertext_and_tag_length,
size_t* max_plaintext_length, char** error_details) {
if (max_plaintext_length == nullptr) {
aes_gcm_format_errors("max_plaintext_length is nullptr.", error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
gsec_aes_gcm_aead_crypter* aes_gcm_crypter =
reinterpret_cast<gsec_aes_gcm_aead_crypter*>(
const_cast<gsec_aead_crypter*>(crypter));
if (ciphertext_and_tag_length < aes_gcm_crypter->tag_length) {
*max_plaintext_length = 0;
aes_gcm_format_errors(
"ciphertext_and_tag_length is smaller than tag_length.", error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
*max_plaintext_length =
ciphertext_and_tag_length - aes_gcm_crypter->tag_length;
return GRPC_STATUS_OK;
}
static grpc_status_code gsec_aes_gcm_aead_crypter_nonce_length(
const gsec_aead_crypter* crypter, size_t* nonce_length,
char** error_details) {
if (nonce_length == nullptr) {
aes_gcm_format_errors("nonce_length is nullptr.", error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
gsec_aes_gcm_aead_crypter* aes_gcm_crypter =
reinterpret_cast<gsec_aes_gcm_aead_crypter*>(
const_cast<gsec_aead_crypter*>(crypter));
*nonce_length = aes_gcm_crypter->nonce_length;
return GRPC_STATUS_OK;
}
static grpc_status_code gsec_aes_gcm_aead_crypter_key_length(
const gsec_aead_crypter* crypter, size_t* key_length,
char** error_details) {
if (key_length == nullptr) {
aes_gcm_format_errors("key_length is nullptr.", error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
gsec_aes_gcm_aead_crypter* aes_gcm_crypter =
reinterpret_cast<gsec_aes_gcm_aead_crypter*>(
const_cast<gsec_aead_crypter*>(crypter));
*key_length = aes_gcm_crypter->key_length;
return GRPC_STATUS_OK;
}
static grpc_status_code gsec_aes_gcm_aead_crypter_tag_length(
const gsec_aead_crypter* crypter, size_t* tag_length,
char** error_details) {
if (tag_length == nullptr) {
aes_gcm_format_errors("tag_length is nullptr.", error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
gsec_aes_gcm_aead_crypter* aes_gcm_crypter =
reinterpret_cast<gsec_aes_gcm_aead_crypter*>(
const_cast<gsec_aead_crypter*>(crypter));
*tag_length = aes_gcm_crypter->tag_length;
return GRPC_STATUS_OK;
}
static void aes_gcm_mask_nonce(uint8_t* dst, const uint8_t* nonce,
const uint8_t* mask) {
uint64_t mask1;
uint32_t mask2;
memcpy(&mask1, mask, sizeof(mask1));
memcpy(&mask2, mask + sizeof(mask1), sizeof(mask2));
uint64_t nonce1;
uint32_t nonce2;
memcpy(&nonce1, nonce, sizeof(nonce1));
memcpy(&nonce2, nonce + sizeof(nonce1), sizeof(nonce2));
nonce1 ^= mask1;
nonce2 ^= mask2;
memcpy(dst, &nonce1, sizeof(nonce1));
memcpy(dst + sizeof(nonce1), &nonce2, sizeof(nonce2));
}
static grpc_status_code aes_gcm_derive_aead_key(uint8_t* dst,
const uint8_t* kdf_key,
const uint8_t* kdf_counter) {
unsigned char buf[EVP_MAX_MD_SIZE];
unsigned char ctr = 1;
#if OPENSSL_VERSION_NUMBER < 0x10100000L
HMAC_CTX hmac;
HMAC_CTX_init(&hmac);
if (!HMAC_Init_ex(&hmac, kdf_key, kKdfKeyLen, EVP_sha256(), nullptr) ||
!HMAC_Update(&hmac, kdf_counter, kKdfCounterLen) ||
!HMAC_Update(&hmac, &ctr, 1) || !HMAC_Final(&hmac, buf, nullptr)) {
HMAC_CTX_cleanup(&hmac);
return GRPC_STATUS_INTERNAL;
}
HMAC_CTX_cleanup(&hmac);
#else
HMAC_CTX* hmac = HMAC_CTX_new();
if (hmac == nullptr) {
return GRPC_STATUS_INTERNAL;
}
if (!HMAC_Init_ex(hmac, kdf_key, kKdfKeyLen, EVP_sha256(), nullptr) ||
!HMAC_Update(hmac, kdf_counter, kKdfCounterLen) ||
!HMAC_Update(hmac, &ctr, 1) || !HMAC_Final(hmac, buf, nullptr)) {
HMAC_CTX_free(hmac);
return GRPC_STATUS_INTERNAL;
}
HMAC_CTX_free(hmac);
#endif
memcpy(dst, buf, kRekeyAeadKeyLen);
return GRPC_STATUS_OK;
}
static grpc_status_code aes_gcm_rekey_if_required(
gsec_aes_gcm_aead_crypter* aes_gcm_crypter, const uint8_t* nonce,
char** error_details) {
// If rekey_data is nullptr, then rekeying is not supported and not required.
// If bytes 2-7 of kdf_counter differ from the (per message) nonce, then the
// encryption key is recomputed from a new kdf_counter to ensure that we don't
// encrypt more than 2^16 messages per encryption key (in each direction).
if (aes_gcm_crypter->rekey_data == nullptr ||
memcmp(aes_gcm_crypter->rekey_data->kdf_counter,
nonce + kKdfCounterOffset, kKdfCounterLen) == 0) {
return GRPC_STATUS_OK;
}
memcpy(aes_gcm_crypter->rekey_data->kdf_counter, nonce + kKdfCounterOffset,
kKdfCounterLen);
uint8_t aead_key[kRekeyAeadKeyLen];
if (aes_gcm_derive_aead_key(aead_key, aes_gcm_crypter->key,
aes_gcm_crypter->rekey_data->kdf_counter) !=
GRPC_STATUS_OK) {
aes_gcm_format_errors("Rekeying failed in key derivation.", error_details);
return GRPC_STATUS_INTERNAL;
}
if (!EVP_DecryptInit_ex(aes_gcm_crypter->ctx, nullptr, nullptr, aead_key,
nullptr)) {
aes_gcm_format_errors("Rekeying failed in context update.", error_details);
return GRPC_STATUS_INTERNAL;
}
return GRPC_STATUS_OK;
}
static grpc_status_code gsec_aes_gcm_aead_crypter_encrypt_iovec(
gsec_aead_crypter* crypter, const uint8_t* nonce, size_t nonce_length,
const struct iovec* aad_vec, size_t aad_vec_length,
const struct iovec* plaintext_vec, size_t plaintext_vec_length,
struct iovec ciphertext_vec, size_t* ciphertext_bytes_written,
char** error_details) {
gsec_aes_gcm_aead_crypter* aes_gcm_crypter =
reinterpret_cast<gsec_aes_gcm_aead_crypter*>(crypter);
// Input checks
if (nonce == nullptr) {
aes_gcm_format_errors("Nonce buffer is nullptr.", error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
if (kAesGcmNonceLength != nonce_length) {
aes_gcm_format_errors("Nonce buffer has the wrong length.", error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
if (aad_vec_length > 0 && aad_vec == nullptr) {
aes_gcm_format_errors("Non-zero aad_vec_length but aad_vec is nullptr.",
error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
if (plaintext_vec_length > 0 && plaintext_vec == nullptr) {
aes_gcm_format_errors(
"Non-zero plaintext_vec_length but plaintext_vec is nullptr.",
error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
if (ciphertext_bytes_written == nullptr) {
aes_gcm_format_errors("bytes_written is nullptr.", error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
*ciphertext_bytes_written = 0;
// rekey if required
if (aes_gcm_rekey_if_required(aes_gcm_crypter, nonce, error_details) !=
GRPC_STATUS_OK) {
return GRPC_STATUS_INTERNAL;
}
// mask nonce if required
const uint8_t* nonce_aead = nonce;
uint8_t nonce_masked[kAesGcmNonceLength];
if (aes_gcm_crypter->rekey_data != nullptr) {
aes_gcm_mask_nonce(nonce_masked, aes_gcm_crypter->rekey_data->nonce_mask,
nonce);
nonce_aead = nonce_masked;
}
// init openssl context
if (!EVP_EncryptInit_ex(aes_gcm_crypter->ctx, nullptr, nullptr, nullptr,
nonce_aead)) {
aes_gcm_format_errors("Initializing nonce failed", error_details);
return GRPC_STATUS_INTERNAL;
}
// process aad
size_t i;
for (i = 0; i < aad_vec_length; i++) {
const uint8_t* aad = static_cast<uint8_t*>(aad_vec[i].iov_base);
size_t aad_length = aad_vec[i].iov_len;
if (aad_length == 0) {
continue;
}
size_t aad_bytes_read = 0;
if (aad == nullptr) {
aes_gcm_format_errors("aad is nullptr.", error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
if (!EVP_EncryptUpdate(aes_gcm_crypter->ctx, nullptr,
reinterpret_cast<int*>(&aad_bytes_read), aad,
static_cast<int>(aad_length)) ||
aad_bytes_read != aad_length) {
aes_gcm_format_errors("Setting authenticated associated data failed",
error_details);
return GRPC_STATUS_INTERNAL;
}
}
uint8_t* ciphertext = static_cast<uint8_t*>(ciphertext_vec.iov_base);
size_t ciphertext_length = ciphertext_vec.iov_len;
if (ciphertext == nullptr) {
aes_gcm_format_errors("ciphertext is nullptr.", error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
// process plaintext
for (i = 0; i < plaintext_vec_length; i++) {
const uint8_t* plaintext = static_cast<uint8_t*>(plaintext_vec[i].iov_base);
size_t plaintext_length = plaintext_vec[i].iov_len;
if (plaintext == nullptr) {
if (plaintext_length == 0) {
continue;
}
aes_gcm_format_errors("plaintext is nullptr.", error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
if (ciphertext_length < plaintext_length) {
aes_gcm_format_errors(
"ciphertext is not large enough to hold the result.", error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
int bytes_written = 0;
int bytes_to_write = static_cast<int>(plaintext_length);
if (!EVP_EncryptUpdate(aes_gcm_crypter->ctx, ciphertext, &bytes_written,
plaintext, bytes_to_write)) {
aes_gcm_format_errors("Encrypting plaintext failed.", error_details);
return GRPC_STATUS_INTERNAL;
}
if (bytes_written > bytes_to_write) {
aes_gcm_format_errors("More bytes written than expected.", error_details);
return GRPC_STATUS_INTERNAL;
}
ciphertext += bytes_written;
ciphertext_length -= bytes_written;
}
int bytes_written_temp = 0;
if (!EVP_EncryptFinal_ex(aes_gcm_crypter->ctx, nullptr,
&bytes_written_temp)) {
aes_gcm_format_errors("Finalizing encryption failed.", error_details);
return GRPC_STATUS_INTERNAL;
}
if (bytes_written_temp != 0) {
aes_gcm_format_errors("Openssl wrote some unexpected bytes.",
error_details);
return GRPC_STATUS_INTERNAL;
}
if (ciphertext_length < kAesGcmTagLength) {
aes_gcm_format_errors("ciphertext is too small to hold a tag.",
error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
if (!EVP_CIPHER_CTX_ctrl(aes_gcm_crypter->ctx, EVP_CTRL_GCM_GET_TAG,
kAesGcmTagLength, ciphertext)) {
aes_gcm_format_errors("Writing tag failed.", error_details);
return GRPC_STATUS_INTERNAL;
}
ciphertext += kAesGcmTagLength;
ciphertext_length -= kAesGcmTagLength;
*ciphertext_bytes_written = ciphertext_vec.iov_len - ciphertext_length;
return GRPC_STATUS_OK;
}
static grpc_status_code gsec_aes_gcm_aead_crypter_decrypt_iovec(
gsec_aead_crypter* crypter, const uint8_t* nonce, size_t nonce_length,
const struct iovec* aad_vec, size_t aad_vec_length,
const struct iovec* ciphertext_vec, size_t ciphertext_vec_length,
struct iovec plaintext_vec, size_t* plaintext_bytes_written,
char** error_details) {
gsec_aes_gcm_aead_crypter* aes_gcm_crypter =
reinterpret_cast<gsec_aes_gcm_aead_crypter*>(
const_cast<gsec_aead_crypter*>(crypter));
if (nonce == nullptr) {
aes_gcm_format_errors("Nonce buffer is nullptr.", error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
if (kAesGcmNonceLength != nonce_length) {
aes_gcm_format_errors("Nonce buffer has the wrong length.", error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
if (aad_vec_length > 0 && aad_vec == nullptr) {
aes_gcm_format_errors("Non-zero aad_vec_length but aad_vec is nullptr.",
error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
if (ciphertext_vec_length > 0 && ciphertext_vec == nullptr) {
aes_gcm_format_errors(
"Non-zero plaintext_vec_length but plaintext_vec is nullptr.",
error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
// Compute the total length so we can ensure we don't pass the tag into
// EVP_decrypt.
size_t total_ciphertext_length = 0;
size_t i;
for (i = 0; i < ciphertext_vec_length; i++) {
total_ciphertext_length += ciphertext_vec[i].iov_len;
}
if (total_ciphertext_length < kAesGcmTagLength) {
aes_gcm_format_errors("ciphertext is too small to hold a tag.",
error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
if (plaintext_bytes_written == nullptr) {
aes_gcm_format_errors("bytes_written is nullptr.", error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
*plaintext_bytes_written = 0;
// rekey if required
if (aes_gcm_rekey_if_required(aes_gcm_crypter, nonce, error_details) !=
GRPC_STATUS_OK) {
aes_gcm_format_errors("Rekeying failed.", error_details);
return GRPC_STATUS_INTERNAL;
}
// mask nonce if required
const uint8_t* nonce_aead = nonce;
uint8_t nonce_masked[kAesGcmNonceLength];
if (aes_gcm_crypter->rekey_data != nullptr) {
aes_gcm_mask_nonce(nonce_masked, aes_gcm_crypter->rekey_data->nonce_mask,
nonce);
nonce_aead = nonce_masked;
}
// init openssl context
if (!EVP_DecryptInit_ex(aes_gcm_crypter->ctx, nullptr, nullptr, nullptr,
nonce_aead)) {
aes_gcm_format_errors("Initializing nonce failed.", error_details);
return GRPC_STATUS_INTERNAL;
}
// process aad
for (i = 0; i < aad_vec_length; i++) {
const uint8_t* aad = static_cast<uint8_t*>(aad_vec[i].iov_base);
size_t aad_length = aad_vec[i].iov_len;
if (aad_length == 0) {
continue;
}
size_t aad_bytes_read = 0;
if (aad == nullptr) {
aes_gcm_format_errors("aad is nullptr.", error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
if (!EVP_DecryptUpdate(aes_gcm_crypter->ctx, nullptr,
reinterpret_cast<int*>(&aad_bytes_read), aad,
static_cast<int>(aad_length)) ||
aad_bytes_read != aad_length) {
aes_gcm_format_errors("Setting authenticated associated data failed.",
error_details);
return GRPC_STATUS_INTERNAL;
}
}
// process ciphertext
uint8_t* plaintext = static_cast<uint8_t*>(plaintext_vec.iov_base);
size_t plaintext_length = plaintext_vec.iov_len;
if (plaintext_length > 0 && plaintext == nullptr) {
aes_gcm_format_errors(
"plaintext is nullptr, but plaintext_length is positive.",
error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
const uint8_t* ciphertext = nullptr;
size_t ciphertext_length = 0;
for (i = 0;
i < ciphertext_vec_length && total_ciphertext_length > kAesGcmTagLength;
i++) {
ciphertext = static_cast<uint8_t*>(ciphertext_vec[i].iov_base);
ciphertext_length = ciphertext_vec[i].iov_len;
if (ciphertext == nullptr) {
if (ciphertext_length == 0) {
continue;
}
aes_gcm_format_errors("ciphertext is nullptr.", error_details);
memset(plaintext_vec.iov_base, 0x00, plaintext_vec.iov_len);
return GRPC_STATUS_INVALID_ARGUMENT;
}
size_t bytes_written = 0;
size_t bytes_to_write = ciphertext_length;
// Don't include the tag
if (bytes_to_write > total_ciphertext_length - kAesGcmTagLength) {
bytes_to_write = total_ciphertext_length - kAesGcmTagLength;
}
if (plaintext_length < bytes_to_write) {
aes_gcm_format_errors(
"Not enough plaintext buffer to hold encrypted ciphertext.",
error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
if (!EVP_DecryptUpdate(aes_gcm_crypter->ctx, plaintext,
reinterpret_cast<int*>(&bytes_written), ciphertext,
static_cast<int>(bytes_to_write))) {
aes_gcm_format_errors("Decrypting ciphertext failed.", error_details);
memset(plaintext_vec.iov_base, 0x00, plaintext_vec.iov_len);
return GRPC_STATUS_INTERNAL;
}
if (bytes_written > ciphertext_length) {
aes_gcm_format_errors("More bytes written than expected.", error_details);
memset(plaintext_vec.iov_base, 0x00, plaintext_vec.iov_len);
return GRPC_STATUS_INTERNAL;
}
ciphertext += bytes_written;
ciphertext_length -= bytes_written;
total_ciphertext_length -= bytes_written;
plaintext += bytes_written;
plaintext_length -= bytes_written;
}
if (total_ciphertext_length > kAesGcmTagLength) {
aes_gcm_format_errors(
"Not enough plaintext buffer to hold encrypted ciphertext.",
error_details);
memset(plaintext_vec.iov_base, 0x00, plaintext_vec.iov_len);
return GRPC_STATUS_INVALID_ARGUMENT;
}
uint8_t tag[kAesGcmTagLength];
uint8_t* tag_tmp = tag;
if (ciphertext_length > 0) {
memcpy(tag_tmp, ciphertext, ciphertext_length);
tag_tmp += ciphertext_length;
total_ciphertext_length -= ciphertext_length;
}
for (; i < ciphertext_vec_length; i++) {
ciphertext = static_cast<uint8_t*>(ciphertext_vec[i].iov_base);
ciphertext_length = ciphertext_vec[i].iov_len;
if (ciphertext == nullptr) {
if (ciphertext_length == 0) {
continue;
}
aes_gcm_format_errors("ciphertext is nullptr.", error_details);
memset(plaintext_vec.iov_base, 0x00, plaintext_vec.iov_len);
return GRPC_STATUS_INVALID_ARGUMENT;
}
memcpy(tag_tmp, ciphertext, ciphertext_length);
tag_tmp += ciphertext_length;
total_ciphertext_length -= ciphertext_length;
}
if (!EVP_CIPHER_CTX_ctrl(aes_gcm_crypter->ctx, EVP_CTRL_GCM_SET_TAG,
kAesGcmTagLength, reinterpret_cast<void*>(tag))) {
aes_gcm_format_errors("Setting tag failed.", error_details);
memset(plaintext_vec.iov_base, 0x00, plaintext_vec.iov_len);
return GRPC_STATUS_INTERNAL;
}
int bytes_written_temp = 0;
if (!EVP_DecryptFinal_ex(aes_gcm_crypter->ctx, nullptr,
&bytes_written_temp)) {
aes_gcm_format_errors("Checking tag failed.", error_details);
memset(plaintext_vec.iov_base, 0x00, plaintext_vec.iov_len);
return GRPC_STATUS_FAILED_PRECONDITION;
}
if (bytes_written_temp != 0) {
aes_gcm_format_errors("Openssl wrote some unexpected bytes.",
error_details);
memset(plaintext_vec.iov_base, 0x00, plaintext_vec.iov_len);
return GRPC_STATUS_INTERNAL;
}
*plaintext_bytes_written = plaintext_vec.iov_len - plaintext_length;
return GRPC_STATUS_OK;
}
static void gsec_aes_gcm_aead_crypter_destroy(gsec_aead_crypter* crypter) {
gsec_aes_gcm_aead_crypter* aes_gcm_crypter =
reinterpret_cast<gsec_aes_gcm_aead_crypter*>(
const_cast<gsec_aead_crypter*>(crypter));
gpr_free(aes_gcm_crypter->key);
gpr_free(aes_gcm_crypter->rekey_data);
EVP_CIPHER_CTX_free(aes_gcm_crypter->ctx);
}
static const gsec_aead_crypter_vtable vtable = {
gsec_aes_gcm_aead_crypter_encrypt_iovec,
gsec_aes_gcm_aead_crypter_decrypt_iovec,
gsec_aes_gcm_aead_crypter_max_ciphertext_and_tag_length,
gsec_aes_gcm_aead_crypter_max_plaintext_length,
gsec_aes_gcm_aead_crypter_nonce_length,
gsec_aes_gcm_aead_crypter_key_length,
gsec_aes_gcm_aead_crypter_tag_length,
gsec_aes_gcm_aead_crypter_destroy};
static grpc_status_code aes_gcm_new_evp_cipher_ctx(
gsec_aes_gcm_aead_crypter* aes_gcm_crypter, char** error_details) {
const EVP_CIPHER* cipher = nullptr;
bool is_rekey = aes_gcm_crypter->rekey_data != nullptr;
switch (is_rekey ? kRekeyAeadKeyLen : aes_gcm_crypter->key_length) {
case kAes128GcmKeyLength:
cipher = EVP_aes_128_gcm();
break;
case kAes256GcmKeyLength:
cipher = EVP_aes_256_gcm();
break;
}
const uint8_t* aead_key = aes_gcm_crypter->key;
uint8_t aead_key_rekey[kRekeyAeadKeyLen];
if (is_rekey) {
if (aes_gcm_derive_aead_key(aead_key_rekey, aes_gcm_crypter->key,
aes_gcm_crypter->rekey_data->kdf_counter) !=
GRPC_STATUS_OK) {
aes_gcm_format_errors("Deriving key failed.", error_details);
return GRPC_STATUS_INTERNAL;
}
aead_key = aead_key_rekey;
}
if (!EVP_DecryptInit_ex(aes_gcm_crypter->ctx, cipher, nullptr, aead_key,
nullptr)) {
aes_gcm_format_errors("Setting key failed.", error_details);
return GRPC_STATUS_INTERNAL;
}
if (!EVP_CIPHER_CTX_ctrl(aes_gcm_crypter->ctx, EVP_CTRL_GCM_SET_IVLEN,
static_cast<int>(aes_gcm_crypter->nonce_length),
nullptr)) {
aes_gcm_format_errors("Setting nonce length failed.", error_details);
return GRPC_STATUS_INTERNAL;
}
return GRPC_STATUS_OK;
}
grpc_status_code gsec_aes_gcm_aead_crypter_create(const uint8_t* key,
size_t key_length,
size_t nonce_length,
size_t tag_length, bool rekey,
gsec_aead_crypter** crypter,
char** error_details) {
if (key == nullptr) {
aes_gcm_format_errors("key is nullptr.", error_details);
return GRPC_STATUS_FAILED_PRECONDITION;
}
if (crypter == nullptr) {
aes_gcm_format_errors("crypter is nullptr.", error_details);
return GRPC_STATUS_FAILED_PRECONDITION;
}
*crypter = nullptr;
if ((rekey && key_length != kAes128GcmRekeyKeyLength) ||
(!rekey && key_length != kAes128GcmKeyLength &&
key_length != kAes256GcmKeyLength) ||
(tag_length != kAesGcmTagLength) ||
(nonce_length != kAesGcmNonceLength)) {
aes_gcm_format_errors(
"Invalid key and/or nonce and/or tag length are provided at AEAD "
"crypter instance construction time.",
error_details);
return GRPC_STATUS_FAILED_PRECONDITION;
}
gsec_aes_gcm_aead_crypter* aes_gcm_crypter =
static_cast<gsec_aes_gcm_aead_crypter*>(
gpr_malloc(sizeof(gsec_aes_gcm_aead_crypter)));
aes_gcm_crypter->crypter.vtable = &vtable;
aes_gcm_crypter->nonce_length = nonce_length;
aes_gcm_crypter->tag_length = tag_length;
if (rekey) {
aes_gcm_crypter->key_length = kKdfKeyLen;
aes_gcm_crypter->rekey_data = static_cast<gsec_aes_gcm_aead_rekey_data*>(
gpr_malloc(sizeof(gsec_aes_gcm_aead_rekey_data)));
memcpy(aes_gcm_crypter->rekey_data->nonce_mask, key + kKdfKeyLen,
kAesGcmNonceLength);
// Set kdf_counter to all-zero for initial key derivation.
memset(aes_gcm_crypter->rekey_data->kdf_counter, 0, kKdfCounterLen);
} else {
aes_gcm_crypter->key_length = key_length;
aes_gcm_crypter->rekey_data = nullptr;
}
aes_gcm_crypter->key =
static_cast<uint8_t*>(gpr_malloc(aes_gcm_crypter->key_length));
memcpy(aes_gcm_crypter->key, key, aes_gcm_crypter->key_length);
aes_gcm_crypter->ctx = EVP_CIPHER_CTX_new();
grpc_status_code status =
aes_gcm_new_evp_cipher_ctx(aes_gcm_crypter, error_details);
if (status != GRPC_STATUS_OK) {
gsec_aes_gcm_aead_crypter_destroy(&aes_gcm_crypter->crypter);
gpr_free(aes_gcm_crypter);
return status;
}
*crypter = &aes_gcm_crypter->crypter;
return GRPC_STATUS_OK;
}

@ -0,0 +1,189 @@
/*
*
* 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/crypt/gsec.h"
#include <stdio.h>
#include <string.h>
#include <grpc/support/alloc.h>
static const char vtable_error_msg[] =
"crypter or crypter->vtable has not been initialized properly";
static void maybe_copy_error_msg(const char* src, char** dst) {
if (dst != nullptr && src != nullptr) {
*dst = static_cast<char*>(gpr_malloc(strlen(src) + 1));
memcpy(*dst, src, strlen(src) + 1);
}
}
grpc_status_code gsec_aead_crypter_encrypt(
gsec_aead_crypter* crypter, const uint8_t* nonce, size_t nonce_length,
const uint8_t* aad, size_t aad_length, const uint8_t* plaintext,
size_t plaintext_length, uint8_t* ciphertext_and_tag,
size_t ciphertext_and_tag_length, size_t* bytes_written,
char** error_details) {
if (crypter != nullptr && crypter->vtable != nullptr &&
crypter->vtable->encrypt_iovec != nullptr) {
struct iovec aad_vec = {(void*)aad, aad_length};
struct iovec plaintext_vec = {(void*)plaintext, plaintext_length};
struct iovec ciphertext_vec = {ciphertext_and_tag,
ciphertext_and_tag_length};
return crypter->vtable->encrypt_iovec(
crypter, nonce, nonce_length, &aad_vec, 1, &plaintext_vec, 1,
ciphertext_vec, bytes_written, error_details);
}
/* An error occurred. */
maybe_copy_error_msg(vtable_error_msg, error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
grpc_status_code gsec_aead_crypter_encrypt_iovec(
gsec_aead_crypter* crypter, const uint8_t* nonce, size_t nonce_length,
const struct iovec* aad_vec, size_t aad_vec_length,
const struct iovec* plaintext_vec, size_t plaintext_vec_length,
struct iovec ciphertext_vec, size_t* ciphertext_bytes_written,
char** error_details) {
if (crypter != nullptr && crypter->vtable != nullptr &&
crypter->vtable->encrypt_iovec != nullptr) {
return crypter->vtable->encrypt_iovec(
crypter, nonce, nonce_length, aad_vec, aad_vec_length, plaintext_vec,
plaintext_vec_length, ciphertext_vec, ciphertext_bytes_written,
error_details);
}
/* An error occurred. */
maybe_copy_error_msg(vtable_error_msg, error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
grpc_status_code gsec_aead_crypter_decrypt(
gsec_aead_crypter* crypter, const uint8_t* nonce, size_t nonce_length,
const uint8_t* aad, size_t aad_length, const uint8_t* ciphertext_and_tag,
size_t ciphertext_and_tag_length, uint8_t* plaintext,
size_t plaintext_length, size_t* bytes_written, char** error_details) {
if (crypter != nullptr && crypter->vtable != nullptr &&
crypter->vtable->decrypt_iovec != nullptr) {
struct iovec aad_vec = {(void*)aad, aad_length};
struct iovec ciphertext_vec = {(void*)ciphertext_and_tag,
ciphertext_and_tag_length};
struct iovec plaintext_vec = {plaintext, plaintext_length};
return crypter->vtable->decrypt_iovec(
crypter, nonce, nonce_length, &aad_vec, 1, &ciphertext_vec, 1,
plaintext_vec, bytes_written, error_details);
}
/* An error occurred. */
maybe_copy_error_msg(vtable_error_msg, error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
grpc_status_code gsec_aead_crypter_decrypt_iovec(
gsec_aead_crypter* crypter, const uint8_t* nonce, size_t nonce_length,
const struct iovec* aad_vec, size_t aad_vec_length,
const struct iovec* ciphertext_vec, size_t ciphertext_vec_length,
struct iovec plaintext_vec, size_t* plaintext_bytes_written,
char** error_details) {
if (crypter != nullptr && crypter->vtable != nullptr &&
crypter->vtable->encrypt_iovec != nullptr) {
return crypter->vtable->decrypt_iovec(
crypter, nonce, nonce_length, aad_vec, aad_vec_length, ciphertext_vec,
ciphertext_vec_length, plaintext_vec, plaintext_bytes_written,
error_details);
}
/* An error occurred. */
maybe_copy_error_msg(vtable_error_msg, error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
grpc_status_code gsec_aead_crypter_max_ciphertext_and_tag_length(
const gsec_aead_crypter* crypter, size_t plaintext_length,
size_t* max_ciphertext_and_tag_length_to_return, char** error_details) {
if (crypter != nullptr && crypter->vtable != nullptr &&
crypter->vtable->max_ciphertext_and_tag_length != nullptr) {
return crypter->vtable->max_ciphertext_and_tag_length(
crypter, plaintext_length, max_ciphertext_and_tag_length_to_return,
error_details);
}
/* An error occurred. */
maybe_copy_error_msg(vtable_error_msg, error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
grpc_status_code gsec_aead_crypter_max_plaintext_length(
const gsec_aead_crypter* crypter, size_t ciphertext_and_tag_length,
size_t* max_plaintext_length_to_return, char** error_details) {
if (crypter != nullptr && crypter->vtable != nullptr &&
crypter->vtable->max_plaintext_length != nullptr) {
return crypter->vtable->max_plaintext_length(
crypter, ciphertext_and_tag_length, max_plaintext_length_to_return,
error_details);
}
/* An error occurred. */
maybe_copy_error_msg(vtable_error_msg, error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
grpc_status_code gsec_aead_crypter_nonce_length(
const gsec_aead_crypter* crypter, size_t* nonce_length_to_return,
char** error_details) {
if (crypter != nullptr && crypter->vtable != nullptr &&
crypter->vtable->nonce_length != nullptr) {
return crypter->vtable->nonce_length(crypter, nonce_length_to_return,
error_details);
}
/* An error occurred. */
maybe_copy_error_msg(vtable_error_msg, error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
grpc_status_code gsec_aead_crypter_key_length(const gsec_aead_crypter* crypter,
size_t* key_length_to_return,
char** error_details) {
if (crypter != nullptr && crypter->vtable != nullptr &&
crypter->vtable->key_length != nullptr) {
return crypter->vtable->key_length(crypter, key_length_to_return,
error_details);
}
/* An error occurred */
maybe_copy_error_msg(vtable_error_msg, error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
grpc_status_code gsec_aead_crypter_tag_length(const gsec_aead_crypter* crypter,
size_t* tag_length_to_return,
char** error_details) {
if (crypter != nullptr && crypter->vtable != nullptr &&
crypter->vtable->tag_length != nullptr) {
return crypter->vtable->tag_length(crypter, tag_length_to_return,
error_details);
}
/* An error occurred. */
maybe_copy_error_msg(vtable_error_msg, error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
void gsec_aead_crypter_destroy(gsec_aead_crypter* crypter) {
if (crypter != nullptr) {
if (crypter->vtable != nullptr && crypter->vtable->destruct != nullptr) {
crypter->vtable->destruct(crypter);
}
gpr_free(crypter);
}
}

@ -0,0 +1,454 @@
/*
*
* 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.
*
*/
#ifndef GRPC_CORE_TSI_ALTS_CRYPT_GSEC_H
#define GRPC_CORE_TSI_ALTS_CRYPT_GSEC_H
#include <grpc/support/port_platform.h>
#include <assert.h>
#include <stdint.h>
#include <stdlib.h>
#include <grpc/grpc.h>
struct iovec {
void* iov_base;
size_t iov_len;
};
/**
* A gsec interface for AEAD encryption schemes. The API is thread-compatible.
* Each implementation of this interface should specify supported values for
* key, nonce, and tag lengths.
*/
/* Key, nonce, and tag length in bytes */
const size_t kAesGcmNonceLength = 12;
const size_t kAesGcmTagLength = 16;
const size_t kAes128GcmKeyLength = 16;
const size_t kAes256GcmKeyLength = 32;
// The first 32 bytes are used as a KDF key and the remaining 12 bytes are used
// to mask the nonce.
const size_t kAes128GcmRekeyKeyLength = 44;
typedef struct gsec_aead_crypter gsec_aead_crypter;
/**
* The gsec_aead_crypter is an API for different AEAD implementations such as
* AES_GCM. It encapsulates all AEAD-related operations in the format of
* V-table that stores pointers to functions implementing those operations.
* It also provides helper functions to wrap each of those function pointers.
*
* A typical usage of this object would be:
*
*------------------------------------------------------------------------------
* // Declare a gsec_aead_crypter object, and create and assign an instance
* // of specific AEAD implementation e.g., AES_GCM to it. We assume both
* // key and nonce contain cryptographically secure random bytes, and the key
* // can be derived from an upper-layer application.
* gsec_aead_crypter* crypter;
* char* error_in_creation;
* // User can populate the message with any 100 bytes data.
* uint8_t* message = gpr_malloc(100);
* grpc_status_code creation_status = gsec_aes_gcm_aead_crypter_create(key,
* kAes128GcmKeyLength,
* kAesGcmNonceLength,
* kAesGcmTagLength,
* &crypter,
* false,
* 0
* &error_in_creation);
*
* if (creation_status == GRPC_STATUS_OK) {
* // Allocate a correct amount of memory to hold a ciphertext.
* size_t clength = 0;
* gsec_aead_crypter_max_ciphertext_and_tag_length(crypter, 100, &clength,
* nullptr);
* uint8_t* ciphertext = gpr_malloc(clength);
*
* // Perform encryption
* size_t num_encrypted_bytes = 0;
* char* error_in_encryption = nullptr;
* grpc_status_code status = gsec_aead_crypter_encrypt(crypter, nonce,
* kAesGcmNonceLength,
* nullptr, 0, message,
* 100, ciphertext,
* clength,
* &num_encrypted_bytes,
* &error_in_encryption);
* if (status == GRPC_STATUS_OK) {
* // Allocate a correct amount of memory to hold a plaintext.
* size_t plength = 0;
* gsec_aead_crypter_max_plaintext_length(crypter, num_encrypted_bytes,
* &plength, nullptr);
* uint8_t* plaintext = gpr_malloc(plength);
*
* // Perform decryption.
* size_t num_decrypted_bytes = 0;
* char* error_in_decryption = nullptr;
* status = gsec_aead_crypter_decrypt(crypter, nonce,
* kAesGcmNonceLength, nullptr, 0,
* ciphertext, num_encrypted_bytes,
* plaintext, plength,
* &num_decrypted_bytes,
* &error_in_decryption);
* if (status != GRPC_STATUS_OK) {
* fprintf(stderr, "AEAD decrypt operation failed with error code:"
* "%d, message: %s\n", status, error_in_decryption);
* }
* ...
* gpr_free(plaintext);
* gpr_free(error_in_decryption);
* } else {
* fprintf(stderr, "AEAD encrypt operation failed with error code:"
* "%d, message: %s\n", status, error_in_encryption);
* }
* ...
* gpr_free(ciphertext);
* gpr_free(error_in_encryption);
* } else {
* fprintf(stderr, "Creation of AEAD crypter instance failed with error code:"
* "%d, message: %s\n", creation_status, error_in_creation);
* }
*
* // Destruct AEAD crypter instance.
* if (creation_status == GRPC_STATUS_OK) {
* gsec_aead_crypter_destroy(crypter);
* }
* gpr_free(error_in_creation);
* gpr_free(message);
* -----------------------------------------------------------------------------
*/
/* V-table for gsec AEAD operations */
typedef struct gsec_aead_crypter_vtable {
grpc_status_code (*encrypt_iovec)(
gsec_aead_crypter* crypter, const uint8_t* nonce, size_t nonce_length,
const struct iovec* aad_vec, size_t aad_vec_length,
const struct iovec* plaintext_vec, size_t plaintext_vec_length,
struct iovec ciphertext_vec, size_t* ciphertext_bytes_written,
char** error_details);
grpc_status_code (*decrypt_iovec)(
gsec_aead_crypter* crypter, const uint8_t* nonce, size_t nonce_length,
const struct iovec* aad_vec, size_t aad_vec_length,
const struct iovec* ciphertext_vec, size_t ciphertext_vec_length,
struct iovec plaintext_vec, size_t* plaintext_bytes_written,
char** error_details);
grpc_status_code (*max_ciphertext_and_tag_length)(
const gsec_aead_crypter* crypter, size_t plaintext_length,
size_t* max_ciphertext_and_tag_length_to_return, char** error_details);
grpc_status_code (*max_plaintext_length)(
const gsec_aead_crypter* crypter, size_t ciphertext_and_tag_length,
size_t* max_plaintext_length_to_return, char** error_details);
grpc_status_code (*nonce_length)(const gsec_aead_crypter* crypter,
size_t* nonce_length_to_return,
char** error_details);
grpc_status_code (*key_length)(const gsec_aead_crypter* crypter,
size_t* key_length_to_return,
char** error_details);
grpc_status_code (*tag_length)(const gsec_aead_crypter* crypter,
size_t* tag_length_to_return,
char** error_details);
void (*destruct)(gsec_aead_crypter* crypter);
} gsec_aead_crypter_vtable;
/* Main struct for gsec interface */
struct gsec_aead_crypter {
const struct gsec_aead_crypter_vtable* vtable;
};
/**
* This method performs an AEAD encrypt operation.
*
* - crypter: AEAD crypter instance.
* - nonce: buffer containing a nonce with its size equal to nonce_length.
* - nonce_length: size of nonce buffer, and must be equal to the value returned
* from method gsec_aead_crypter_nonce_length.
* - aad: buffer containing data that needs to be authenticated but not
* encrypted with its size equal to aad_length.
* - aad_length: size of aad buffer, which should be zero if the buffer is
* nullptr.
* - plaintext: buffer containing data that needs to be both encrypted and
* authenticated with its size equal to plaintext_length.
* - plaintext_length: size of plaintext buffer, which should be zero if
* plaintext is nullptr.
* - ciphertext_and_tag: buffer that will contain ciphertext and tags the method
* produced. The buffer should not overlap the plaintext buffer, and pointers
* to those buffers should not be equal. Also if the ciphertext+tag buffer is
* nullptr, the plaintext_length should be zero.
* - ciphertext_and_tag_length: size of ciphertext+tag buffer, which should be
* at least as long as the one returned from method
* gsec_aead_crypter_max_ciphertext_and_tag_length.
* - bytes_written: the actual number of bytes written to the ciphertext+tag
* buffer. If bytes_written is nullptr, the plaintext_length should be zero.
* - error_details: a buffer containing an error message if the method does not
* function correctly. It is legal to pass nullptr into error_details, and
* otherwise, the parameter should be freed with gpr_free.
*
* On the success of encryption, the method returns GRPC_STATUS_OK. Otherwise,
* it returns an error status code along with its details specified in
* error_details (if error_details is not nullptr).
*
*/
grpc_status_code gsec_aead_crypter_encrypt(
gsec_aead_crypter* crypter, const uint8_t* nonce, size_t nonce_length,
const uint8_t* aad, size_t aad_length, const uint8_t* plaintext,
size_t plaintext_length, uint8_t* ciphertext_and_tag,
size_t ciphertext_and_tag_length, size_t* bytes_written,
char** error_details);
/**
* This method performs an AEAD encrypt operation.
*
* - crypter: AEAD crypter instance.
* - nonce: buffer containing a nonce with its size equal to nonce_length.
* - nonce_length: size of nonce buffer, and must be equal to the value returned
* from method gsec_aead_crypter_nonce_length.
* - aad_vec: an iovec array containing data that needs to be authenticated but
* not encrypted.
* - aad_vec_length: the array length of aad_vec.
* - plaintext_vec: an iovec array containing data that needs to be both
* encrypted and authenticated.
* - plaintext_vec_length: the array length of plaintext_vec.
* - ciphertext_vec: an iovec containing a ciphertext buffer. The buffer should
* not overlap the plaintext buffer.
* - ciphertext_bytes_written: the actual number of bytes written to
* ciphertext_vec.
* - error_details: a buffer containing an error message if the method does not
* function correctly. It is legal to pass nullptr into error_details, and
* otherwise, the parameter should be freed with gpr_free.
*
* On the success of encryption, the method returns GRPC_STATUS_OK. Otherwise,
* it returns an error status code along with its details specified in
* error_details (if error_details is not nullptr).
*
*/
grpc_status_code gsec_aead_crypter_encrypt_iovec(
gsec_aead_crypter* crypter, const uint8_t* nonce, size_t nonce_length,
const struct iovec* aad_vec, size_t aad_vec_length,
const struct iovec* plaintext_vec, size_t plaintext_vec_length,
struct iovec ciphertext_vec, size_t* ciphertext_bytes_written,
char** error_details);
/**
* This method performs an AEAD decrypt operation.
*
* - crypter: AEAD crypter instance.
* - nonce: buffer containing a nonce with its size equal to nonce_length.
* - nonce_length: size of nonce buffer, and must be equal to the value returned
* from method gsec_aead_crypter_nonce_length.
* - aad: buffer containing data that needs to be authenticated only.
* - aad_length: size of aad buffer, which should be zero if the buffer is
* nullptr.
* - ciphertext_and_tag: buffer containing ciphertext and tag.
* - ciphertext_and_tag_length: length of ciphertext and tag. It should be zero
* if any of plaintext, ciphertext_and_tag, or bytes_written is nullptr. Also,
* ciphertext_and_tag_length should be at least as large as the tag length set
* at AEAD crypter instance construction time.
* - plaintext: buffer containing decrypted and authenticated data the method
* produced. The buffer should not overlap with the ciphertext+tag buffer, and
* pointers to those buffers should not be equal.
* - plaintext_length: size of plaintext buffer, which should be at least as
* long as the one returned from gsec_aead_crypter_max_plaintext_length
* method.
* - bytes_written: the actual number of bytes written to the plaintext
* buffer.
* - error_details: a buffer containing an error message if the method does not
* function correctly. It is legal to pass nullptr into error_details, and
* otherwise, the parameter should be freed with gpr_free.
*
* On the success of decryption, the method returns GRPC_STATUS_OK. Otherwise,
* it returns an error status code along with its details specified in
* error_details (if error_details is not nullptr).
*/
grpc_status_code gsec_aead_crypter_decrypt(
gsec_aead_crypter* crypter, const uint8_t* nonce, size_t nonce_length,
const uint8_t* aad, size_t aad_length, const uint8_t* ciphertext_and_tag,
size_t ciphertext_and_tag_length, uint8_t* plaintext,
size_t plaintext_length, size_t* bytes_written, char** error_details);
/**
* This method performs an AEAD decrypt operation.
*
* - crypter: AEAD crypter instance.
* - nonce: buffer containing a nonce with its size equal to nonce_length.
* - nonce_length: size of nonce buffer, and must be equal to the value returned
* from method gsec_aead_crypter_nonce_length.
* - aad_vec: an iovec array containing data that needs to be authenticated but
* not encrypted.
* - aad_vec_length: the array length of aad_vec.
* - ciphertext_vec: an iovec array containing the ciphertext and tag.
* - ciphertext_vec_length: the array length of ciphertext_vec.
* - plaintext_vec: an iovec containing a plaintext buffer. The buffer should
* not overlap the ciphertext buffer.
* - plaintext_bytes_written: the actual number of bytes written to
* plaintext_vec.
* - error_details: a buffer containing an error message if the method does not
* function correctly. It is legal to pass nullptr into error_details, and
* otherwise, the parameter should be freed with gpr_free.
*
* On the success of decryption, the method returns GRPC_STATUS_OK. Otherwise,
* it returns an error status code along with its details specified in
* error_details (if error_details is not nullptr).
*/
grpc_status_code gsec_aead_crypter_decrypt_iovec(
gsec_aead_crypter* crypter, const uint8_t* nonce, size_t nonce_length,
const struct iovec* aad_vec, size_t aad_vec_length,
const struct iovec* ciphertext_vec, size_t ciphertext_vec_length,
struct iovec plaintext_vec, size_t* plaintext_bytes_written,
char** error_details);
/**
* This method computes the size of ciphertext+tag buffer that must be passed to
* gsec_aead_crypter_encrypt function to ensure correct encryption of a
* plaintext. The actual size of ciphertext+tag written to the buffer could be
* smaller.
*
* - crypter: AEAD crypter instance.
* - plaintext_length: length of plaintext.
* - max_ciphertext_and_tag_length_to_return: the size of ciphertext+tag buffer
* the method returns.
* - error_details: a buffer containing an error message if the method does not
* function correctly. It is legal to pass nullptr into error_details, and
* otherwise, the parameter should be freed with gpr_free.
*
* On the success of execution, the method returns GRPC_STATUS_OK. Otherwise,
* it returns an error status code along with its details specified in
* error_details (if error_details is not nullptr).
*/
grpc_status_code gsec_aead_crypter_max_ciphertext_and_tag_length(
const gsec_aead_crypter* crypter, size_t plaintext_length,
size_t* max_ciphertext_and_tag_length_to_return, char** error_details);
/**
* This method computes the size of plaintext buffer that must be passed to
* gsec_aead_crypter_decrypt function to ensure correct decryption of a
* ciphertext. The actual size of plaintext written to the buffer could be
* smaller.
*
* - crypter: AEAD crypter instance.
* - ciphertext_and_tag_length: length of ciphertext and tag.
* - max_plaintext_length_to_return: the size of plaintext buffer the method
* returns.
* - error_details: a buffer containing an error message if the method does not
* function correctly. It is legal to pass nullptr into error_details, and
* otherwise, the parameter should be freed with gpr_free.
*
* On the success of execution, the method returns GRPC_STATUS_OK. Otherwise,
* it returns an error status code along with its details specified in
* error_details (if error_details is not nullptr).
*/
grpc_status_code gsec_aead_crypter_max_plaintext_length(
const gsec_aead_crypter* crypter, size_t ciphertext_and_tag_length,
size_t* max_plaintext_length_to_return, char** error_details);
/**
* This method returns a valid size of nonce array used at the construction of
* AEAD crypter instance. It is also the size that should be passed to encrypt
* and decrypt methods executed on the instance.
*
* - crypter: AEAD crypter instance.
* - nonce_length_to_return: the length of nonce array the method returns.
* - error_details: a buffer containing an error message if the method does not
* function correctly. It is legal to pass nullptr into error_details, and
* otherwise, the parameter should be freed with gpr_free.
*
* On the success of execution, the method returns GRPC_STATUS_OK. Otherwise,
* it returns an error status code along with its details specified in
* error_details (if error_details is not nullptr).
*/
grpc_status_code gsec_aead_crypter_nonce_length(
const gsec_aead_crypter* crypter, size_t* nonce_length_to_return,
char** error_details);
/**
* This method returns a valid size of key array used at the construction of
* AEAD crypter instance. It is also the size that should be passed to encrypt
* and decrypt methods executed on the instance.
*
* - crypter: AEAD crypter instance.
* - key_length_to_return: the length of key array the method returns.
* - error_details: a buffer containing an error message if the method does not
* function correctly. It is legal to pass nullptr into error_details, and
* otherwise, the parameter should be freed with gpr_free.
*
* On the success of execution, the method returns GRPC_STATUS_OK. Otherwise,
* it returns an error status code along with its details specified in
* error_details (if error_details is not nullptr).
*/
grpc_status_code gsec_aead_crypter_key_length(const gsec_aead_crypter* crypter,
size_t* key_length_to_return,
char** error_details);
/**
* This method returns a valid size of tag array used at the construction of
* AEAD crypter instance. It is also the size that should be passed to encrypt
* and decrypt methods executed on the instance.
*
* - crypter: AEAD crypter instance.
* - tag_length_to_return: the length of tag array the method returns.
* - error_details: a buffer containing an error message if the method does not
* function correctly. It is legal to pass nullptr into error_details, and
* otherwise, the parameter should be freed with gpr_free.
*
* On the success of execution, the method returns GRPC_STATUS_OK. Otherwise,
* it returns an error status code along with its details specified in
* error_details (if error_details is not nullptr).
*/
grpc_status_code gsec_aead_crypter_tag_length(const gsec_aead_crypter* crypter,
size_t* tag_length_to_return,
char** error_details);
/**
* This method destroys an AEAD crypter instance by de-allocating all of its
* occupied memory.
*
* - crypter: AEAD crypter instance that needs to be destroyed.
*/
void gsec_aead_crypter_destroy(gsec_aead_crypter* crypter);
/**
* This method creates an AEAD crypter instance of AES-GCM encryption scheme
* which supports 16 and 32 bytes long keys, 12 and 16 bytes long nonces, and
* 16 bytes long tags. It should be noted that once the lengths of key, nonce,
* and tag are determined at construction time, they cannot be modified later.
*
* - key: buffer containing a key which is binded with AEAD crypter instance.
* - key_length: length of a key in bytes, which should be 44 if rekeying is
* enabled and 16 or 32 otherwise.
* - nonce_length: length of a nonce in bytes, which should be either 12 or 16.
* - tag_length: length of a tag in bytes, which should be always 16.
* - rekey: enable nonce-based rekeying and nonce-masking.
* - crypter: address of AES_GCM crypter instance returned from the method.
* - error_details: a buffer containing an error message if the method does not
* function correctly. It is legal to pass nullptr into error_details, and
* otherwise, the parameter should be freed with gpr_free.
*
* On success of instance creation, it stores the address of instance at
* crypter. Otherwise, it returns an error status code together with its details
* specified in error_details.
*/
grpc_status_code gsec_aes_gcm_aead_crypter_create(const uint8_t* key,
size_t key_length,
size_t nonce_length,
size_t tag_length, bool rekey,
gsec_aead_crypter** crypter,
char** error_details);
#endif /* GRPC_CORE_TSI_ALTS_CRYPT_GSEC_H */

@ -0,0 +1,118 @@
/*
*
* 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/frame_protector/alts_counter.h"
#include <string.h>
#include <grpc/support/alloc.h>
static void maybe_copy_error_msg(const char* src, char** dst) {
if (dst != nullptr && src != nullptr) {
*dst = static_cast<char*>(gpr_malloc(strlen(src) + 1));
memcpy(*dst, src, strlen(src) + 1);
}
}
grpc_status_code alts_counter_create(bool is_client, size_t counter_size,
size_t overflow_size,
alts_counter** crypter_counter,
char** error_details) {
/* Perform input sanity check. */
if (counter_size == 0) {
const char error_msg[] = "counter_size is invalid.";
maybe_copy_error_msg(error_msg, error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
if (overflow_size == 0 || overflow_size >= counter_size) {
const char error_msg[] = "overflow_size is invalid.";
maybe_copy_error_msg(error_msg, error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
if (crypter_counter == nullptr) {
const char error_msg[] = "crypter_counter is nullptr.";
maybe_copy_error_msg(error_msg, error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
*crypter_counter =
static_cast<alts_counter*>(gpr_malloc(sizeof(**crypter_counter)));
(*crypter_counter)->size = counter_size;
(*crypter_counter)->overflow_size = overflow_size;
(*crypter_counter)->counter =
static_cast<unsigned char*>(gpr_zalloc(counter_size));
if (is_client) {
((*crypter_counter)->counter)[counter_size - 1] = 0x80;
}
return GRPC_STATUS_OK;
}
grpc_status_code alts_counter_increment(alts_counter* crypter_counter,
bool* is_overflow,
char** error_details) {
/* Perform input sanity check. */
if (crypter_counter == nullptr) {
const char error_msg[] = "crypter_counter is nullptr.";
maybe_copy_error_msg(error_msg, error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
if (is_overflow == nullptr) {
const char error_msg[] = "is_overflow is nullptr.";
maybe_copy_error_msg(error_msg, error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
/* Increment the internal counter. */
size_t i = 0;
for (; i < crypter_counter->overflow_size; i++) {
(crypter_counter->counter)[i]++;
if ((crypter_counter->counter)[i] != 0x00) {
break;
}
}
/**
* If the lower overflow_size bytes are all zero, the counter has overflowed.
*/
if (i == crypter_counter->overflow_size) {
*is_overflow = true;
return GRPC_STATUS_FAILED_PRECONDITION;
}
*is_overflow = false;
return GRPC_STATUS_OK;
}
size_t alts_counter_get_size(alts_counter* crypter_counter) {
if (crypter_counter == nullptr) {
return 0;
}
return crypter_counter->size;
}
unsigned char* alts_counter_get_counter(alts_counter* crypter_counter) {
if (crypter_counter == nullptr) {
return nullptr;
}
return crypter_counter->counter;
}
void alts_counter_destroy(alts_counter* crypter_counter) {
if (crypter_counter != nullptr) {
gpr_free(crypter_counter->counter);
gpr_free(crypter_counter);
}
}

@ -0,0 +1,98 @@
/*
*
* 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.
*
*/
#ifndef GRPC_CORE_TSI_ALTS_FRAME_PROTECTOR_ALTS_COUNTER_H
#define GRPC_CORE_TSI_ALTS_FRAME_PROTECTOR_ALTS_COUNTER_H
#include <grpc/support/port_platform.h>
#include <stdbool.h>
#include <stdlib.h>
#include <grpc/grpc.h>
/* Main struct for a crypter counter managed within seal/unseal operations. */
typedef struct alts_counter {
size_t size;
size_t overflow_size;
unsigned char* counter;
} alts_counter;
/**
* This method creates and initializes an alts_counter instance.
*
* - is_client: a flag indicating if the alts_counter instance will be used
* at client (is_client = true) or server (is_client = false) side.
* - counter_size: size of buffer holding the counter value.
* - overflow_size: overflow size in bytes. The counter instance can be used
* to produce at most 2^(overflow_size*8) frames.
* - crypter_counter: an alts_counter instance to be returned from the method.
* - error_details: a buffer containing an error message if the method does not
* function correctly. It is legal to pass nullptr into error_details and
* otherwise, the parameter should be freed with gpr_free.
*
* On success, the method returns GRPC_STATUS_OK. Otherwise,
* it returns an error status code along with its details specified in
* error_details (if error_details is not nullptr).
*/
grpc_status_code alts_counter_create(bool is_client, size_t counter_size,
size_t overflow_size,
alts_counter** crypter_counter,
char** error_details);
/**
* This method increments the internal counter.
*
* - crypter_counter: an alts_counter instance.
* - is_overflow: after incrementing the internal counter, if an overflow
* occurs, is_overflow is set to true, and no further calls to
* alts_counter_increment() should be made. Otherwise, is_overflow is set to
* false.
* - error_details: a buffer containing an error message if the method does not
* function correctly. It is legal to pass nullptr into error_details and
* otherwise, the parameter should be freed with gpr_free.
*
* On success, the method returns GRPC_STATUS_OK. Otherwise,
* it returns an error status code along with its details specified in
* error_details (if error_details is not nullptr).
*/
grpc_status_code alts_counter_increment(alts_counter* crypter_counter,
bool* is_overflow,
char** error_details);
/**
* This method returns the size of counter buffer.
*
* - crypter_counter: an alts_counter instance.
*/
size_t alts_counter_get_size(alts_counter* crypter_counter);
/**
* This method returns the counter buffer.
*
* - crypter_counter: an alts_counter instance.
*/
unsigned char* alts_counter_get_counter(alts_counter* crypter_counter);
/**
* This method de-allocates all memory allocated to an alts_coutner instance.
* - crypter_counter: an alts_counter instance.
*/
void alts_counter_destroy(alts_counter* crypter_counter);
#endif /* GRPC_CORE_TSI_ALTS_FRAME_PROTECTOR_ALTS_COUNTER_H */

@ -0,0 +1,66 @@
/*
*
* 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/frame_protector/alts_crypter.h"
#include <string.h>
#include <grpc/support/alloc.h>
static void maybe_copy_error_msg(const char* src, char** dst) {
if (dst != nullptr && src != nullptr) {
*dst = static_cast<char*>(gpr_malloc(strlen(src) + 1));
memcpy(*dst, src, strlen(src) + 1);
}
}
grpc_status_code alts_crypter_process_in_place(
alts_crypter* crypter, unsigned char* data, size_t data_allocated_size,
size_t data_size, size_t* output_size, char** error_details) {
if (crypter != nullptr && crypter->vtable != nullptr &&
crypter->vtable->process_in_place != nullptr) {
return crypter->vtable->process_in_place(crypter, data, data_allocated_size,
data_size, output_size,
error_details);
}
/* An error occurred. */
const char error_msg[] =
"crypter or crypter->vtable has not been initialized properly.";
maybe_copy_error_msg(error_msg, error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
size_t alts_crypter_num_overhead_bytes(const alts_crypter* crypter) {
if (crypter != nullptr && crypter->vtable != nullptr &&
crypter->vtable->num_overhead_bytes != nullptr) {
return crypter->vtable->num_overhead_bytes(crypter);
}
/* An error occurred. */
return 0;
}
void alts_crypter_destroy(alts_crypter* crypter) {
if (crypter != nullptr) {
if (crypter->vtable != nullptr && crypter->vtable->destruct != nullptr) {
crypter->vtable->destruct(crypter);
}
gpr_free(crypter);
}
}

@ -0,0 +1,255 @@
/*
*
* 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.
*
*/
#ifndef GRPC_CORE_TSI_ALTS_FRAME_PROTECTOR_ALTS_CRYPTER_H
#define GRPC_CORE_TSI_ALTS_FRAME_PROTECTOR_ALTS_CRYPTER_H
#include <grpc/support/port_platform.h>
#include <stdbool.h>
#include <string.h>
#include <grpc/grpc.h>
#include "src/core/tsi/alts/crypt/gsec.h"
/**
* An alts_crypter interface for an ALTS record protocol providing
* seal/unseal functionality. The interface is thread-compatible.
*/
typedef struct alts_crypter alts_crypter;
/**
* A typical usage of the interface would be
*------------------------------------------------------------------------------
* // Perform a seal operation. We assume the gsec_aead_crypter instance -
* // client_aead_crypter is created beforehand with a 16-byte key and 12-byte
* // nonce length.
*
* alts_crypter* client = nullptr;
* char* client_error_in_creation = nullptr;
* unsigned char* data = nullptr;
* grpc_status_code client_status =
* alts_seal_crypter_create(client_aead_crypter, 1, 5, &client,
* &client_error_in_creation);
* if (client_status == GRPC_STATUS_OK) {
* size_t data_size = 100;
* size_t num_overhead_bytes = alts_crypter_num_overhead_bytes(client);
* size_t data_allocated_size = data_size + num_overhead_bytes;
* data = gpr_malloc(data_allocated_size);
* char* client_error_in_seal = nullptr;
* // Client performs a seal operation.
* client_status = alts_crypter_process_in_place(client, data,
* data_allocated_size,
* &data_size,
* &client_error_in_seal);
* if (client_status != GRPC_STATUS_OK) {
* fprintf(stderr, "seal operation failed with error code:"
* "%d, message: %s\n", client_status,
* client_error_in_seal);
* }
* gpr_free(client_error_in_seal);
* } else {
* fprintf(stderr, "alts_crypter instance creation failed with error"
* "code: %d, message: %s\n", client_status,
* client_error_in_creation);
* }
*
* ...
*
* gpr_free(client_error_in_creation);
* alts_crypter_destroy(client);
*
* ...
*
* // Perform an unseal operation. We assume the gsec_aead_crypter instance -
* // server_aead_crypter is created beforehand with a 16-byte key and 12-byte
* // nonce length. The key used in the creation of gsec_aead_crypter instances
* // at server and client sides should be identical.
*
* alts_crypter* server = nullptr;
* char* server_error_in_creation = nullptr;
* grpc_status_code server_status =
* alts_unseal_crypter_create(server_aead_crypter, 0, 5, &server,
* &server_error_in_creation);
* if (server_status == GRPC_STATUS_OK) {
* size_t num_overhead_bytes = alts_crypter_num_overhead_bytes(server);
* size_t data_size = 100 + num_overhead_bytes;
* size_t data_allocated_size = data_size;
* char* server_error_in_unseal = nullptr;
* // Server performs an unseal operation.
* server_status = alts_crypter_process_in_place(server, data,
* data_allocated_size,
* &data_size,
* &server_error_in_unseal);
* if (server_status != GRPC_STATUS_OK) {
* fprintf(stderr, "unseal operation failed with error code:"
* "%d, message: %s\n", server_status,
* server_error_in_unseal);
* }
* gpr_free(server_error_in_unseal);
* } else {
* fprintf(stderr, "alts_crypter instance creation failed with error"
* "code: %d, message: %s\n", server_status,
* server_error_in_creation);
* }
*
* ...
*
* gpr_free(data);
* gpr_free(server_error_in_creation);
* alts_crypter_destroy(server);
*
* ...
*------------------------------------------------------------------------------
*/
/* V-table for alts_crypter operations */
typedef struct alts_crypter_vtable {
size_t (*num_overhead_bytes)(const alts_crypter* crypter);
grpc_status_code (*process_in_place)(alts_crypter* crypter,
unsigned char* data,
size_t data_allocated_size,
size_t data_size, size_t* output_size,
char** error_details);
void (*destruct)(alts_crypter* crypter);
} alts_crypter_vtable;
/* Main struct for alts_crypter interface */
struct alts_crypter {
const alts_crypter_vtable* vtable;
};
/**
* This method gets the number of overhead bytes needed for sealing data that
* is the difference in size between the protected and raw data. The counter
* value used in a seal or unseal operation is locally maintained (not sent or
* received from the other peer) and therefore, will not be counted as part of
* overhead bytes.
*
* - crypter: an alts_crypter instance.
*
* On success, the method returns the number of overhead bytes. Otherwise, it
* returns zero.
*
*/
size_t alts_crypter_num_overhead_bytes(const alts_crypter* crypter);
/**
* This method performs either a seal or an unseal operation depending on the
* alts_crypter instance - crypter passed to the method. If the crypter is
* an instance implementing a seal operation, the method will perform a seal
* operation. That is, it seals raw data and stores the result in-place, and the
* memory allocated for data must be at least data_length +
* alts_crypter_num_overhead_bytes(). If the crypter is an instance
* implementing an unseal operation, the method will perform an unseal
* operation. That is, it unseals protected data and stores the result in-place.
* The size of unsealed data will be data_length -
* alts_crypter_num_overhead_bytes(). Integrity tag will be verified during
* the unseal operation, and if verification fails, the data will be wiped.
* The counters used in both seal and unseal operations are managed internally.
*
* - crypter: an alts_crypter instance.
* - data: if the method performs a seal operation, the data represents raw data
* that needs to be sealed. It also plays the role of buffer to hold the
* protected data as a result of seal. If the method performs an unseal
* operation, the data represents protected data that needs to be unsealed. It
* also plays the role of buffer to hold raw data as a result of unseal.
* - data_allocated_size: the size of data buffer. The parameter is used to
* check whether the result of either seal or unseal can be safely written to
* the data buffer.
* - data_size: if the method performs a seal operation, data_size
* represents the size of raw data that needs to be sealed, and if the method
* performs an unseal operation, data_size represents the size of protected
* data that needs to be unsealed.
* - output_size: size of data written to the data buffer after a seal or an
* unseal operation.
* - error_details: a buffer containing an error message if the method does not
* function correctly. It is legal to pass nullptr into error_details and
* otherwise, the parameter should be freed with gpr_free.
*
* On success, the method returns GRPC_STATUS_OK. Otherwise,
* it returns an error status code along with its details specified in
* error_details (if error_details is not nullptr).
*/
grpc_status_code alts_crypter_process_in_place(
alts_crypter* crypter, unsigned char* data, size_t data_allocated_size,
size_t data_size, size_t* output_size, char** error_details);
/**
* This method creates an alts_crypter instance to be used to perform a seal
* operation, given a gsec_aead_crypter instance and a flag indicating if the
* created instance will be used at the client or server side. It takes
* ownership of gsec_aead_crypter instance.
*
* - gc: a gsec_aead_crypter instance used to perform AEAD encryption.
* - is_client: a flag indicating if the alts_crypter instance will be
* used at the client (is_client = true) or server (is_client =
* false) side.
* - overflow_size: overflow size of counter in bytes.
* - crypter: an alts_crypter instance to be returned from the method.
* - error_details: a buffer containing an error message if the method does
* not function correctly. It is legal to pass nullptr into error_details, and
* otherwise, the parameter should be freed with gpr_free.
*
* On success of creation, the method returns GRPC_STATUS_OK.
* Otherwise, it returns an error status code along with its details specified
* in error_details (if error_details is not nullptr).
*/
grpc_status_code alts_seal_crypter_create(gsec_aead_crypter* gc, bool is_client,
size_t overflow_size,
alts_crypter** crypter,
char** error_details);
/**
* This method creates an alts_crypter instance used to perform an unseal
* operation, given a gsec_aead_crypter instance and a flag indicating if the
* created instance will be used at the client or server side. It takes
* ownership of gsec_aead_crypter instance.
*
* - gc: a gsec_aead_crypter instance used to perform AEAD decryption.
* - is_client: a flag indicating if the alts_crypter instance will be
* used at the client (is_client = true) or server (is_client =
* false) side.
* - overflow_size: overflow size of counter in bytes.
* - crypter: an alts_crypter instance to be returned from the method.
* - error_details: a buffer containing an error message if the method does
* not function correctly. It is legal to pass nullptr into error_details, and
* otherwise, the parameter should be freed with gpr_free.
*
* On success of creation, the method returns GRPC_STATUS_OK.
* Otherwise, it returns an error status code along with its details specified
* in error_details (if error_details is not nullptr).
*/
grpc_status_code alts_unseal_crypter_create(gsec_aead_crypter* gc,
bool is_client,
size_t overflow_size,
alts_crypter** crypter,
char** error_details);
/**
* This method destroys an alts_crypter instance by de-allocating all of its
* occupied memory. A gsec_aead_crypter instance passed in at alts_crypter
* instance creation time will be destroyed in this method.
*
* - crypter: an alts_crypter instance.
*/
void alts_crypter_destroy(alts_crypter* crypter);
#endif /* GRPC_CORE_TSI_ALTS_FRAME_PROTECTOR_ALTS_CRYPTER_H */

@ -0,0 +1,407 @@
/*
*
* 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/frame_protector/alts_frame_protector.h"
#include <stdio.h>
#include <stdlib.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include "src/core/lib/gpr/useful.h"
#include "src/core/tsi/alts/crypt/gsec.h"
#include "src/core/tsi/alts/frame_protector/alts_crypter.h"
#include "src/core/tsi/alts/frame_protector/frame_handler.h"
#include "src/core/tsi/transport_security.h"
constexpr size_t kMinFrameLength = 1024;
constexpr size_t kDefaultFrameLength = 16 * 1024;
constexpr size_t kMaxFrameLength = 1024 * 1024;
// Limit k on number of frames such that at most 2^(8 * k) frames can be sent.
constexpr size_t kAltsRecordProtocolRekeyFrameLimit = 8;
constexpr size_t kAltsRecordProtocolFrameLimit = 5;
/* Main struct for alts_frame_protector. */
struct alts_frame_protector {
tsi_frame_protector base;
alts_crypter* seal_crypter;
alts_crypter* unseal_crypter;
alts_frame_writer* writer;
alts_frame_reader* reader;
unsigned char* in_place_protect_buffer;
unsigned char* in_place_unprotect_buffer;
size_t in_place_protect_bytes_buffered;
size_t in_place_unprotect_bytes_processed;
size_t max_protected_frame_size;
size_t max_unprotected_frame_size;
size_t overhead_length;
size_t counter_overflow;
};
static tsi_result seal(alts_frame_protector* impl) {
char* error_details = nullptr;
size_t output_size = 0;
grpc_status_code status = alts_crypter_process_in_place(
impl->seal_crypter, impl->in_place_protect_buffer,
impl->max_protected_frame_size, impl->in_place_protect_bytes_buffered,
&output_size, &error_details);
impl->in_place_protect_bytes_buffered = output_size;
if (status != GRPC_STATUS_OK) {
gpr_log(GPR_ERROR, "%s", error_details);
gpr_free(error_details);
return TSI_INTERNAL_ERROR;
}
return TSI_OK;
}
static size_t max_encrypted_payload_bytes(alts_frame_protector* impl) {
return impl->max_protected_frame_size - kFrameHeaderSize;
}
static tsi_result alts_protect_flush(tsi_frame_protector* self,
unsigned char* protected_output_frames,
size_t* protected_output_frames_size,
size_t* still_pending_size) {
if (self == nullptr || protected_output_frames == nullptr ||
protected_output_frames_size == nullptr ||
still_pending_size == nullptr) {
gpr_log(GPR_ERROR, "Invalid nullptr arguments to alts_protect_flush().");
return TSI_INVALID_ARGUMENT;
}
alts_frame_protector* impl = reinterpret_cast<alts_frame_protector*>(self);
/**
* If there's nothing to flush (i.e., in_place_protect_buffer is empty),
* we're done.
*/
if (impl->in_place_protect_bytes_buffered == 0) {
*protected_output_frames_size = 0;
*still_pending_size = 0;
return TSI_OK;
}
/**
* If a new frame can start being processed, we encrypt the payload and reset
* the frame writer to point to in_place_protect_buffer that holds the newly
* sealed frame.
*/
if (alts_is_frame_writer_done(impl->writer)) {
tsi_result result = seal(impl);
if (result != TSI_OK) {
return result;
}
if (!alts_reset_frame_writer(impl->writer, impl->in_place_protect_buffer,
impl->in_place_protect_bytes_buffered)) {
gpr_log(GPR_ERROR, "Couldn't reset frame writer.");
return TSI_INTERNAL_ERROR;
}
}
/**
* Write the sealed frame as much as possible to protected_output_frames. It's
* possible a frame will not be written out completely by a single flush
* (i.e., still_pending_size != 0), in which case the flush should be called
* iteratively until a complete frame has been written out.
*/
size_t written_frame_bytes = *protected_output_frames_size;
if (!alts_write_frame_bytes(impl->writer, protected_output_frames,
&written_frame_bytes)) {
gpr_log(GPR_ERROR, "Couldn't write frame bytes.");
return TSI_INTERNAL_ERROR;
}
*protected_output_frames_size = written_frame_bytes;
*still_pending_size = alts_get_num_writer_bytes_remaining(impl->writer);
/**
* If the current frame has been finished processing (i.e., sealed and written
* out completely), we empty in_place_protect_buffer.
*/
if (alts_is_frame_writer_done(impl->writer)) {
impl->in_place_protect_bytes_buffered = 0;
}
return TSI_OK;
}
static tsi_result alts_protect(tsi_frame_protector* self,
const unsigned char* unprotected_bytes,
size_t* unprotected_bytes_size,
unsigned char* protected_output_frames,
size_t* protected_output_frames_size) {
if (self == nullptr || unprotected_bytes == nullptr ||
unprotected_bytes_size == nullptr || protected_output_frames == nullptr ||
protected_output_frames_size == nullptr) {
gpr_log(GPR_ERROR, "Invalid nullptr arguments to alts_protect().");
return TSI_INVALID_ARGUMENT;
}
alts_frame_protector* impl = reinterpret_cast<alts_frame_protector*>(self);
/**
* If more payload can be buffered, we buffer it as much as possible to
* in_place_protect_buffer.
*/
if (impl->in_place_protect_bytes_buffered + impl->overhead_length <
max_encrypted_payload_bytes(impl)) {
size_t bytes_to_buffer = GPR_MIN(*unprotected_bytes_size,
max_encrypted_payload_bytes(impl) -
impl->in_place_protect_bytes_buffered -
impl->overhead_length);
*unprotected_bytes_size = bytes_to_buffer;
if (bytes_to_buffer > 0) {
memcpy(
impl->in_place_protect_buffer + impl->in_place_protect_bytes_buffered,
unprotected_bytes, bytes_to_buffer);
impl->in_place_protect_bytes_buffered += bytes_to_buffer;
}
} else {
*unprotected_bytes_size = 0;
}
/**
* If a full frame has been buffered, we output it. If the first condition
* holds, then there exists an unencrypted full frame. If the second
* condition holds, then there exists a full frame that has already been
* encrypted.
*/
if (max_encrypted_payload_bytes(impl) ==
impl->in_place_protect_bytes_buffered + impl->overhead_length ||
max_encrypted_payload_bytes(impl) ==
impl->in_place_protect_bytes_buffered) {
size_t still_pending_size = 0;
return alts_protect_flush(self, protected_output_frames,
protected_output_frames_size,
&still_pending_size);
} else {
*protected_output_frames_size = 0;
return TSI_OK;
}
}
static tsi_result unseal(alts_frame_protector* impl) {
char* error_details = nullptr;
size_t output_size = 0;
grpc_status_code status = alts_crypter_process_in_place(
impl->unseal_crypter, impl->in_place_unprotect_buffer,
impl->max_unprotected_frame_size,
alts_get_output_bytes_read(impl->reader), &output_size, &error_details);
if (status != GRPC_STATUS_OK) {
gpr_log(GPR_ERROR, "%s", error_details);
gpr_free(error_details);
return TSI_DATA_CORRUPTED;
}
return TSI_OK;
}
static void ensure_buffer_size(alts_frame_protector* impl) {
if (!alts_has_read_frame_length(impl->reader)) {
return;
}
size_t buffer_space_remaining = impl->max_unprotected_frame_size -
alts_get_output_bytes_read(impl->reader);
/**
* Check if we need to resize in_place_unprotect_buffer in order to hold
* remaining bytes of a full frame.
*/
if (buffer_space_remaining < alts_get_reader_bytes_remaining(impl->reader)) {
size_t buffer_len = alts_get_output_bytes_read(impl->reader) +
alts_get_reader_bytes_remaining(impl->reader);
unsigned char* buffer = static_cast<unsigned char*>(gpr_malloc(buffer_len));
memcpy(buffer, impl->in_place_unprotect_buffer,
alts_get_output_bytes_read(impl->reader));
impl->max_unprotected_frame_size = buffer_len;
gpr_free(impl->in_place_unprotect_buffer);
impl->in_place_unprotect_buffer = buffer;
alts_reset_reader_output_buffer(
impl->reader, buffer + alts_get_output_bytes_read(impl->reader));
}
}
static tsi_result alts_unprotect(tsi_frame_protector* self,
const unsigned char* protected_frames_bytes,
size_t* protected_frames_bytes_size,
unsigned char* unprotected_bytes,
size_t* unprotected_bytes_size) {
if (self == nullptr || protected_frames_bytes == nullptr ||
protected_frames_bytes_size == nullptr || unprotected_bytes == nullptr ||
unprotected_bytes_size == nullptr) {
gpr_log(GPR_ERROR, "Invalid nullptr arguments to alts_unprotect().");
return TSI_INVALID_ARGUMENT;
}
alts_frame_protector* impl = reinterpret_cast<alts_frame_protector*>(self);
/**
* If a new frame can start being processed, we reset the frame reader to
* point to in_place_unprotect_buffer that will be used to hold deframed
* result.
*/
if (alts_is_frame_reader_done(impl->reader) &&
((alts_get_output_buffer(impl->reader) == nullptr) ||
(alts_get_output_bytes_read(impl->reader) ==
impl->in_place_unprotect_bytes_processed + impl->overhead_length))) {
if (!alts_reset_frame_reader(impl->reader,
impl->in_place_unprotect_buffer)) {
gpr_log(GPR_ERROR, "Couldn't reset frame reader.");
return TSI_INTERNAL_ERROR;
}
impl->in_place_unprotect_bytes_processed = 0;
}
/**
* If a full frame has not yet been read, we read more bytes from
* protected_frames_bytes until a full frame has been read. We also need to
* make sure in_place_unprotect_buffer is large enough to hold a complete
* frame.
*/
if (!alts_is_frame_reader_done(impl->reader)) {
ensure_buffer_size(impl);
*protected_frames_bytes_size =
GPR_MIN(impl->max_unprotected_frame_size -
alts_get_output_bytes_read(impl->reader),
*protected_frames_bytes_size);
size_t read_frames_bytes_size = *protected_frames_bytes_size;
if (!alts_read_frame_bytes(impl->reader, protected_frames_bytes,
&read_frames_bytes_size)) {
gpr_log(GPR_ERROR, "Failed to process frame.");
return TSI_INTERNAL_ERROR;
}
*protected_frames_bytes_size = read_frames_bytes_size;
} else {
*protected_frames_bytes_size = 0;
}
/**
* If a full frame has been read, we unseal it, and write out the
* deframed result to unprotected_bytes.
*/
if (alts_is_frame_reader_done(impl->reader)) {
if (impl->in_place_unprotect_bytes_processed == 0) {
tsi_result result = unseal(impl);
if (result != TSI_OK) {
return result;
}
}
size_t bytes_to_write = GPR_MIN(
*unprotected_bytes_size, alts_get_output_bytes_read(impl->reader) -
impl->in_place_unprotect_bytes_processed -
impl->overhead_length);
if (bytes_to_write > 0) {
memcpy(unprotected_bytes,
impl->in_place_unprotect_buffer +
impl->in_place_unprotect_bytes_processed,
bytes_to_write);
}
*unprotected_bytes_size = bytes_to_write;
impl->in_place_unprotect_bytes_processed += bytes_to_write;
return TSI_OK;
} else {
*unprotected_bytes_size = 0;
return TSI_OK;
}
}
static void alts_destroy(tsi_frame_protector* self) {
alts_frame_protector* impl = reinterpret_cast<alts_frame_protector*>(self);
if (impl != nullptr) {
alts_crypter_destroy(impl->seal_crypter);
alts_crypter_destroy(impl->unseal_crypter);
gpr_free(impl->in_place_protect_buffer);
gpr_free(impl->in_place_unprotect_buffer);
alts_destroy_frame_writer(impl->writer);
alts_destroy_frame_reader(impl->reader);
gpr_free(impl);
}
}
static const tsi_frame_protector_vtable alts_frame_protector_vtable = {
alts_protect, alts_protect_flush, alts_unprotect, alts_destroy};
static grpc_status_code create_alts_crypters(const uint8_t* key,
size_t key_size, bool is_client,
bool is_rekey,
alts_frame_protector* impl,
char** error_details) {
grpc_status_code status;
gsec_aead_crypter* aead_crypter_seal = nullptr;
gsec_aead_crypter* aead_crypter_unseal = nullptr;
status = gsec_aes_gcm_aead_crypter_create(key, key_size, kAesGcmNonceLength,
kAesGcmTagLength, is_rekey,
&aead_crypter_seal, error_details);
if (status != GRPC_STATUS_OK) {
return status;
}
status = gsec_aes_gcm_aead_crypter_create(
key, key_size, kAesGcmNonceLength, kAesGcmTagLength, is_rekey,
&aead_crypter_unseal, error_details);
if (status != GRPC_STATUS_OK) {
return status;
}
size_t overflow_size = is_rekey ? kAltsRecordProtocolRekeyFrameLimit
: kAltsRecordProtocolFrameLimit;
status = alts_seal_crypter_create(aead_crypter_seal, is_client, overflow_size,
&impl->seal_crypter, error_details);
if (status != GRPC_STATUS_OK) {
return status;
}
status =
alts_unseal_crypter_create(aead_crypter_unseal, is_client, overflow_size,
&impl->unseal_crypter, error_details);
return status;
}
tsi_result alts_create_frame_protector(const uint8_t* key, size_t key_size,
bool is_client, bool is_rekey,
size_t* max_protected_frame_size,
tsi_frame_protector** self) {
if (key == nullptr || self == nullptr) {
gpr_log(GPR_ERROR,
"Invalid nullptr arguments to alts_create_frame_protector().");
return TSI_INTERNAL_ERROR;
}
char* error_details = nullptr;
alts_frame_protector* impl =
static_cast<alts_frame_protector*>(gpr_zalloc(sizeof(*impl)));
grpc_status_code status = create_alts_crypters(
key, key_size, is_client, is_rekey, impl, &error_details);
if (status != GRPC_STATUS_OK) {
gpr_log(GPR_ERROR, "Failed to create ALTS crypters, %s.", error_details);
gpr_free(error_details);
return TSI_INTERNAL_ERROR;
}
/**
* Set maximum frame size to be used by a frame protector. If it is nullptr, a
* default frame size will be used. Otherwise, the provided frame size will be
* adjusted (if not falling into a valid frame range) and used.
*/
size_t max_protected_frame_size_to_set = kDefaultFrameLength;
if (max_protected_frame_size != nullptr) {
*max_protected_frame_size =
GPR_MIN(*max_protected_frame_size, kMaxFrameLength);
*max_protected_frame_size =
GPR_MAX(*max_protected_frame_size, kMinFrameLength);
max_protected_frame_size_to_set = *max_protected_frame_size;
}
impl->max_protected_frame_size = max_protected_frame_size_to_set;
impl->max_unprotected_frame_size = max_protected_frame_size_to_set;
impl->in_place_protect_bytes_buffered = 0;
impl->in_place_unprotect_bytes_processed = 0;
impl->in_place_protect_buffer = static_cast<unsigned char*>(
gpr_malloc(sizeof(unsigned char) * max_protected_frame_size_to_set));
impl->in_place_unprotect_buffer = static_cast<unsigned char*>(
gpr_malloc(sizeof(unsigned char) * max_protected_frame_size_to_set));
impl->overhead_length = alts_crypter_num_overhead_bytes(impl->seal_crypter);
impl->writer = alts_create_frame_writer();
impl->reader = alts_create_frame_reader();
impl->base.vtable = &alts_frame_protector_vtable;
*self = &impl->base;
return TSI_OK;
}

@ -0,0 +1,55 @@
/*
*
* 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.
*
*/
#ifndef GRPC_CORE_TSI_ALTS_FRAME_PROTECTOR_ALTS_FRAME_PROTECTOR_H
#define GRPC_CORE_TSI_ALTS_FRAME_PROTECTOR_ALTS_FRAME_PROTECTOR_H
#include <grpc/support/port_platform.h>
#include <stdbool.h>
#include "src/core/tsi/transport_security_interface.h"
typedef struct alts_frame_protector alts_frame_protector;
/**
* TODO: Add a parameter to the interface to support the use of
* different record protocols within a frame protector.
*
* This method creates a frame protector.
*
* - key: a symmetric key used to seal/unseal frames.
* - key_size: the size of symmetric key.
* - is_client: a flag indicating if the frame protector will be used at client
* (is_client = true) or server (is_client = false) side.
* - is_rekey: a flag indicating if the frame protector will use an AEAD with
* rekeying.
* - max_protected_frame_size: an in/out parameter indicating max frame size
* to be used by the frame protector. If it is nullptr, the default frame
* size will be used. Otherwise, the provided frame size will be adjusted (if
* not falling into a valid frame range) and used.
* - self: a pointer to the frame protector returned from the method.
*
* This method returns TSI_OK on success and TSI_INTERNAL_ERROR otherwise.
*/
tsi_result alts_create_frame_protector(const uint8_t* key, size_t key_size,
bool is_client, bool is_rekey,
size_t* max_protected_frame_size,
tsi_frame_protector** self);
#endif /* GRPC_CORE_TSI_ALTS_FRAME_PROTECTOR_ALTS_FRAME_PROTECTOR_H */

@ -0,0 +1,114 @@
/*
*
* 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/frame_protector/alts_record_protocol_crypter_common.h"
#include <grpc/support/alloc.h>
static void maybe_copy_error_msg(const char* src, char** dst) {
if (dst != nullptr && src != nullptr) {
*dst = static_cast<char*>(gpr_malloc(strlen(src) + 1));
memcpy(*dst, src, strlen(src) + 1);
}
}
grpc_status_code input_sanity_check(
const alts_record_protocol_crypter* rp_crypter, const unsigned char* data,
size_t* output_size, char** error_details) {
if (rp_crypter == nullptr) {
maybe_copy_error_msg("alts_crypter instance is nullptr.", error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
} else if (data == nullptr) {
maybe_copy_error_msg("data is nullptr.", error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
} else if (output_size == nullptr) {
maybe_copy_error_msg("output_size is nullptr.", error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
return GRPC_STATUS_OK;
}
grpc_status_code increment_counter(alts_record_protocol_crypter* rp_crypter,
char** error_details) {
bool is_overflow = false;
grpc_status_code status =
alts_counter_increment(rp_crypter->ctr, &is_overflow, error_details);
if (status != GRPC_STATUS_OK) {
return status;
}
if (is_overflow) {
const char error_msg[] =
"crypter counter is wrapped. The connection"
"should be closed and the key should be deleted.";
maybe_copy_error_msg(error_msg, error_details);
return GRPC_STATUS_INTERNAL;
}
return GRPC_STATUS_OK;
}
size_t alts_record_protocol_crypter_num_overhead_bytes(const alts_crypter* c) {
if (c != nullptr) {
size_t num_overhead_bytes = 0;
char* error_details = nullptr;
const alts_record_protocol_crypter* rp_crypter =
reinterpret_cast<const alts_record_protocol_crypter*>(c);
grpc_status_code status = gsec_aead_crypter_tag_length(
rp_crypter->crypter, &num_overhead_bytes, &error_details);
if (status == GRPC_STATUS_OK) {
return num_overhead_bytes;
}
}
return 0;
}
void alts_record_protocol_crypter_destruct(alts_crypter* c) {
if (c != nullptr) {
alts_record_protocol_crypter* rp_crypter =
reinterpret_cast<alts_record_protocol_crypter*>(c);
alts_counter_destroy(rp_crypter->ctr);
gsec_aead_crypter_destroy(rp_crypter->crypter);
}
}
alts_record_protocol_crypter* alts_crypter_create_common(
gsec_aead_crypter* crypter, bool is_client, size_t overflow_size,
char** error_details) {
if (crypter != nullptr) {
auto* rp_crypter = static_cast<alts_record_protocol_crypter*>(
gpr_malloc(sizeof(alts_record_protocol_crypter)));
size_t counter_size = 0;
grpc_status_code status =
gsec_aead_crypter_nonce_length(crypter, &counter_size, error_details);
if (status != GRPC_STATUS_OK) {
return nullptr;
}
/* Create a counter. */
status = alts_counter_create(is_client, counter_size, overflow_size,
&rp_crypter->ctr, error_details);
if (status != GRPC_STATUS_OK) {
return nullptr;
}
rp_crypter->crypter = crypter;
return rp_crypter;
}
const char error_msg[] = "crypter is nullptr.";
maybe_copy_error_msg(error_msg, error_details);
return nullptr;
}

@ -0,0 +1,114 @@
/*
*
* 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.
*
*/
#ifndef GRPC_CORE_TSI_ALTS_FRAME_PROTECTOR_ALTS_RECORD_PROTOCOL_CRYPTER_COMMON_H
#define GRPC_CORE_TSI_ALTS_FRAME_PROTECTOR_ALTS_RECORD_PROTOCOL_CRYPTER_COMMON_H
#include <grpc/support/port_platform.h>
#include <grpc/grpc.h>
#include "src/core/tsi/alts/frame_protector/alts_counter.h"
#include "src/core/tsi/alts/frame_protector/alts_crypter.h"
/**
* This file contains common implementation that will be used in both seal and
* unseal operations.
*/
/**
* Main struct for alts_record_protocol_crypter that will be used in both
* seal and unseal operations.
*/
typedef struct alts_record_protocol_crypter {
alts_crypter base;
gsec_aead_crypter* crypter;
alts_counter* ctr;
} alts_record_protocol_crypter;
/**
* This method performs input sanity checks on a subset of inputs to
* alts_crypter_process_in_place() for both seal and unseal operations.
*
* - rp_crypter: an alts_record_protocol_crypter instance.
* - data: it represents raw data that needs to be sealed in a seal operation or
* protected data that needs to be unsealed in an unseal operation.
* - output_size: size of data written to the data buffer after a seal or
* unseal operation.
* - error_details: a buffer containing an error message if any of checked
* inputs is nullptr. It is legal to pass nullptr into error_details and
* otherwise, the parameter should be freed with gpr_free.
*
* On success, the method returns GRPC_STATUS_OK. Otherwise,
* it returns an error status code along with its details specified in
* error_details (if error_details is not nullptr).
*/
grpc_status_code input_sanity_check(
const alts_record_protocol_crypter* rp_crypter, const unsigned char* data,
size_t* output_size, char** error_details);
/**
* This method increments the counter within an alts_record_protocol_crypter
* instance.
*
* - rp_crypter: an alts_record_protocol_crypter instance.
* - error_details: a buffer containing an error message if the method does not
* function correctly or the counter is wrapped. It is legal to pass nullptr
* into error_details and otherwise, the parameter should be freed with
* gpr_free.
*
* On success, the method returns GRPC_STATUS_OK. Otherwise,
* it returns an error status code along with its details specified in
* error_details (if error_details is not nullptr).
*/
grpc_status_code increment_counter(alts_record_protocol_crypter* rp_crypter,
char** error_details);
/**
* This method creates an alts_crypter instance, and populates the fields
* that are common to both seal and unseal operations.
*
* - crypter: a gsec_aead_crypter instance used to perform AEAD decryption. The
* function does not take ownership of crypter.
* - is_client: a flag indicating if the alts_crypter instance will be
* used at the client (is_client = true) or server (is_client =
* false) side.
* - overflow_size: overflow size of counter in bytes.
* - error_details: a buffer containing an error message if the method does
* not function correctly. It is legal to pass nullptr into error_details, and
* otherwise, the parameter should be freed with gpr_free.
*
* On success of creation, the method returns alts_record_protocol_crypter
* instance. Otherwise, it returns nullptr with its details specified in
* error_details (if error_details is not nullptr).
*
*/
alts_record_protocol_crypter* alts_crypter_create_common(
gsec_aead_crypter* crypter, bool is_client, size_t overflow_size,
char** error_details);
/**
* For the following two methods, please refer to the corresponding API in
* alts_crypter.h for detailed specifications.
*/
size_t alts_record_protocol_crypter_num_overhead_bytes(const alts_crypter* c);
void alts_record_protocol_crypter_destruct(alts_crypter* c);
#endif /* GRPC_CORE_TSI_ALTS_FRAME_PROTECTOR_ALTS_RECORD_PROTOCOL_CRYPTER_COMMON_H \
*/

@ -0,0 +1,105 @@
/*
*
* 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 <grpc/support/alloc.h>
#include "src/core/tsi/alts/frame_protector/alts_counter.h"
#include "src/core/tsi/alts/frame_protector/alts_crypter.h"
#include "src/core/tsi/alts/frame_protector/alts_record_protocol_crypter_common.h"
static void maybe_copy_error_msg(const char* src, char** dst) {
if (dst != nullptr && src != nullptr) {
*dst = static_cast<char*>(gpr_malloc(strlen(src) + 1));
memcpy(*dst, src, strlen(src) + 1);
}
}
/* Perform input santity check for a seal operation. */
static grpc_status_code seal_check(alts_crypter* c, const unsigned char* data,
size_t data_allocated_size, size_t data_size,
size_t* output_size, char** error_details) {
/* Do common input sanity check. */
grpc_status_code status = input_sanity_check(
reinterpret_cast<const alts_record_protocol_crypter*>(c), data,
output_size, error_details);
if (status != GRPC_STATUS_OK) return status;
/* Do seal-specific check. */
size_t num_overhead_bytes =
alts_crypter_num_overhead_bytes(reinterpret_cast<const alts_crypter*>(c));
if (data_size == 0) {
const char error_msg[] = "data_size is zero.";
maybe_copy_error_msg(error_msg, error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
if (data_size + num_overhead_bytes > data_allocated_size) {
const char error_msg[] =
"data_allocated_size is smaller than sum of data_size and "
"num_overhead_bytes.";
maybe_copy_error_msg(error_msg, error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
return GRPC_STATUS_OK;
}
static grpc_status_code alts_seal_crypter_process_in_place(
alts_crypter* c, unsigned char* data, size_t data_allocated_size,
size_t data_size, size_t* output_size, char** error_details) {
grpc_status_code status = seal_check(c, data, data_allocated_size, data_size,
output_size, error_details);
if (status != GRPC_STATUS_OK) {
return status;
}
/* Do AEAD encryption. */
alts_record_protocol_crypter* rp_crypter =
reinterpret_cast<alts_record_protocol_crypter*>(c);
status = gsec_aead_crypter_encrypt(
rp_crypter->crypter, alts_counter_get_counter(rp_crypter->ctr),
alts_counter_get_size(rp_crypter->ctr), nullptr /* aad */,
0 /* aad_length */, data, data_size, data, data_allocated_size,
output_size, error_details);
if (status != GRPC_STATUS_OK) {
return status;
}
/* Increment the crypter counter. */
return increment_counter(rp_crypter, error_details);
}
static const alts_crypter_vtable vtable = {
alts_record_protocol_crypter_num_overhead_bytes,
alts_seal_crypter_process_in_place, alts_record_protocol_crypter_destruct};
grpc_status_code alts_seal_crypter_create(gsec_aead_crypter* gc, bool is_client,
size_t overflow_size,
alts_crypter** crypter,
char** error_details) {
if (crypter == nullptr) {
const char error_msg[] = "crypter is nullptr.";
maybe_copy_error_msg(error_msg, error_details);
return GRPC_STATUS_FAILED_PRECONDITION;
}
alts_record_protocol_crypter* rp_crypter =
alts_crypter_create_common(gc, !is_client, overflow_size, error_details);
if (rp_crypter == nullptr) {
return GRPC_STATUS_FAILED_PRECONDITION;
}
rp_crypter->base.vtable = &vtable;
*crypter = &rp_crypter->base;
return GRPC_STATUS_OK;
}

@ -0,0 +1,103 @@
/*
*
* 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 <grpc/support/alloc.h>
#include "src/core/tsi/alts/frame_protector/alts_counter.h"
#include "src/core/tsi/alts/frame_protector/alts_crypter.h"
#include "src/core/tsi/alts/frame_protector/alts_record_protocol_crypter_common.h"
static void maybe_copy_error_msg(const char* src, char** dst) {
if (dst != nullptr && src != nullptr) {
*dst = static_cast<char*>(gpr_malloc(strlen(src) + 1));
memcpy(*dst, src, strlen(src) + 1);
}
}
/* Perform input santity check. */
static grpc_status_code unseal_check(alts_crypter* c, const unsigned char* data,
size_t data_allocated_size,
size_t data_size, size_t* output_size,
char** error_details) {
/* Do common input sanity check. */
grpc_status_code status = input_sanity_check(
reinterpret_cast<const alts_record_protocol_crypter*>(c), data,
output_size, error_details);
if (status != GRPC_STATUS_OK) {
return status;
}
/* Do unseal-specific input check. */
size_t num_overhead_bytes =
alts_crypter_num_overhead_bytes(reinterpret_cast<const alts_crypter*>(c));
if (num_overhead_bytes > data_size) {
const char error_msg[] = "data_size is smaller than num_overhead_bytes.";
maybe_copy_error_msg(error_msg, error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
return GRPC_STATUS_OK;
}
static grpc_status_code alts_unseal_crypter_process_in_place(
alts_crypter* c, unsigned char* data, size_t data_allocated_size,
size_t data_size, size_t* output_size, char** error_details) {
grpc_status_code status = unseal_check(c, data, data_allocated_size,
data_size, output_size, error_details);
if (status != GRPC_STATUS_OK) {
return status;
}
/* Do AEAD decryption. */
alts_record_protocol_crypter* rp_crypter =
reinterpret_cast<alts_record_protocol_crypter*>(c);
status = gsec_aead_crypter_decrypt(
rp_crypter->crypter, alts_counter_get_counter(rp_crypter->ctr),
alts_counter_get_size(rp_crypter->ctr), nullptr /* aad */,
0 /* aad_length */, data, data_size, data, data_allocated_size,
output_size, error_details);
if (status != GRPC_STATUS_OK) {
return status;
}
/* Increment the crypter counter. */
return increment_counter(rp_crypter, error_details);
}
static const alts_crypter_vtable vtable = {
alts_record_protocol_crypter_num_overhead_bytes,
alts_unseal_crypter_process_in_place,
alts_record_protocol_crypter_destruct};
grpc_status_code alts_unseal_crypter_create(gsec_aead_crypter* gc,
bool is_client,
size_t overflow_size,
alts_crypter** crypter,
char** error_details) {
if (crypter == nullptr) {
const char error_msg[] = "crypter is nullptr.";
maybe_copy_error_msg(error_msg, error_details);
return GRPC_STATUS_FAILED_PRECONDITION;
}
alts_record_protocol_crypter* rp_crypter =
alts_crypter_create_common(gc, is_client, overflow_size, error_details);
if (rp_crypter == nullptr) {
return GRPC_STATUS_FAILED_PRECONDITION;
}
rp_crypter->base.vtable = &vtable;
*crypter = &rp_crypter->base;
return GRPC_STATUS_OK;
}

@ -0,0 +1,218 @@
/*
*
* 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/frame_protector/frame_handler.h"
#include <limits.h>
#include <stdint.h>
#include <string.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include "src/core/lib/gpr/useful.h"
/* Use little endian to interpret a string of bytes as uint32_t. */
static uint32_t load_32_le(const unsigned char* buffer) {
return (((uint32_t)buffer[3]) << 24) | (((uint32_t)buffer[2]) << 16) |
(((uint32_t)buffer[1]) << 8) | ((uint32_t)buffer[0]);
}
/* Store uint32_t as a string of little endian bytes. */
static void store_32_le(uint32_t value, unsigned char* buffer) {
buffer[3] = (unsigned char)(value >> 24) & 0xFF;
buffer[2] = (unsigned char)(value >> 16) & 0xFF;
buffer[1] = (unsigned char)(value >> 8) & 0xFF;
buffer[0] = (unsigned char)(value)&0xFF;
}
/* Frame writer implementation. */
alts_frame_writer* alts_create_frame_writer() {
alts_frame_writer* writer =
static_cast<alts_frame_writer*>(gpr_zalloc(sizeof(*writer)));
return writer;
}
bool alts_reset_frame_writer(alts_frame_writer* writer,
const unsigned char* buffer, size_t length) {
if (buffer == nullptr) return false;
size_t max_input_size = SIZE_MAX - kFrameLengthFieldSize;
if (length > max_input_size) {
gpr_log(GPR_ERROR, "length must be at most %zu", max_input_size);
return false;
}
writer->input_buffer = buffer;
writer->input_size = length;
writer->input_bytes_written = 0;
writer->header_bytes_written = 0;
store_32_le(
static_cast<uint32_t>(writer->input_size + kFrameMessageTypeFieldSize),
writer->header_buffer);
store_32_le(kFrameMessageType, writer->header_buffer + kFrameLengthFieldSize);
return true;
}
bool alts_write_frame_bytes(alts_frame_writer* writer, unsigned char* output,
size_t* bytes_size) {
if (bytes_size == nullptr || output == nullptr) return false;
if (alts_is_frame_writer_done(writer)) {
*bytes_size = 0;
return true;
}
size_t bytes_written = 0;
/* Write some header bytes, if needed. */
if (writer->header_bytes_written != sizeof(writer->header_buffer)) {
size_t bytes_to_write =
GPR_MIN(*bytes_size,
sizeof(writer->header_buffer) - writer->header_bytes_written);
memcpy(output, writer->header_buffer + writer->header_bytes_written,
bytes_to_write);
bytes_written += bytes_to_write;
*bytes_size -= bytes_to_write;
writer->header_bytes_written += bytes_to_write;
output += bytes_to_write;
if (writer->header_bytes_written != sizeof(writer->header_buffer)) {
*bytes_size = bytes_written;
return true;
}
}
/* Write some non-header bytes. */
size_t bytes_to_write =
GPR_MIN(writer->input_size - writer->input_bytes_written, *bytes_size);
memcpy(output, writer->input_buffer, bytes_to_write);
writer->input_buffer += bytes_to_write;
bytes_written += bytes_to_write;
writer->input_bytes_written += bytes_to_write;
*bytes_size = bytes_written;
return true;
}
bool alts_is_frame_writer_done(alts_frame_writer* writer) {
return writer->input_buffer == nullptr ||
writer->input_size == writer->input_bytes_written;
}
size_t alts_get_num_writer_bytes_remaining(alts_frame_writer* writer) {
return (sizeof(writer->header_buffer) - writer->header_bytes_written) +
(writer->input_size - writer->input_bytes_written);
}
void alts_destroy_frame_writer(alts_frame_writer* writer) { gpr_free(writer); }
/* Frame reader implementation. */
alts_frame_reader* alts_create_frame_reader() {
alts_frame_reader* reader =
static_cast<alts_frame_reader*>(gpr_zalloc(sizeof(*reader)));
return reader;
}
bool alts_is_frame_reader_done(alts_frame_reader* reader) {
return reader->output_buffer == nullptr ||
(reader->header_bytes_read == sizeof(reader->header_buffer) &&
reader->bytes_remaining == 0);
}
bool alts_has_read_frame_length(alts_frame_reader* reader) {
return sizeof(reader->header_buffer) == reader->header_bytes_read;
}
size_t alts_get_reader_bytes_remaining(alts_frame_reader* reader) {
return alts_has_read_frame_length(reader) ? reader->bytes_remaining : 0;
}
void alts_reset_reader_output_buffer(alts_frame_reader* reader,
unsigned char* buffer) {
reader->output_buffer = buffer;
}
bool alts_reset_frame_reader(alts_frame_reader* reader, unsigned char* buffer) {
if (buffer == nullptr) return false;
reader->output_buffer = buffer;
reader->bytes_remaining = 0;
reader->header_bytes_read = 0;
reader->output_bytes_read = 0;
return true;
}
bool alts_read_frame_bytes(alts_frame_reader* reader,
const unsigned char* bytes, size_t* bytes_size) {
if (bytes_size == nullptr) return false;
if (bytes == nullptr) {
*bytes_size = 0;
return false;
}
if (alts_is_frame_reader_done(reader)) {
*bytes_size = 0;
return true;
}
size_t bytes_processed = 0;
/* Process the header, if needed. */
if (reader->header_bytes_read != sizeof(reader->header_buffer)) {
size_t bytes_to_write = GPR_MIN(
*bytes_size, sizeof(reader->header_buffer) - reader->header_bytes_read);
memcpy(reader->header_buffer + reader->header_bytes_read, bytes,
bytes_to_write);
reader->header_bytes_read += bytes_to_write;
bytes_processed += bytes_to_write;
bytes += bytes_to_write;
*bytes_size -= bytes_to_write;
if (reader->header_bytes_read != sizeof(reader->header_buffer)) {
*bytes_size = bytes_processed;
return true;
}
size_t frame_length = load_32_le(reader->header_buffer);
if (frame_length < kFrameMessageTypeFieldSize ||
frame_length > kFrameMaxSize) {
gpr_log(GPR_ERROR,
"Bad frame length (should be at least %zu, and at most %zu)",
kFrameMessageTypeFieldSize, kFrameMaxSize);
*bytes_size = 0;
return false;
}
size_t message_type =
load_32_le(reader->header_buffer + kFrameLengthFieldSize);
if (message_type != kFrameMessageType) {
gpr_log(GPR_ERROR, "Unsupported message type %zu (should be %zu)",
message_type, kFrameMessageType);
*bytes_size = 0;
return false;
}
reader->bytes_remaining = frame_length - kFrameMessageTypeFieldSize;
}
/* Process the non-header bytes. */
size_t bytes_to_write = GPR_MIN(*bytes_size, reader->bytes_remaining);
memcpy(reader->output_buffer, bytes, bytes_to_write);
reader->output_buffer += bytes_to_write;
bytes_processed += bytes_to_write;
reader->bytes_remaining -= bytes_to_write;
reader->output_bytes_read += bytes_to_write;
*bytes_size = bytes_processed;
return true;
}
size_t alts_get_output_bytes_read(alts_frame_reader* reader) {
return reader->output_bytes_read;
}
unsigned char* alts_get_output_buffer(alts_frame_reader* reader) {
return reader->output_buffer;
}
void alts_destroy_frame_reader(alts_frame_reader* reader) { gpr_free(reader); }

@ -0,0 +1,236 @@
/*
*
* 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.
*
*/
#ifndef GRPC_CORE_TSI_ALTS_FRAME_PROTECTOR_FRAME_HANDLER_H
#define GRPC_CORE_TSI_ALTS_FRAME_PROTECTOR_FRAME_HANDLER_H
#include <grpc/support/port_platform.h>
#include <stdbool.h>
#include <stdlib.h>
const size_t kFrameMessageType = 0x06;
const size_t kFrameLengthFieldSize = 4;
const size_t kFrameMessageTypeFieldSize = 4;
const size_t kFrameMaxSize = 1024 * 1024;
const size_t kFrameHeaderSize =
kFrameLengthFieldSize + kFrameMessageTypeFieldSize;
/**
* Implementation of frame reader and frame writer. All APIs in the
* header are thread-compatible.
*/
/**
* Main struct for a frame writer. It reads frames from an input buffer, and
* writes the contents as raw bytes. It does not own the input buffer.
*/
typedef struct alts_frame_writer {
const unsigned char* input_buffer;
unsigned char header_buffer[kFrameHeaderSize];
size_t input_bytes_written;
size_t header_bytes_written;
size_t input_size;
} alts_frame_writer;
/**
* Main struct for a frame reader. It reads raw bytes and puts the framed
* result into an output buffer. It does not own the output buffer.
*/
typedef struct alts_frame_reader {
unsigned char* output_buffer;
unsigned char header_buffer[kFrameHeaderSize];
size_t header_bytes_read;
size_t output_bytes_read;
size_t bytes_remaining;
} alts_frame_reader;
/**
* This method creates a frame writer instance and initializes its internal
* states.
*/
alts_frame_writer* alts_create_frame_writer();
/**
* This method resets internal states of a frame writer and prepares to write
* a single frame. It does not take ownership of payload_buffer.
* The payload_buffer must outlive the writer.
*
* - writer: a frame writer instance.
* - buffer: a buffer storing full payload data to be framed.
* - length: size of payload data.
*
* The method returns true on success and false otherwise.
*/
bool alts_reset_frame_writer(alts_frame_writer* writer,
const unsigned char* buffer, size_t length);
/**
* This method writes up to bytes_size bytes of a frame to output.
*
* - writer: a frame writer instance.
* - output: an output buffer used to store the frame.
* - bytes_size: an in/out parameter that stores the size of output buffer
* before the call, and gets written the number of frame bytes written to the
* buffer.
*
* The method returns true on success and false otherwise.
*/
bool alts_write_frame_bytes(alts_frame_writer* writer, unsigned char* output,
size_t* bytes_size);
/**
* This method checks if a reset can be called to write a new frame. It returns
* true if it's the first time to frame a payload, or the current frame has
* been finished processing. It returns false if it's not ready yet to start a
* new frame (e.g., more payload data needs to be accumulated to process the
* current frame).
*
* if (alts_is_frame_writer_done(writer)) {
* // a new frame can be written, call reset.
* alts_reset_frame_writer(writer, payload_buffer, payload_size);
* } else {
* // accumulate more payload data until a full frame can be written.
* }
*
* - writer: a frame writer instance.
*/
bool alts_is_frame_writer_done(alts_frame_writer* writer);
/**
* This method returns the number of bytes left to write before a complete frame
* is formed.
*
* - writer: a frame writer instance.
*/
size_t alts_get_num_writer_bytes_remaining(alts_frame_writer* writer);
/**
* This method destroys a frame writer instance.
*
* - writer: a frame writer instance.
*/
void alts_destroy_frame_writer(alts_frame_writer* writer);
/**
* This method creates a frame reader instance and initializes its internal
* states.
*/
alts_frame_reader* alts_create_frame_reader();
/**
* This method resets internal states of a frame reader (including setting its
* output_buffer with buffer), and prepares to write processed bytes to
* an output_buffer. It does not take ownership of buffer. The buffer must
* outlive reader.
*
* - reader: a frame reader instance.
* - buffer: an output buffer used to store deframed results.
*
* The method returns true on success and false otherwise.
*/
bool alts_reset_frame_reader(alts_frame_reader* reader, unsigned char* buffer);
/**
* This method processes up to the number of bytes given in bytes_size. It may
* choose not to process all the bytes, if, for instance, more bytes are
* given to the method than required to complete the current frame.
*
* - reader: a frame reader instance.
* - bytes: a buffer that stores data to be processed.
* - bytes_size: an in/out parameter that stores the size of bytes before the
* call and gets written the number of bytes processed.
*
* The method returns true on success and false otherwise.
*/
bool alts_read_frame_bytes(alts_frame_reader* reader,
const unsigned char* bytes, size_t* bytes_size);
/**
* This method checks if a frame length has been read.
*
* - reader: a frame reader instance.
*
* The method returns true if a frame length has been read and false otherwise.
*/
bool alts_has_read_frame_length(alts_frame_reader* reader);
/**
* This method returns the number of bytes the frame reader intends to write.
* It may only be called if alts_has_read_frame_length() returns true.
*
* - reader: a frame reader instance.
*/
size_t alts_get_reader_bytes_remaining(alts_frame_reader* reader);
/**
* This method resets output_buffer but does not otherwise modify other internal
* states of a frame reader instance. After being set, the new output_buffer
* will hold the deframed payload held by the original output_buffer. It does
* not take ownership of buffer. The buffer must outlive the reader.
* To distinguish between two reset methods on a frame reader,
*
* if (alts_fh_is_frame_reader_done(reader)) {
* // if buffer contains a full payload to be deframed, call reset.
* alts_reset_frame_reader(reader, buffer);
* }
*
* // if remaining buffer space is not enough to hold a full payload
* if (buffer_space_remaining < alts_get_reader_bytes_remaining(reader)) {
* // allocate enough space for a new buffer, copy back data processed so far,
* // and call reset.
* alts_reset_reader_output_buffer(reader, new_buffer).
* }
*
* - reader: a frame reader instance.
* - buffer: a buffer used to set reader's output_buffer.
*/
void alts_reset_reader_output_buffer(alts_frame_reader* reader,
unsigned char* buffer);
/**
* This method checks if reset can be called to start processing a new frame.
* If true and reset was previously called, a full frame has been processed and
* the content of the frame is available in output_buffer.
* - reader: a frame reader instance.
*/
bool alts_is_frame_reader_done(alts_frame_reader* reader);
/**
* This method returns output_bytes_read of a frame reader instance.
*
* - reader: a frame reader instance.
*/
size_t alts_get_output_bytes_read(alts_frame_reader* reader);
/**
* This method returns output_buffer of a frame reader instance.
*
* - reader: a frame reader instance.
*/
unsigned char* alts_get_output_buffer(alts_frame_reader* reader);
/**
* This method destroys a frame reader instance.
*
* - reader: a frame reader instance.
*/
void alts_destroy_frame_reader(alts_frame_reader* reader);
#endif /* GRPC_CORE_TSI_ALTS_FRAME_PROTECTOR_FRAME_HANDLER_H */

@ -0,0 +1,316 @@
/*
*
* 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_client.h"
#include <grpc/byte_buffer.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include "src/core/tsi/alts/handshaker/alts_handshaker_service_api.h"
const int kHandshakerClientOpNum = 4;
typedef struct alts_grpc_handshaker_client {
alts_handshaker_client base;
grpc_call* call;
alts_grpc_caller grpc_caller;
} alts_grpc_handshaker_client;
static grpc_call_error grpc_start_batch(grpc_call* call, const grpc_op* ops,
size_t nops, void* tag) {
return grpc_call_start_batch(call, ops, nops, tag, nullptr);
}
/**
* Populate grpc operation data with the fields of ALTS TSI event and make a
* grpc call.
*/
static tsi_result make_grpc_call(alts_handshaker_client* client,
alts_tsi_event* event, bool is_start) {
GPR_ASSERT(client != nullptr && event != nullptr);
alts_grpc_handshaker_client* grpc_client =
reinterpret_cast<alts_grpc_handshaker_client*>(client);
grpc_op ops[kHandshakerClientOpNum];
memset(ops, 0, sizeof(ops));
grpc_op* op = ops;
if (is_start) {
op->op = GRPC_OP_SEND_INITIAL_METADATA;
op->data.send_initial_metadata.count = 0;
op++;
GPR_ASSERT(op - ops <= kHandshakerClientOpNum);
op->op = GRPC_OP_RECV_INITIAL_METADATA;
op->data.recv_initial_metadata.recv_initial_metadata =
&event->initial_metadata;
op++;
GPR_ASSERT(op - ops <= kHandshakerClientOpNum);
}
op->op = GRPC_OP_SEND_MESSAGE;
op->data.send_message.send_message = event->send_buffer;
op++;
GPR_ASSERT(op - ops <= kHandshakerClientOpNum);
op->op = GRPC_OP_RECV_MESSAGE;
op->data.recv_message.recv_message = &event->recv_buffer;
op++;
GPR_ASSERT(op - ops <= kHandshakerClientOpNum);
GPR_ASSERT(grpc_client->grpc_caller != nullptr);
if (grpc_client->grpc_caller(grpc_client->call, ops,
static_cast<size_t>(op - ops),
(void*)event) != GRPC_CALL_OK) {
gpr_log(GPR_ERROR, "Start batch operation failed");
return TSI_INTERNAL_ERROR;
}
return TSI_OK;
}
/* Create and populate a client_start handshaker request, then serialize it. */
static grpc_byte_buffer* get_serialized_start_client(alts_tsi_event* event) {
bool ok = true;
grpc_gcp_handshaker_req* req =
grpc_gcp_handshaker_req_create(CLIENT_START_REQ);
ok &= grpc_gcp_handshaker_req_set_handshake_protocol(
req, grpc_gcp_HandshakeProtocol_ALTS);
ok &= grpc_gcp_handshaker_req_add_application_protocol(
req, ALTS_APPLICATION_PROTOCOL);
ok &= grpc_gcp_handshaker_req_add_record_protocol(req, ALTS_RECORD_PROTOCOL);
grpc_gcp_rpc_protocol_versions* versions = &event->options->rpc_versions;
ok &= grpc_gcp_handshaker_req_set_rpc_versions(
req, versions->max_rpc_version.major, versions->max_rpc_version.minor,
versions->min_rpc_version.major, versions->min_rpc_version.minor);
char* target_name = grpc_slice_to_c_string(event->target_name);
ok &= grpc_gcp_handshaker_req_set_target_name(req, target_name);
target_service_account* ptr =
(reinterpret_cast<grpc_alts_credentials_client_options*>(event->options))
->target_account_list_head;
while (ptr != nullptr) {
grpc_gcp_handshaker_req_add_target_identity_service_account(req, ptr->data);
ptr = ptr->next;
}
grpc_slice slice;
ok &= grpc_gcp_handshaker_req_encode(req, &slice);
grpc_byte_buffer* buffer = nullptr;
if (ok) {
buffer = grpc_raw_byte_buffer_create(&slice, 1 /* number of slices */);
}
grpc_slice_unref(slice);
gpr_free(target_name);
grpc_gcp_handshaker_req_destroy(req);
return buffer;
}
static tsi_result handshaker_client_start_client(alts_handshaker_client* client,
alts_tsi_event* event) {
if (client == nullptr || event == nullptr) {
gpr_log(GPR_ERROR,
"Invalid arguments to alts_grpc_handshaker_client_start_client()");
return TSI_INVALID_ARGUMENT;
}
grpc_byte_buffer* buffer = get_serialized_start_client(event);
if (buffer == nullptr) {
gpr_log(GPR_ERROR, "get_serialized_start_client() failed");
return TSI_INTERNAL_ERROR;
}
event->send_buffer = buffer;
tsi_result result = make_grpc_call(client, event, true /* is_start */);
if (result != TSI_OK) {
gpr_log(GPR_ERROR, "make_grpc_call() failed");
}
return result;
}
/* Create and populate a start_server handshaker request, then serialize it. */
static grpc_byte_buffer* get_serialized_start_server(
alts_tsi_event* event, grpc_slice* bytes_received) {
GPR_ASSERT(bytes_received != nullptr);
grpc_gcp_handshaker_req* req =
grpc_gcp_handshaker_req_create(SERVER_START_REQ);
bool ok = grpc_gcp_handshaker_req_add_application_protocol(
req, ALTS_APPLICATION_PROTOCOL);
ok &= grpc_gcp_handshaker_req_param_add_record_protocol(
req, grpc_gcp_HandshakeProtocol_ALTS, ALTS_RECORD_PROTOCOL);
ok &= grpc_gcp_handshaker_req_set_in_bytes(
req, reinterpret_cast<const char*> GRPC_SLICE_START_PTR(*bytes_received),
GRPC_SLICE_LENGTH(*bytes_received));
grpc_gcp_rpc_protocol_versions* versions = &event->options->rpc_versions;
ok &= grpc_gcp_handshaker_req_set_rpc_versions(
req, versions->max_rpc_version.major, versions->max_rpc_version.minor,
versions->min_rpc_version.major, versions->min_rpc_version.minor);
grpc_slice req_slice;
ok &= grpc_gcp_handshaker_req_encode(req, &req_slice);
grpc_byte_buffer* buffer = nullptr;
if (ok) {
buffer = grpc_raw_byte_buffer_create(&req_slice, 1 /* number of slices */);
}
grpc_slice_unref(req_slice);
grpc_gcp_handshaker_req_destroy(req);
return buffer;
}
static tsi_result handshaker_client_start_server(alts_handshaker_client* client,
alts_tsi_event* event,
grpc_slice* bytes_received) {
if (client == nullptr || event == nullptr || bytes_received == nullptr) {
gpr_log(GPR_ERROR,
"Invalid arguments to alts_grpc_handshaker_client_start_server()");
return TSI_INVALID_ARGUMENT;
}
grpc_byte_buffer* buffer = get_serialized_start_server(event, bytes_received);
if (buffer == nullptr) {
gpr_log(GPR_ERROR, "get_serialized_start_server() failed");
return TSI_INTERNAL_ERROR;
}
event->send_buffer = buffer;
tsi_result result = make_grpc_call(client, event, true /* is_start */);
if (result != TSI_OK) {
gpr_log(GPR_ERROR, "make_grpc_call() failed");
}
return result;
}
/* Create and populate a next handshaker request, then serialize it. */
static grpc_byte_buffer* get_serialized_next(grpc_slice* bytes_received) {
GPR_ASSERT(bytes_received != nullptr);
grpc_gcp_handshaker_req* req = grpc_gcp_handshaker_req_create(NEXT_REQ);
bool ok = grpc_gcp_handshaker_req_set_in_bytes(
req, reinterpret_cast<const char*> GRPC_SLICE_START_PTR(*bytes_received),
GRPC_SLICE_LENGTH(*bytes_received));
grpc_slice req_slice;
ok &= grpc_gcp_handshaker_req_encode(req, &req_slice);
grpc_byte_buffer* buffer = nullptr;
if (ok) {
buffer = grpc_raw_byte_buffer_create(&req_slice, 1 /* number of slices */);
}
grpc_slice_unref(req_slice);
grpc_gcp_handshaker_req_destroy(req);
return buffer;
}
static tsi_result handshaker_client_next(alts_handshaker_client* client,
alts_tsi_event* event,
grpc_slice* bytes_received) {
if (client == nullptr || event == nullptr || bytes_received == nullptr) {
gpr_log(GPR_ERROR,
"Invalid arguments to alts_grpc_handshaker_client_next()");
return TSI_INVALID_ARGUMENT;
}
grpc_byte_buffer* buffer = get_serialized_next(bytes_received);
if (buffer == nullptr) {
gpr_log(GPR_ERROR, "get_serialized_next() failed");
return TSI_INTERNAL_ERROR;
}
event->send_buffer = buffer;
tsi_result result = make_grpc_call(client, event, false /* is_start */);
if (result != TSI_OK) {
gpr_log(GPR_ERROR, "make_grpc_call() failed");
}
return result;
}
static void handshaker_client_destruct(alts_handshaker_client* client) {
if (client == nullptr) {
return;
}
alts_grpc_handshaker_client* grpc_client =
reinterpret_cast<alts_grpc_handshaker_client*>(client);
grpc_call_unref(grpc_client->call);
}
static const alts_handshaker_client_vtable vtable = {
handshaker_client_start_client, handshaker_client_start_server,
handshaker_client_next, handshaker_client_destruct};
alts_handshaker_client* alts_grpc_handshaker_client_create(
grpc_channel* channel, grpc_completion_queue* queue,
const char* handshaker_service_url) {
if (channel == nullptr || queue == nullptr ||
handshaker_service_url == nullptr) {
gpr_log(GPR_ERROR, "Invalid arguments to alts_handshaker_client_create()");
return nullptr;
}
alts_grpc_handshaker_client* client =
static_cast<alts_grpc_handshaker_client*>(gpr_zalloc(sizeof(*client)));
client->grpc_caller = grpc_start_batch;
grpc_slice slice = grpc_slice_from_copied_string(handshaker_service_url);
client->call = grpc_channel_create_call(
channel, nullptr, GRPC_PROPAGATE_DEFAULTS, queue,
grpc_slice_from_static_string(ALTS_SERVICE_METHOD), &slice,
gpr_inf_future(GPR_CLOCK_REALTIME), nullptr);
client->base.vtable = &vtable;
grpc_slice_unref(slice);
return &client->base;
}
namespace grpc_core {
namespace internal {
void alts_handshaker_client_set_grpc_caller_for_testing(
alts_handshaker_client* client, alts_grpc_caller caller) {
GPR_ASSERT(client != nullptr && caller != nullptr);
alts_grpc_handshaker_client* grpc_client =
reinterpret_cast<alts_grpc_handshaker_client*>(client);
grpc_client->grpc_caller = caller;
}
} // namespace internal
} // namespace grpc_core
tsi_result alts_handshaker_client_start_client(alts_handshaker_client* client,
alts_tsi_event* event) {
if (client != nullptr && client->vtable != nullptr &&
client->vtable->client_start != nullptr) {
return client->vtable->client_start(client, event);
}
gpr_log(GPR_ERROR,
"client or client->vtable has not been initialized properly");
return TSI_INVALID_ARGUMENT;
}
tsi_result alts_handshaker_client_start_server(alts_handshaker_client* client,
alts_tsi_event* event,
grpc_slice* bytes_received) {
if (client != nullptr && client->vtable != nullptr &&
client->vtable->server_start != nullptr) {
return client->vtable->server_start(client, event, bytes_received);
}
gpr_log(GPR_ERROR,
"client or client->vtable has not been initialized properly");
return TSI_INVALID_ARGUMENT;
}
tsi_result alts_handshaker_client_next(alts_handshaker_client* client,
alts_tsi_event* event,
grpc_slice* bytes_received) {
if (client != nullptr && client->vtable != nullptr &&
client->vtable->next != nullptr) {
return client->vtable->next(client, event, bytes_received);
}
gpr_log(GPR_ERROR,
"client or client->vtable has not been initialized properly");
return TSI_INVALID_ARGUMENT;
}
void alts_handshaker_client_destroy(alts_handshaker_client* client) {
if (client != nullptr) {
if (client->vtable != nullptr && client->vtable->destruct != nullptr) {
client->vtable->destruct(client);
}
gpr_free(client);
}
}

@ -0,0 +1,137 @@
/*
*
* 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.
*
*/
#ifndef GRPC_CORE_TSI_ALTS_HANDSHAKER_ALTS_HANDSHAKER_CLIENT_H
#define GRPC_CORE_TSI_ALTS_HANDSHAKER_ALTS_HANDSHAKER_CLIENT_H
#include <grpc/support/port_platform.h>
#include <grpc/grpc.h>
#include "src/core/tsi/alts/handshaker/alts_tsi_event.h"
#define ALTS_SERVICE_METHOD "/grpc.gcp.HandshakerService/DoHandshake"
#define ALTS_APPLICATION_PROTOCOL "grpc"
#define ALTS_RECORD_PROTOCOL "ALTSRP_GCM_AES128_REKEY"
const size_t kAltsAes128GcmRekeyKeyLength = 44;
/**
* A ALTS handshaker client interface. It is used to communicate with
* ALTS handshaker service by scheduling a handshaker request that could be one
* of client_start, server_start, and next handshaker requests. All APIs in the
* header are thread-compatible.
*/
typedef struct alts_handshaker_client alts_handshaker_client;
/* A function that makes the grpc call to the handshaker service. */
typedef grpc_call_error (*alts_grpc_caller)(grpc_call* call, const grpc_op* ops,
size_t nops, void* tag);
/* V-table for ALTS handshaker client operations. */
typedef struct alts_handshaker_client_vtable {
tsi_result (*client_start)(alts_handshaker_client* client,
alts_tsi_event* event);
tsi_result (*server_start)(alts_handshaker_client* client,
alts_tsi_event* event, grpc_slice* bytes_received);
tsi_result (*next)(alts_handshaker_client* client, alts_tsi_event* event,
grpc_slice* bytes_received);
void (*destruct)(alts_handshaker_client* client);
} alts_handshaker_client_vtable;
struct alts_handshaker_client {
const alts_handshaker_client_vtable* vtable;
};
/**
* This method schedules a client_start handshaker request to ALTS handshaker
* service.
*
* - client: ALTS handshaker client instance.
* - event: ALTS TSI event instance.
*
* It returns TSI_OK on success and an error status code on failure.
*/
tsi_result alts_handshaker_client_start_client(alts_handshaker_client* client,
alts_tsi_event* event);
/**
* This method schedules a server_start handshaker request to ALTS handshaker
* service.
*
* - client: ALTS handshaker client instance.
* - event: ALTS TSI event instance.
* - bytes_received: bytes in out_frames returned from the peer's handshaker
* response.
*
* It returns TSI_OK on success and an error status code on failure.
*/
tsi_result alts_handshaker_client_start_server(alts_handshaker_client* client,
alts_tsi_event* event,
grpc_slice* bytes_received);
/**
* This method schedules a next handshaker request to ALTS handshaker service.
*
* - client: ALTS handshaker client instance.
* - event: ALTS TSI event instance.
* - bytes_received: bytes in out_frames returned from the peer's handshaker
* response.
*
* It returns TSI_OK on success and an error status code on failure.
*/
tsi_result alts_handshaker_client_next(alts_handshaker_client* client,
alts_tsi_event* event,
grpc_slice* bytes_received);
/**
* This method destroys a ALTS handshaker client.
*
* - client: a ALTS handshaker client instance.
*/
void alts_handshaker_client_destroy(alts_handshaker_client* client);
/**
* This method creates a ALTS handshaker client.
*
* - channel: grpc channel to ALTS handshaker service.
* - queue: grpc completion queue.
* - handshaker_service_url: address of ALTS handshaker service in the format of
* "host:port".
*
* It returns the created ALTS handshaker client on success, and NULL on
* failure.
*/
alts_handshaker_client* alts_grpc_handshaker_client_create(
grpc_channel* channel, grpc_completion_queue* queue,
const char* handshaker_service_url);
namespace grpc_core {
namespace internal {
/**
* Unsafe, use for testing only. It allows the caller to change the way that
* GRPC calls are made to the handshaker service.
*/
void alts_handshaker_client_set_grpc_caller_for_testing(
alts_handshaker_client* client, alts_grpc_caller caller);
} // namespace internal
} // namespace grpc_core
#endif /* GRPC_CORE_TSI_ALTS_HANDSHAKER_ALTS_HANDSHAKER_CLIENT_H */

@ -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;
}

@ -0,0 +1,323 @@
/*
*
* 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.
*
*/
#ifndef GRPC_CORE_TSI_ALTS_HANDSHAKER_ALTS_HANDSHAKER_SERVICE_API_H
#define GRPC_CORE_TSI_ALTS_HANDSHAKER_ALTS_HANDSHAKER_SERVICE_API_H
#include <grpc/support/port_platform.h>
#include "src/core/tsi/alts/handshaker/alts_handshaker_service_api_util.h"
/**
* An implementation of nanopb thin wrapper used to set/get and
* serialize/de-serialize of ALTS handshake requests and responses.
*
* All APIs in the header are thread-compatible. A typical usage of this API at
* the client side is as follows:
*
* -----------------------------------------------------------------------------
* // Create, populate, and serialize an ALTS client_start handshake request to
* // send to the server.
* grpc_gcp_handshaker_req* req =
* grpc_gcp_handshaker_req_create(CLIENT_START_REQ);
* grpc_gcp_handshaker_req_set_handshake_protocol(
req, grpc_gcp_HandshakeProtocol_ALTS);
* grpc_gcp_handshaker_req_add_application_protocol(req, "grpc");
* grpc_gcp_handshaker_req_add_record_protocol(req, "ALTSRP_GCM_AES128");
* grpc_slice client_slice;
* if (!grpc_gcp_handshaker_req_encode(req, &client_slice)) {
* fprintf(stderr, "ALTS handshake request encoding failed.";
* }
*
* // De-serialize a data stream received from the server, and store the result
* // at ALTS handshake response.
* grpc_gcp_handshaker_resp* resp = grpc_gcp_handshaker_resp_create();
* if (!grpc_gcp_handshaker_resp_decode(server_slice, resp)) {
* fprintf(stderr, "ALTS handshake response decoding failed.");
* }
* // To access a variable-length datatype field (i.e., pb_callback_t),
* // access its "arg" subfield (if it has been set).
* if (resp->out_frames.arg != nullptr) {
* grpc_slice* slice = resp->out_frames.arg;
* }
* // To access a fixed-length datatype field (i.e., not pb_calback_t),
* // access the field directly (if it has been set).
* if (resp->has_status && resp->status->has_code) {
* uint32_t code = resp->status->code;
* }
*------------------------------------------------------------------------------
*/
/**
* This method creates an ALTS handshake request.
*
* - type: an enum type value that can be either CLIENT_START_REQ,
* SERVER_START_REQ, or NEXT_REQ to indicate the created instance will be
* client_start, server_start, and next handshake request message
* respectively.
*
* The method returns a pointer to the created instance.
*/
grpc_gcp_handshaker_req* grpc_gcp_handshaker_req_create(
grpc_gcp_handshaker_req_type type);
/**
* This method sets the value for handshake_security_protocol field of ALTS
* client_start handshake request.
*
* - req: an ALTS handshake request.
* - handshake_protocol: a enum type value representing the handshake security
* protocol.
*
* The method returns true on success and false otherwise.
*/
bool grpc_gcp_handshaker_req_set_handshake_protocol(
grpc_gcp_handshaker_req* req,
grpc_gcp_handshake_protocol handshake_protocol);
/**
* This method sets the value for target_name field of ALTS client_start
* handshake request.
*
* - req: an ALTS handshake request.
* - target_name: a target name to be set.
*
* The method returns true on success and false otherwise.
*/
bool grpc_gcp_handshaker_req_set_target_name(grpc_gcp_handshaker_req* req,
const char* target_name);
/**
* This method adds an application protocol supported by the server (or
* client) to ALTS server_start (or client_start) handshake request.
*
* - req: an ALTS handshake request.
* - application_protocol: an application protocol (e.g., grpc) to be added.
*
* The method returns true on success and false otherwise.
*/
bool grpc_gcp_handshaker_req_add_application_protocol(
grpc_gcp_handshaker_req* req, const char* application_protocol);
/**
* This method adds a record protocol supported by the client to ALTS
* client_start handshake request.
*
* - req: an ALTS handshake request.
* - record_protocol: a record protocol (e.g., ALTSRP_GCM_AES128) to be
* added.
*
* The method returns true on success and false otherwise.
*/
bool grpc_gcp_handshaker_req_add_record_protocol(grpc_gcp_handshaker_req* req,
const char* record_protocol);
/**
* This method adds a target server identity represented as hostname and
* acceptable by a client to ALTS client_start handshake request.
*
* - req: an ALTS handshake request.
* - hostname: a string representation of hostname at the connection
* endpoint to be added.
*
* The method returns true on success and false otherwise.
*/
bool grpc_gcp_handshaker_req_add_target_identity_hostname(
grpc_gcp_handshaker_req* req, const char* hostname);
/**
* This method adds a target server identity represented as service account and
* acceptable by a client to ALTS client_start handshake request.
*
* - req: an ALTS handshake request.
* - service_account: a string representation of service account at the
* connection endpoint to be added.
*
* The method returns true on success and false otherwise.
*/
bool grpc_gcp_handshaker_req_add_target_identity_service_account(
grpc_gcp_handshaker_req* req, const char* service_account);
/**
* This method sets the hostname for local_identity field of ALTS client_start
* handshake request.
*
* - req: an ALTS handshake request.
* - hostname: a string representation of hostname.
*
* The method returns true on success and false otherwise.
*/
bool grpc_gcp_handshaker_req_set_local_identity_hostname(
grpc_gcp_handshaker_req* req, const char* hostname);
/**
* This method sets the service account for local_identity field of ALTS
* client_start handshake request.
*
* - req: an ALTS handshake request.
* - service_account: a string representation of service account.
*
* The method returns true on success and false otherwise.
*/
bool grpc_gcp_handshaker_req_set_local_identity_service_account(
grpc_gcp_handshaker_req* req, const char* service_account);
/**
* This method sets the value for local_endpoint field of either ALTS
* client_start or server_start handshake request.
*
* - req: an ALTS handshake request.
* - ip_address: a string representation of ip address associated with the
* local endpoint, that could be either IPv4 or IPv6.
* - port: a port number associated with the local endpoint.
* - protocol: a network protocol (e.g., TCP or UDP) associated with the
* local endpoint.
*
* The method returns true on success and false otherwise.
*/
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);
/**
* This method sets the value for remote_endpoint field of either ALTS
* client_start or server_start handshake request.
*
* - req: an ALTS handshake request.
* - ip_address: a string representation of ip address associated with the
* remote endpoint, that could be either IPv4 or IPv6.
* - port: a port number associated with the remote endpoint.
* - protocol: a network protocol (e.g., TCP or UDP) associated with the
* remote endpoint.
*
* The method returns true on success and false otherwise.
*/
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);
/**
* This method sets the value for in_bytes field of either ALTS server_start or
* next handshake request.
*
* - req: an ALTS handshake request.
* - in_bytes: a buffer containing bytes taken from out_frames of the peer's
* ALTS handshake response. It is possible that the peer's out_frames are
* split into multiple handshake request messages.
* - size: size of in_bytes buffer.
*
* The method returns true on success and false otherwise.
*/
bool grpc_gcp_handshaker_req_set_in_bytes(grpc_gcp_handshaker_req* req,
const char* in_bytes, size_t size);
/**
* This method adds a record protocol to handshake parameters mapped by the
* handshake protocol for ALTS server_start handshake request.
*
* - req: an ALTS handshake request.
* - key: an enum type value representing a handshake security protocol.
* - record_protocol: a record protocol to be added.
*
* The method returns true on success and false otherwise.
*/
bool grpc_gcp_handshaker_req_param_add_record_protocol(
grpc_gcp_handshaker_req* req, grpc_gcp_handshake_protocol key,
const char* record_protocol);
/**
* This method adds a local identity represented as hostname to handshake
* parameters mapped by the handshake protocol for ALTS server_start handshake
* request.
*
* - req: an ALTS handshake request.
* - key: an enum type value representing a handshake security protocol.
* - hostname: a string representation of hostname to be added.
*
* The method returns true on success and false otherwise.
*/
bool grpc_gcp_handshaker_req_param_add_local_identity_hostname(
grpc_gcp_handshaker_req* req, grpc_gcp_handshake_protocol key,
const char* hostname);
/**
* This method adds a local identity represented as service account to handshake
* parameters mapped by the handshake protocol for ALTS server_start handshake
* request.
*
* - req: an ALTS handshake request.
* - key: an enum type value representing a handshake security protocol.
* - service_account: a string representation of service account to be added.
*
* The method returns true on success and false otherwise.
*/
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);
/**
* This method sets the value for rpc_versions field of either ALTS
* client_start or server_start handshake request.
*
* - req: an ALTS handshake request.
* - max_major: a major version of maximum supported RPC version.
* - max_minor: a minor version of maximum supported RPC version.
* - min_major: a major version of minimum supported RPC version.
* - min_minor: a minor version of minimum supported RPC version.
*
* The method returns true on success and false otherwise.
*/
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);
/**
* This method serializes an ALTS handshake request and returns a data stream.
*
* - req: an ALTS handshake request.
* - slice: a data stream where the serialized result will be written.
*
* The method returns true on success and false otherwise.
*/
bool grpc_gcp_handshaker_req_encode(grpc_gcp_handshaker_req* req,
grpc_slice* slice);
/* This method destroys an ALTS handshake request. */
void grpc_gcp_handshaker_req_destroy(grpc_gcp_handshaker_req* req);
/* This method creates an ALTS handshake response. */
grpc_gcp_handshaker_resp* grpc_gcp_handshaker_resp_create(void);
/**
* This method de-serializes a data stream and stores the result
* in an ALTS handshake response.
*
* - slice: a data stream containing a serialized ALTS handshake response.
* - resp: an ALTS handshake response used to hold de-serialized result.
*
* The method returns true on success and false otherwise.
*/
bool grpc_gcp_handshaker_resp_decode(grpc_slice slice,
grpc_gcp_handshaker_resp* resp);
/* This method destroys an ALTS handshake response. */
void grpc_gcp_handshaker_resp_destroy(grpc_gcp_handshaker_resp* resp);
#endif /* GRPC_CORE_TSI_ALTS_HANDSHAKER_ALTS_HANDSHAKER_SERVICE_API_H */

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

@ -0,0 +1,149 @@
/*
*
* 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.
*
*/
#ifndef GRPC_CORE_TSI_ALTS_HANDSHAKER_ALTS_HANDSHAKER_SERVICE_API_UTIL_H
#define GRPC_CORE_TSI_ALTS_HANDSHAKER_ALTS_HANDSHAKER_SERVICE_API_UTIL_H
#include <grpc/support/port_platform.h>
#include "third_party/nanopb/pb_decode.h"
#include "third_party/nanopb/pb_encode.h"
#include <grpc/slice.h>
#include <grpc/slice_buffer.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include "src/core/tsi/alts/handshaker/handshaker.pb.h"
/**
* An implementation of utility functions used to serialize/
* de-serialize ALTS handshake requests/responses. All APIs in the header
* are thread-compatible.
*/
/* Renaming of message/field structs generated by nanopb compiler. */
typedef grpc_gcp_HandshakeProtocol grpc_gcp_handshake_protocol;
typedef grpc_gcp_NetworkProtocol grpc_gcp_network_protocol;
typedef grpc_gcp_Identity grpc_gcp_identity;
typedef grpc_gcp_NextHandshakeMessageReq grpc_gcp_next_handshake_message_req;
typedef grpc_gcp_ServerHandshakeParameters grpc_gcp_server_handshake_parameters;
typedef grpc_gcp_Endpoint grpc_gcp_endpoint;
typedef grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry
grpc_gcp_handshake_parameters_entry;
typedef grpc_gcp_StartClientHandshakeReq grpc_gcp_start_client_handshake_req;
typedef grpc_gcp_StartServerHandshakeReq grpc_gcp_start_server_handshake_req;
typedef grpc_gcp_HandshakerReq grpc_gcp_handshaker_req;
typedef grpc_gcp_HandshakerResult grpc_gcp_handshaker_result;
typedef grpc_gcp_HandshakerStatus grpc_gcp_handshaker_status;
typedef grpc_gcp_HandshakerResp grpc_gcp_handshaker_resp;
typedef enum {
CLIENT_START_REQ = 0, /* StartClientHandshakeReq. */
SERVER_START_REQ = 1, /* StartServerHandshakeReq. */
NEXT_REQ = 2, /* NextHandshakeMessageReq. */
} grpc_gcp_handshaker_req_type;
/**
* A struct representing a repeated field. The struct is used to organize all
* instances of a specific repeated field into a linked list, which then will
* be used at encode/decode phase. For instance at the encode phase, the encode
* function will iterate through the list, encode each field, and then output
* the result to the stream.
*/
typedef struct repeated_field_ {
struct repeated_field_* next;
const void* data;
} repeated_field;
/**
* This method adds a repeated field to the head of repeated field list.
*
* - head: a head of repeated field list.
* - field: a repeated field to be added to the list.
*/
void add_repeated_field(repeated_field** head, const void* field);
/**
* This method destroys a repeated field list that consists of string type
* fields.
*
* - head: a head of repeated field list.
*/
void destroy_repeated_field_list_string(repeated_field* head);
/**
* This method destroys a repeated field list that consists of
* grpc_gcp_identity type fields.
*
* - head: a head of repeated field list.
*/
void destroy_repeated_field_list_identity(repeated_field* head);
/**
* This method creates a grpc_slice instance by copying a data buffer. It is
* similar to grpc_slice_from_copied_buffer() except that it returns an instance
* allocated from the heap.
*
* - data: a data buffer to be copied to grpc_slice instance.
* - size: size of data buffer.
*/
grpc_slice* create_slice(const char* data, size_t size);
/* This method destroys a grpc_slice instance. */
void destroy_slice(grpc_slice* slice);
/**
* The following encode/decode functions will be assigned to encode/decode
* function pointers of pb_callback_t struct (defined in
* //third_party/nanopb/pb.h), that represent a repeated field with a dynamic
* length (e.g., a string type or repeated field).
*/
/* This method is an encode callback function for a string or byte array. */
bool encode_string_or_bytes_cb(pb_ostream_t* stream, const pb_field_t* field,
void* const* arg);
/**
* This method is an encode callback function for a repeated grpc_gcp_identity
* field.
*/
bool encode_repeated_identity_cb(pb_ostream_t* stream, const pb_field_t* field,
void* const* arg);
/* This method is an encode callback function for a repeated string field. */
bool encode_repeated_string_cb(pb_ostream_t* stream, const pb_field_t* field,
void* const* arg);
/**
* This method is a decode callback function for a string or byte array field.
*/
bool decode_string_or_bytes_cb(pb_istream_t* stream, const pb_field_t* field,
void** arg);
/**
* This method is a decode callback function for a repeated grpc_gcp_identity
* field.
*/
bool decode_repeated_identity_cb(pb_istream_t* stream, const pb_field_t* field,
void** arg);
/* This method is a decode callback function for a repeated string field. */
bool decode_repeated_string_cb(pb_istream_t* stream, const pb_field_t* field,
void** arg);
#endif /* GRPC_CORE_TSI_ALTS_HANDSHAKER_ALTS_HANDSHAKER_SERVICE_API_UTIL_H */

@ -0,0 +1,73 @@
/*
*
* 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_tsi_event.h"
#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
tsi_result alts_tsi_event_create(alts_tsi_handshaker* handshaker,
tsi_handshaker_on_next_done_cb cb,
void* user_data,
grpc_alts_credentials_options* options,
grpc_slice target_name,
alts_tsi_event** event) {
if (event == nullptr || handshaker == nullptr || cb == nullptr) {
gpr_log(GPR_ERROR, "Invalid arguments to alts_tsi_event_create()");
return TSI_INVALID_ARGUMENT;
}
alts_tsi_event* e = static_cast<alts_tsi_event*>(gpr_zalloc(sizeof(*e)));
e->handshaker = handshaker;
e->cb = cb;
e->user_data = user_data;
e->options = grpc_alts_credentials_options_copy(options);
e->target_name = grpc_slice_copy(target_name);
grpc_metadata_array_init(&e->initial_metadata);
grpc_metadata_array_init(&e->trailing_metadata);
*event = e;
return TSI_OK;
}
void alts_tsi_event_dispatch_to_handshaker(alts_tsi_event* event, bool is_ok) {
if (event == nullptr) {
gpr_log(
GPR_ERROR,
"ALTS TSI event is nullptr in alts_tsi_event_dispatch_to_handshaker()");
return;
}
alts_tsi_handshaker_handle_response(event->handshaker, event->recv_buffer,
event->status, &event->details, event->cb,
event->user_data, is_ok);
}
void alts_tsi_event_destroy(alts_tsi_event* event) {
if (event == nullptr) {
return;
}
grpc_byte_buffer_destroy(event->send_buffer);
grpc_byte_buffer_destroy(event->recv_buffer);
grpc_metadata_array_destroy(&event->initial_metadata);
grpc_metadata_array_destroy(&event->trailing_metadata);
grpc_slice_unref(event->details);
grpc_slice_unref(event->target_name);
grpc_alts_credentials_options_destroy(event->options);
gpr_free(event);
}

@ -0,0 +1,93 @@
/*
*
* 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.
*
*/
#ifndef GRPC_CORE_TSI_ALTS_HANDSHAKER_ALTS_TSI_EVENT_H
#define GRPC_CORE_TSI_ALTS_HANDSHAKER_ALTS_TSI_EVENT_H
#include <grpc/support/port_platform.h>
#include <grpc/byte_buffer.h>
#include <grpc/byte_buffer_reader.h>
#include "src/core/tsi/alts/handshaker/alts_tsi_handshaker.h"
#include "src/core/tsi/transport_security_interface.h"
/**
* A ALTS TSI event interface. In asynchronous implementation of
* tsi_handshaker_next(), the function will exit after scheduling a handshaker
* request to ALTS handshaker service without waiting for response to return.
* The event is used to link the scheduled handshaker request with the
* corresponding response so that enough context information can be inferred
* from it to handle the response. All APIs in the header are thread-compatible.
*/
/**
* Main struct for ALTS TSI event. It retains ownership on send_buffer and
* recv_buffer, but not on handshaker.
*/
typedef struct alts_tsi_event {
alts_tsi_handshaker* handshaker;
grpc_byte_buffer* send_buffer;
grpc_byte_buffer* recv_buffer;
grpc_status_code status;
grpc_slice details;
grpc_metadata_array initial_metadata;
grpc_metadata_array trailing_metadata;
tsi_handshaker_on_next_done_cb cb;
void* user_data;
grpc_alts_credentials_options* options;
grpc_slice target_name;
} alts_tsi_event;
/**
* This method creates a ALTS TSI event.
*
* - handshaker: ALTS TSI handshaker instance associated with the event to be
* created. The created event does not own the handshaker instance.
* - cb: callback function to be called when handling data received from ALTS
* handshaker service.
* - user_data: argument to callback function.
* - options: ALTS credentials options.
* - target_name: name of endpoint used for secure naming check.
* - event: address of ALTS TSI event instance to be returned from the method.
*
* It returns TSI_OK on success and an error status code on failure.
*/
tsi_result alts_tsi_event_create(alts_tsi_handshaker* handshaker,
tsi_handshaker_on_next_done_cb cb,
void* user_data,
grpc_alts_credentials_options* options,
grpc_slice target_name,
alts_tsi_event** event);
/**
* This method dispatches a ALTS TSI event received from the handshaker service,
* and a boolean flag indicating if the event is valid to read to ALTS TSI
* handshaker to process. It is called by TSI thread.
*
* - event: ALTS TSI event instance.
* - is_ok: a boolean value indicating if the event is valid to read.
*/
void alts_tsi_event_dispatch_to_handshaker(alts_tsi_event* event, bool is_ok);
/**
* This method destroys the ALTS TSI event.
*/
void alts_tsi_event_destroy(alts_tsi_event* event);
#endif /* GRPC_CORE_TSI_ALTS_HANDSHAKER_ALTS_TSI_EVENT_H */

@ -0,0 +1,483 @@
/*
*
* 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_tsi_handshaker.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
#include <grpc/support/thd_id.h>
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gprpp/thd.h"
#include "src/core/tsi/alts/frame_protector/alts_frame_protector.h"
#include "src/core/tsi/alts/handshaker/alts_handshaker_client.h"
#include "src/core/tsi/alts/handshaker/alts_tsi_utils.h"
#include "src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.h"
#include "src/core/tsi/alts_transport_security.h"
#define TSI_ALTS_INITIAL_BUFFER_SIZE 256
static alts_shared_resource* kSharedResource = alts_get_shared_resource();
/* Main struct for ALTS TSI handshaker. */
typedef struct alts_tsi_handshaker {
tsi_handshaker base;
alts_handshaker_client* client;
grpc_slice recv_bytes;
grpc_slice target_name;
unsigned char* buffer;
size_t buffer_size;
bool is_client;
bool has_sent_start_message;
grpc_alts_credentials_options* options;
} alts_tsi_handshaker;
/* Main struct for ALTS TSI handshaker result. */
typedef struct alts_tsi_handshaker_result {
tsi_handshaker_result base;
char* peer_identity;
char* key_data;
unsigned char* unused_bytes;
size_t unused_bytes_size;
grpc_slice rpc_versions;
bool is_client;
} alts_tsi_handshaker_result;
static tsi_result handshaker_result_extract_peer(
const tsi_handshaker_result* self, tsi_peer* peer) {
if (self == nullptr || peer == nullptr) {
gpr_log(GPR_ERROR, "Invalid argument to handshaker_result_extract_peer()");
return TSI_INVALID_ARGUMENT;
}
alts_tsi_handshaker_result* result =
reinterpret_cast<alts_tsi_handshaker_result*>(
const_cast<tsi_handshaker_result*>(self));
GPR_ASSERT(kTsiAltsNumOfPeerProperties == 3);
tsi_result ok = tsi_construct_peer(kTsiAltsNumOfPeerProperties, peer);
int index = 0;
if (ok != TSI_OK) {
gpr_log(GPR_ERROR, "Failed to construct tsi peer");
return ok;
}
GPR_ASSERT(&peer->properties[index] != nullptr);
ok = tsi_construct_string_peer_property_from_cstring(
TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_ALTS_CERTIFICATE_TYPE,
&peer->properties[index]);
if (ok != TSI_OK) {
tsi_peer_destruct(peer);
gpr_log(GPR_ERROR, "Failed to set tsi peer property");
return ok;
}
index++;
GPR_ASSERT(&peer->properties[index] != nullptr);
ok = tsi_construct_string_peer_property_from_cstring(
TSI_ALTS_SERVICE_ACCOUNT_PEER_PROPERTY, result->peer_identity,
&peer->properties[index]);
if (ok != TSI_OK) {
tsi_peer_destruct(peer);
gpr_log(GPR_ERROR, "Failed to set tsi peer property");
}
index++;
GPR_ASSERT(&peer->properties[index] != nullptr);
ok = tsi_construct_string_peer_property(
TSI_ALTS_RPC_VERSIONS,
reinterpret_cast<char*>(GRPC_SLICE_START_PTR(result->rpc_versions)),
GRPC_SLICE_LENGTH(result->rpc_versions), &peer->properties[2]);
if (ok != TSI_OK) {
tsi_peer_destruct(peer);
gpr_log(GPR_ERROR, "Failed to set tsi peer property");
}
GPR_ASSERT(++index == kTsiAltsNumOfPeerProperties);
return ok;
}
static tsi_result handshaker_result_create_zero_copy_grpc_protector(
const tsi_handshaker_result* self, size_t* max_output_protected_frame_size,
tsi_zero_copy_grpc_protector** protector) {
if (self == nullptr || protector == nullptr) {
gpr_log(GPR_ERROR,
"Invalid arguments to create_zero_copy_grpc_protector()");
return TSI_INVALID_ARGUMENT;
}
alts_tsi_handshaker_result* result =
reinterpret_cast<alts_tsi_handshaker_result*>(
const_cast<tsi_handshaker_result*>(self));
tsi_result ok = alts_zero_copy_grpc_protector_create(
reinterpret_cast<const uint8_t*>(result->key_data),
kAltsAes128GcmRekeyKeyLength, /*is_rekey=*/true, result->is_client,
/*is_integrity_only=*/false, max_output_protected_frame_size, protector);
if (ok != TSI_OK) {
gpr_log(GPR_ERROR, "Failed to create zero-copy grpc protector");
}
return ok;
}
static tsi_result handshaker_result_create_frame_protector(
const tsi_handshaker_result* self, size_t* max_output_protected_frame_size,
tsi_frame_protector** protector) {
if (self == nullptr || protector == nullptr) {
gpr_log(GPR_ERROR,
"Invalid arguments to handshaker_result_create_frame_protector()");
return TSI_INVALID_ARGUMENT;
}
alts_tsi_handshaker_result* result =
reinterpret_cast<alts_tsi_handshaker_result*>(
const_cast<tsi_handshaker_result*>(self));
tsi_result ok = alts_create_frame_protector(
reinterpret_cast<const uint8_t*>(result->key_data),
kAltsAes128GcmRekeyKeyLength, result->is_client, /*is_rekey=*/true,
max_output_protected_frame_size, protector);
if (ok != TSI_OK) {
gpr_log(GPR_ERROR, "Failed to create frame protector");
}
return ok;
}
static tsi_result handshaker_result_get_unused_bytes(
const tsi_handshaker_result* self, const unsigned char** bytes,
size_t* bytes_size) {
if (self == nullptr || bytes == nullptr || bytes_size == nullptr) {
gpr_log(GPR_ERROR,
"Invalid arguments to handshaker_result_get_unused_bytes()");
return TSI_INVALID_ARGUMENT;
}
alts_tsi_handshaker_result* result =
reinterpret_cast<alts_tsi_handshaker_result*>(
const_cast<tsi_handshaker_result*>(self));
*bytes = result->unused_bytes;
*bytes_size = result->unused_bytes_size;
return TSI_OK;
}
static void handshaker_result_destroy(tsi_handshaker_result* self) {
if (self == nullptr) {
return;
}
alts_tsi_handshaker_result* result =
reinterpret_cast<alts_tsi_handshaker_result*>(
const_cast<tsi_handshaker_result*>(self));
gpr_free(result->peer_identity);
gpr_free(result->key_data);
gpr_free(result->unused_bytes);
grpc_slice_unref(result->rpc_versions);
gpr_free(result);
}
static const tsi_handshaker_result_vtable result_vtable = {
handshaker_result_extract_peer,
handshaker_result_create_zero_copy_grpc_protector,
handshaker_result_create_frame_protector,
handshaker_result_get_unused_bytes, handshaker_result_destroy};
static tsi_result create_handshaker_result(grpc_gcp_handshaker_resp* resp,
bool is_client,
tsi_handshaker_result** self) {
if (self == nullptr || resp == nullptr) {
gpr_log(GPR_ERROR, "Invalid arguments to create_handshaker_result()");
return TSI_INVALID_ARGUMENT;
}
grpc_slice* key = static_cast<grpc_slice*>(resp->result.key_data.arg);
GPR_ASSERT(key != nullptr);
grpc_slice* identity =
static_cast<grpc_slice*>(resp->result.peer_identity.service_account.arg);
if (identity == nullptr) {
gpr_log(GPR_ERROR, "Invalid service account");
return TSI_FAILED_PRECONDITION;
}
if (GRPC_SLICE_LENGTH(*key) < kAltsAes128GcmRekeyKeyLength) {
gpr_log(GPR_ERROR, "Bad key length");
return TSI_FAILED_PRECONDITION;
}
alts_tsi_handshaker_result* result =
static_cast<alts_tsi_handshaker_result*>(gpr_zalloc(sizeof(*result)));
result->key_data =
static_cast<char*>(gpr_zalloc(kAltsAes128GcmRekeyKeyLength));
memcpy(result->key_data, GRPC_SLICE_START_PTR(*key),
kAltsAes128GcmRekeyKeyLength);
result->peer_identity = grpc_slice_to_c_string(*identity);
if (!resp->result.has_peer_rpc_versions) {
gpr_log(GPR_ERROR, "Peer does not set RPC protocol versions.");
return TSI_FAILED_PRECONDITION;
}
if (!grpc_gcp_rpc_protocol_versions_encode(&resp->result.peer_rpc_versions,
&result->rpc_versions)) {
gpr_log(GPR_ERROR, "Failed to serialize peer's RPC protocol versions.");
return TSI_FAILED_PRECONDITION;
}
result->is_client = is_client;
result->base.vtable = &result_vtable;
*self = &result->base;
return TSI_OK;
}
static tsi_result handshaker_next(
tsi_handshaker* self, const unsigned char* received_bytes,
size_t received_bytes_size, const unsigned char** bytes_to_send,
size_t* bytes_to_send_size, tsi_handshaker_result** result,
tsi_handshaker_on_next_done_cb cb, void* user_data) {
if (self == nullptr || cb == nullptr) {
gpr_log(GPR_ERROR, "Invalid arguments to handshaker_next()");
return TSI_INVALID_ARGUMENT;
}
alts_tsi_handshaker* handshaker =
reinterpret_cast<alts_tsi_handshaker*>(self);
tsi_result ok = TSI_OK;
alts_tsi_event* event = nullptr;
ok = alts_tsi_event_create(handshaker, cb, user_data, handshaker->options,
handshaker->target_name, &event);
if (ok != TSI_OK) {
gpr_log(GPR_ERROR, "Failed to create ALTS TSI event");
return ok;
}
grpc_slice slice = (received_bytes == nullptr || received_bytes_size == 0)
? grpc_empty_slice()
: grpc_slice_from_copied_buffer(
reinterpret_cast<const char*>(received_bytes),
received_bytes_size);
if (!handshaker->has_sent_start_message) {
ok = handshaker->is_client
? alts_handshaker_client_start_client(handshaker->client, event)
: alts_handshaker_client_start_server(handshaker->client, event,
&slice);
handshaker->has_sent_start_message = true;
} else {
if (!GRPC_SLICE_IS_EMPTY(handshaker->recv_bytes)) {
grpc_slice_unref(handshaker->recv_bytes);
}
handshaker->recv_bytes = grpc_slice_ref(slice);
ok = alts_handshaker_client_next(handshaker->client, event, &slice);
}
grpc_slice_unref(slice);
if (ok != TSI_OK) {
gpr_log(GPR_ERROR, "Failed to schedule ALTS handshaker requests");
return ok;
}
return TSI_ASYNC;
}
static void handshaker_destroy(tsi_handshaker* self) {
if (self == nullptr) {
return;
}
alts_tsi_handshaker* handshaker =
reinterpret_cast<alts_tsi_handshaker*>(self);
alts_handshaker_client_destroy(handshaker->client);
grpc_slice_unref(handshaker->recv_bytes);
grpc_slice_unref(handshaker->target_name);
grpc_alts_credentials_options_destroy(handshaker->options);
gpr_free(handshaker->buffer);
gpr_free(handshaker);
}
static const tsi_handshaker_vtable handshaker_vtable = {
nullptr, nullptr, nullptr, nullptr, nullptr, handshaker_destroy,
handshaker_next};
static void thread_worker(void* arg) {
while (true) {
grpc_event event = grpc_completion_queue_next(
kSharedResource->cq, gpr_inf_future(GPR_CLOCK_REALTIME), nullptr);
GPR_ASSERT(event.type != GRPC_QUEUE_TIMEOUT);
if (event.type == GRPC_QUEUE_SHUTDOWN) {
/* signal alts_tsi_shutdown() to destroy completion queue. */
grpc_tsi_alts_signal_for_cq_destroy();
break;
}
/* event.type == GRPC_OP_COMPLETE. */
alts_tsi_event* alts_event = static_cast<alts_tsi_event*>(event.tag);
alts_tsi_event_dispatch_to_handshaker(alts_event, event.success);
alts_tsi_event_destroy(alts_event);
}
}
static void init_shared_resources(const char* handshaker_service_url) {
GPR_ASSERT(handshaker_service_url != nullptr);
gpr_mu_lock(&kSharedResource->mu);
if (kSharedResource->channel == nullptr) {
gpr_cv_init(&kSharedResource->cv);
kSharedResource->channel =
grpc_insecure_channel_create(handshaker_service_url, nullptr, nullptr);
kSharedResource->cq = grpc_completion_queue_create_for_next(nullptr);
kSharedResource->thread =
grpc_core::Thread("alts_tsi_handshaker", &thread_worker, nullptr);
kSharedResource->thread.Start();
}
gpr_mu_unlock(&kSharedResource->mu);
}
tsi_result alts_tsi_handshaker_create(
const grpc_alts_credentials_options* options, const char* target_name,
const char* handshaker_service_url, bool is_client, tsi_handshaker** self) {
if (handshaker_service_url == nullptr || self == nullptr ||
options == nullptr || (is_client && target_name == nullptr)) {
gpr_log(GPR_ERROR, "Invalid arguments to alts_tsi_handshaker_create()");
return TSI_INVALID_ARGUMENT;
}
init_shared_resources(handshaker_service_url);
alts_handshaker_client* client = alts_grpc_handshaker_client_create(
kSharedResource->channel, kSharedResource->cq, handshaker_service_url);
if (client == nullptr) {
gpr_log(GPR_ERROR, "Failed to create ALTS handshaker client");
return TSI_FAILED_PRECONDITION;
}
alts_tsi_handshaker* handshaker =
static_cast<alts_tsi_handshaker*>(gpr_zalloc(sizeof(*handshaker)));
handshaker->client = client;
handshaker->buffer_size = TSI_ALTS_INITIAL_BUFFER_SIZE;
handshaker->buffer =
static_cast<unsigned char*>(gpr_zalloc(handshaker->buffer_size));
handshaker->is_client = is_client;
handshaker->has_sent_start_message = false;
handshaker->target_name = target_name == nullptr
? grpc_empty_slice()
: grpc_slice_from_static_string(target_name);
handshaker->options = grpc_alts_credentials_options_copy(options);
handshaker->base.vtable = &handshaker_vtable;
*self = &handshaker->base;
return TSI_OK;
}
static bool is_handshake_finished_properly(grpc_gcp_handshaker_resp* resp) {
GPR_ASSERT(resp != nullptr);
if (resp->has_result) {
return true;
}
return false;
}
static void set_unused_bytes(tsi_handshaker_result* self,
grpc_slice* recv_bytes, size_t bytes_consumed) {
GPR_ASSERT(recv_bytes != nullptr && self != nullptr);
if (GRPC_SLICE_LENGTH(*recv_bytes) == bytes_consumed) {
return;
}
alts_tsi_handshaker_result* result =
reinterpret_cast<alts_tsi_handshaker_result*>(self);
result->unused_bytes_size = GRPC_SLICE_LENGTH(*recv_bytes) - bytes_consumed;
result->unused_bytes =
static_cast<unsigned char*>(gpr_zalloc(result->unused_bytes_size));
memcpy(result->unused_bytes,
GRPC_SLICE_START_PTR(*recv_bytes) + bytes_consumed,
result->unused_bytes_size);
}
void alts_tsi_handshaker_handle_response(alts_tsi_handshaker* handshaker,
grpc_byte_buffer* recv_buffer,
grpc_status_code status,
grpc_slice* details,
tsi_handshaker_on_next_done_cb cb,
void* user_data, bool is_ok) {
/* Invalid input check. */
if (cb == nullptr) {
gpr_log(GPR_ERROR,
"cb is nullptr in alts_tsi_handshaker_handle_response()");
return;
}
if (handshaker == nullptr || recv_buffer == nullptr) {
gpr_log(GPR_ERROR,
"Invalid arguments to alts_tsi_handshaker_handle_response()");
cb(TSI_INTERNAL_ERROR, user_data, nullptr, 0, nullptr);
return;
}
/* Failed grpc call check. */
if (!is_ok || status != GRPC_STATUS_OK) {
gpr_log(GPR_ERROR, "grpc call made to handshaker service failed");
if (details != nullptr) {
char* error_details = grpc_slice_to_c_string(*details);
gpr_log(GPR_ERROR, "error details:%s", error_details);
gpr_free(error_details);
}
cb(TSI_INTERNAL_ERROR, user_data, nullptr, 0, nullptr);
return;
}
grpc_gcp_handshaker_resp* resp =
alts_tsi_utils_deserialize_response(recv_buffer);
/* Invalid handshaker response check. */
if (resp == nullptr) {
gpr_log(GPR_ERROR, "alts_tsi_utils_deserialize_response() failed");
cb(TSI_DATA_CORRUPTED, user_data, nullptr, 0, nullptr);
return;
}
grpc_slice* slice = static_cast<grpc_slice*>(resp->out_frames.arg);
unsigned char* bytes_to_send = nullptr;
size_t bytes_to_send_size = 0;
if (slice != nullptr) {
bytes_to_send_size = GRPC_SLICE_LENGTH(*slice);
while (bytes_to_send_size > handshaker->buffer_size) {
handshaker->buffer_size *= 2;
handshaker->buffer = static_cast<unsigned char*>(
gpr_realloc(handshaker->buffer, handshaker->buffer_size));
}
memcpy(handshaker->buffer, GRPC_SLICE_START_PTR(*slice),
bytes_to_send_size);
bytes_to_send = handshaker->buffer;
}
tsi_handshaker_result* result = nullptr;
if (is_handshake_finished_properly(resp)) {
create_handshaker_result(resp, handshaker->is_client, &result);
set_unused_bytes(result, &handshaker->recv_bytes, resp->bytes_consumed);
}
grpc_status_code code = static_cast<grpc_status_code>(resp->status.code);
grpc_gcp_handshaker_resp_destroy(resp);
cb(alts_tsi_utils_convert_to_tsi_result(code), user_data, bytes_to_send,
bytes_to_send_size, result);
}
namespace grpc_core {
namespace internal {
bool alts_tsi_handshaker_get_has_sent_start_message_for_testing(
alts_tsi_handshaker* handshaker) {
GPR_ASSERT(handshaker != nullptr);
return handshaker->has_sent_start_message;
}
bool alts_tsi_handshaker_get_is_client_for_testing(
alts_tsi_handshaker* handshaker) {
GPR_ASSERT(handshaker != nullptr);
return handshaker->is_client;
}
void alts_tsi_handshaker_set_recv_bytes_for_testing(
alts_tsi_handshaker* handshaker, grpc_slice* slice) {
GPR_ASSERT(handshaker != nullptr && slice != nullptr);
handshaker->recv_bytes = grpc_slice_ref(*slice);
}
grpc_slice alts_tsi_handshaker_get_recv_bytes_for_testing(
alts_tsi_handshaker* handshaker) {
GPR_ASSERT(handshaker != nullptr);
return handshaker->recv_bytes;
}
void alts_tsi_handshaker_set_client_for_testing(
alts_tsi_handshaker* handshaker, alts_handshaker_client* client) {
GPR_ASSERT(handshaker != nullptr && client != nullptr);
alts_handshaker_client_destroy(handshaker->client);
handshaker->client = client;
}
} // namespace internal
} // namespace grpc_core

@ -0,0 +1,83 @@
/*
*
* 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.
*
*/
#ifndef GRPC_CORE_TSI_ALTS_HANDSHAKER_ALTS_TSI_HANDSHAKER_H
#define GRPC_CORE_TSI_ALTS_HANDSHAKER_ALTS_TSI_HANDSHAKER_H
#include <grpc/support/port_platform.h>
#include <grpc/grpc.h>
#include "src/core/lib/security/credentials/alts/grpc_alts_credentials_options.h"
#include "src/core/tsi/alts_transport_security.h"
#include "src/core/tsi/transport_security.h"
#include "src/core/tsi/transport_security_interface.h"
#define TSI_ALTS_SERVICE_ACCOUNT_PEER_PROPERTY "service_accont"
#define TSI_ALTS_CERTIFICATE_TYPE "ALTS"
#define TSI_ALTS_RPC_VERSIONS "rpc_versions"
const size_t kTsiAltsNumOfPeerProperties = 3;
/**
* Main struct for ALTS TSI handshaker. All APIs in the header are
* thread-comptabile.
*/
typedef struct alts_tsi_handshaker alts_tsi_handshaker;
/**
* This method creates a ALTS TSI handshaker instance.
*
* - options: ALTS credentials options containing information passed from TSI
* caller (e.g., rpc protocol versions).
* - target_name: the name of the endpoint that the channel is connecting to,
* and will be used for secure naming check.
* - handshaker_service_url: address of ALTS handshaker service in the format of
* "host:port".
* - is_client: boolean value indicating if the handshaker is used at the client
* (is_client = true) or server (is_client = false) side.
* - self: address of ALTS TSI handshaker instance to be returned from the
* method.
*
* It returns TSI_OK on success and an error status code on failure.
*/
tsi_result alts_tsi_handshaker_create(
const grpc_alts_credentials_options* options, const char* target_name,
const char* handshaker_service_url, bool is_client, tsi_handshaker** self);
/**
* This method handles handshaker response returned from ALTS handshaker
* service.
*
* - handshaker: ALTS TSI handshaker instance.
* - recv_buffer: buffer holding data received from the handshaker service.
* - status: status of the grpc call made to the handshaker service.
* - details: error details of the grpc call made to the handshaker service.
* - cb: callback function of ALTS TSI event.
* - user_data: argument of callback function.
* - is_ok: a boolean value indicating if the handshaker response is ok to read.
*
*/
void alts_tsi_handshaker_handle_response(alts_tsi_handshaker* handshaker,
grpc_byte_buffer* recv_buffer,
grpc_status_code status,
grpc_slice* details,
tsi_handshaker_on_next_done_cb cb,
void* user_data, bool is_ok);
#endif /* GRPC_CORE_TSI_ALTS_HANDSHAKER_ALTS_TSI_HANDSHAKER_H */

@ -0,0 +1,52 @@
/*
*
* 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.
*
*/
#ifndef GRPC_CORE_TSI_ALTS_HANDSHAKER_ALTS_TSI_HANDSHAKER_PRIVATE_H
#define GRPC_CORE_TSI_ALTS_HANDSHAKER_ALTS_TSI_HANDSHAKER_PRIVATE_H
#include <grpc/support/port_platform.h>
#include "src/core/tsi/alts/handshaker/alts_handshaker_client.h"
namespace grpc_core {
namespace internal {
/**
* Unsafe, use for testing only. It allows the caller to change the way the
* ALTS TSI handshaker schedules handshaker requests.
*/
void alts_tsi_handshaker_set_client_for_testing(alts_tsi_handshaker* handshaker,
alts_handshaker_client* client);
/* For testing only. */
bool alts_tsi_handshaker_get_has_sent_start_message_for_testing(
alts_tsi_handshaker* handshaker);
bool alts_tsi_handshaker_get_is_client_for_testing(
alts_tsi_handshaker* handshaker);
void alts_tsi_handshaker_set_recv_bytes_for_testing(
alts_tsi_handshaker* handshaker, grpc_slice* slice);
grpc_slice alts_tsi_handshaker_get_recv_bytes_for_testing(
alts_tsi_handshaker* handshaker);
} // namespace internal
} // namespace grpc_core
#endif /* GRPC_CORE_TSI_ALTS_HANDSHAKER_ALTS_TSI_HANDSHAKER_PRIVATE_H */

@ -0,0 +1,58 @@
/*
*
* 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_tsi_utils.h"
#include <grpc/byte_buffer_reader.h>
tsi_result alts_tsi_utils_convert_to_tsi_result(grpc_status_code code) {
switch (code) {
case GRPC_STATUS_OK:
return TSI_OK;
case GRPC_STATUS_UNKNOWN:
return TSI_UNKNOWN_ERROR;
case GRPC_STATUS_INVALID_ARGUMENT:
return TSI_INVALID_ARGUMENT;
case GRPC_STATUS_NOT_FOUND:
return TSI_NOT_FOUND;
case GRPC_STATUS_INTERNAL:
return TSI_INTERNAL_ERROR;
default:
return TSI_UNKNOWN_ERROR;
}
}
grpc_gcp_handshaker_resp* alts_tsi_utils_deserialize_response(
grpc_byte_buffer* resp_buffer) {
GPR_ASSERT(resp_buffer != nullptr);
grpc_byte_buffer_reader bbr;
grpc_byte_buffer_reader_init(&bbr, resp_buffer);
grpc_slice slice = grpc_byte_buffer_reader_readall(&bbr);
grpc_gcp_handshaker_resp* resp = grpc_gcp_handshaker_resp_create();
bool ok = grpc_gcp_handshaker_resp_decode(slice, resp);
grpc_slice_unref(slice);
grpc_byte_buffer_reader_destroy(&bbr);
if (!ok) {
grpc_gcp_handshaker_resp_destroy(resp);
gpr_log(GPR_ERROR, "grpc_gcp_handshaker_resp_decode() failed");
return nullptr;
}
return resp;
}

@ -0,0 +1,52 @@
/*
*
* 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.
*
*/
#ifndef GRPC_CORE_TSI_ALTS_HANDSHAKER_ALTS_TSI_UTILS_H
#define GRPC_CORE_TSI_ALTS_HANDSHAKER_ALTS_TSI_UTILS_H
#include <grpc/support/port_platform.h>
#include <grpc/byte_buffer.h>
#include <grpc/grpc.h>
#include "src/core/tsi/alts/handshaker/alts_handshaker_service_api.h"
#include "src/core/tsi/transport_security_interface.h"
/**
* This method converts grpc_status_code code to the corresponding tsi_result
* code.
*
* - code: grpc_status_code code.
*
* It returns the converted tsi_result code.
*/
tsi_result alts_tsi_utils_convert_to_tsi_result(grpc_status_code code);
/**
* This method deserializes a handshaker response returned from ALTS handshaker
* service.
*
* - bytes_received: data returned from ALTS handshaker service.
*
* It returns a deserialized handshaker response on success and nullptr on
* failure.
*/
grpc_gcp_handshaker_resp* alts_tsi_utils_deserialize_response(
grpc_byte_buffer* resp_buffer);
#endif /* GRPC_CORE_TSI_ALTS_HANDSHAKER_ALTS_TSI_UTILS_H */

@ -0,0 +1,48 @@
/* Automatically generated nanopb constant definitions */
/* Generated by nanopb-0.3.7-dev */
#include "src/core/tsi/alts/handshaker/altscontext.pb.h"
/* @@protoc_insertion_point(includes) */
#if PB_PROTO_HEADER_VERSION != 30
#error Regenerate this file with the current version of nanopb generator.
#endif
const pb_field_t grpc_gcp_AltsContext_fields[7] = {
PB_FIELD( 1, STRING , OPTIONAL, CALLBACK, FIRST, grpc_gcp_AltsContext, application_protocol, application_protocol, 0),
PB_FIELD( 2, STRING , OPTIONAL, CALLBACK, OTHER, grpc_gcp_AltsContext, record_protocol, application_protocol, 0),
PB_FIELD( 3, UENUM , OPTIONAL, STATIC , OTHER, grpc_gcp_AltsContext, security_level, record_protocol, 0),
PB_FIELD( 4, STRING , OPTIONAL, CALLBACK, OTHER, grpc_gcp_AltsContext, peer_service_account, security_level, 0),
PB_FIELD( 5, STRING , OPTIONAL, CALLBACK, OTHER, grpc_gcp_AltsContext, local_service_account, peer_service_account, 0),
PB_FIELD( 6, MESSAGE , OPTIONAL, STATIC , OTHER, grpc_gcp_AltsContext, peer_rpc_versions, local_service_account, &grpc_gcp_RpcProtocolVersions_fields),
PB_LAST_FIELD
};
/* Check that field information fits in pb_field_t */
#if !defined(PB_FIELD_32BIT)
/* If you get an error here, it means that you need to define PB_FIELD_32BIT
* compile-time option. You can do that in pb.h or on compiler command line.
*
* The reason you need to do this is that some of your messages contain tag
* numbers or field sizes that are larger than what can fit in 8 or 16 bit
* field descriptors.
*/
PB_STATIC_ASSERT((pb_membersize(grpc_gcp_AltsContext, peer_rpc_versions) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_grpc_gcp_AltsContext)
#endif
#if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT)
/* If you get an error here, it means that you need to define PB_FIELD_16BIT
* compile-time option. You can do that in pb.h or on compiler command line.
*
* The reason you need to do this is that some of your messages contain tag
* numbers or field sizes that are larger than what can fit in the default
* 8 bit descriptors.
*/
PB_STATIC_ASSERT((pb_membersize(grpc_gcp_AltsContext, peer_rpc_versions) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_grpc_gcp_AltsContext)
#endif
/* @@protoc_insertion_point(eof) */

@ -0,0 +1,64 @@
/* Automatically generated nanopb header */
/* Generated by nanopb-0.3.7-dev */
#ifndef PB_GRPC_GCP_ALTSCONTEXT_PB_H_INCLUDED
#define PB_GRPC_GCP_ALTSCONTEXT_PB_H_INCLUDED
#include "third_party/nanopb/pb.h"
#include "src/core/tsi/alts/handshaker/transport_security_common.pb.h"
/* @@protoc_insertion_point(includes) */
#if PB_PROTO_HEADER_VERSION != 30
#error Regenerate this file with the current version of nanopb generator.
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* Struct definitions */
typedef struct _grpc_gcp_AltsContext {
pb_callback_t application_protocol;
pb_callback_t record_protocol;
bool has_security_level;
grpc_gcp_SecurityLevel security_level;
pb_callback_t peer_service_account;
pb_callback_t local_service_account;
bool has_peer_rpc_versions;
grpc_gcp_RpcProtocolVersions peer_rpc_versions;
/* @@protoc_insertion_point(struct:grpc_gcp_AltsContext) */
} grpc_gcp_AltsContext;
/* Default values for struct fields */
/* Initializer values for message structs */
#define grpc_gcp_AltsContext_init_default {{{NULL}, NULL}, {{NULL}, NULL}, false, (grpc_gcp_SecurityLevel)0, {{NULL}, NULL}, {{NULL}, NULL}, false, grpc_gcp_RpcProtocolVersions_init_default}
#define grpc_gcp_AltsContext_init_zero {{{NULL}, NULL}, {{NULL}, NULL}, false, (grpc_gcp_SecurityLevel)0, {{NULL}, NULL}, {{NULL}, NULL}, false, grpc_gcp_RpcProtocolVersions_init_zero}
/* Field tags (for use in manual encoding/decoding) */
#define grpc_gcp_AltsContext_application_protocol_tag 1
#define grpc_gcp_AltsContext_record_protocol_tag 2
#define grpc_gcp_AltsContext_security_level_tag 3
#define grpc_gcp_AltsContext_peer_service_account_tag 4
#define grpc_gcp_AltsContext_local_service_account_tag 5
#define grpc_gcp_AltsContext_peer_rpc_versions_tag 6
/* Struct field encoding specification for nanopb */
extern const pb_field_t grpc_gcp_AltsContext_fields[7];
/* Maximum encoded size of messages (where known) */
/* grpc_gcp_AltsContext_size depends on runtime parameters */
/* Message IDs (where set with "msgid" option) */
#ifdef PB_MSGID
#define ALTSCONTEXT_MESSAGES \
#endif
#ifdef __cplusplus
} /* extern "C" */
#endif
/* @@protoc_insertion_point(eof) */
#endif

@ -0,0 +1,123 @@
/* Automatically generated nanopb constant definitions */
/* Generated by nanopb-0.3.7-dev */
#include "src/core/tsi/alts/handshaker/handshaker.pb.h"
/* @@protoc_insertion_point(includes) */
#if PB_PROTO_HEADER_VERSION != 30
#error Regenerate this file with the current version of nanopb generator.
#endif
const pb_field_t grpc_gcp_Endpoint_fields[4] = {
PB_FIELD( 1, STRING , OPTIONAL, CALLBACK, FIRST, grpc_gcp_Endpoint, ip_address, ip_address, 0),
PB_FIELD( 2, INT32 , OPTIONAL, STATIC , OTHER, grpc_gcp_Endpoint, port, ip_address, 0),
PB_FIELD( 3, UENUM , OPTIONAL, STATIC , OTHER, grpc_gcp_Endpoint, protocol, port, 0),
PB_LAST_FIELD
};
const pb_field_t grpc_gcp_Identity_fields[3] = {
PB_FIELD( 1, STRING , OPTIONAL, CALLBACK, FIRST, grpc_gcp_Identity, service_account, service_account, 0),
PB_FIELD( 2, STRING , OPTIONAL, CALLBACK, OTHER, grpc_gcp_Identity, hostname, service_account, 0),
PB_LAST_FIELD
};
const pb_field_t grpc_gcp_StartClientHandshakeReq_fields[10] = {
PB_FIELD( 1, UENUM , OPTIONAL, STATIC , FIRST, grpc_gcp_StartClientHandshakeReq, handshake_security_protocol, handshake_security_protocol, 0),
PB_FIELD( 2, STRING , REPEATED, CALLBACK, OTHER, grpc_gcp_StartClientHandshakeReq, application_protocols, handshake_security_protocol, 0),
PB_FIELD( 3, STRING , REPEATED, CALLBACK, OTHER, grpc_gcp_StartClientHandshakeReq, record_protocols, application_protocols, 0),
PB_FIELD( 4, MESSAGE , REPEATED, CALLBACK, OTHER, grpc_gcp_StartClientHandshakeReq, target_identities, record_protocols, &grpc_gcp_Identity_fields),
PB_FIELD( 5, MESSAGE , OPTIONAL, STATIC , OTHER, grpc_gcp_StartClientHandshakeReq, local_identity, target_identities, &grpc_gcp_Identity_fields),
PB_FIELD( 6, MESSAGE , OPTIONAL, STATIC , OTHER, grpc_gcp_StartClientHandshakeReq, local_endpoint, local_identity, &grpc_gcp_Endpoint_fields),
PB_FIELD( 7, MESSAGE , OPTIONAL, STATIC , OTHER, grpc_gcp_StartClientHandshakeReq, remote_endpoint, local_endpoint, &grpc_gcp_Endpoint_fields),
PB_FIELD( 8, STRING , OPTIONAL, CALLBACK, OTHER, grpc_gcp_StartClientHandshakeReq, target_name, remote_endpoint, 0),
PB_FIELD( 9, MESSAGE , OPTIONAL, STATIC , OTHER, grpc_gcp_StartClientHandshakeReq, rpc_versions, target_name, &grpc_gcp_RpcProtocolVersions_fields),
PB_LAST_FIELD
};
const pb_field_t grpc_gcp_ServerHandshakeParameters_fields[3] = {
PB_FIELD( 1, STRING , REPEATED, CALLBACK, FIRST, grpc_gcp_ServerHandshakeParameters, record_protocols, record_protocols, 0),
PB_FIELD( 2, MESSAGE , REPEATED, CALLBACK, OTHER, grpc_gcp_ServerHandshakeParameters, local_identities, record_protocols, &grpc_gcp_Identity_fields),
PB_LAST_FIELD
};
const pb_field_t grpc_gcp_StartServerHandshakeReq_fields[7] = {
PB_FIELD( 1, STRING , REPEATED, CALLBACK, FIRST, grpc_gcp_StartServerHandshakeReq, application_protocols, application_protocols, 0),
PB_FIELD( 2, MESSAGE , REPEATED, STATIC , OTHER, grpc_gcp_StartServerHandshakeReq, handshake_parameters, application_protocols, &grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry_fields),
PB_FIELD( 3, BYTES , OPTIONAL, CALLBACK, OTHER, grpc_gcp_StartServerHandshakeReq, in_bytes, handshake_parameters, 0),
PB_FIELD( 4, MESSAGE , OPTIONAL, STATIC , OTHER, grpc_gcp_StartServerHandshakeReq, local_endpoint, in_bytes, &grpc_gcp_Endpoint_fields),
PB_FIELD( 5, MESSAGE , OPTIONAL, STATIC , OTHER, grpc_gcp_StartServerHandshakeReq, remote_endpoint, local_endpoint, &grpc_gcp_Endpoint_fields),
PB_FIELD( 6, MESSAGE , OPTIONAL, STATIC , OTHER, grpc_gcp_StartServerHandshakeReq, rpc_versions, remote_endpoint, &grpc_gcp_RpcProtocolVersions_fields),
PB_LAST_FIELD
};
const pb_field_t grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry_fields[3] = {
PB_FIELD( 1, INT32 , OPTIONAL, STATIC , FIRST, grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry, key, key, 0),
PB_FIELD( 2, MESSAGE , OPTIONAL, STATIC , OTHER, grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry, value, key, &grpc_gcp_ServerHandshakeParameters_fields),
PB_LAST_FIELD
};
const pb_field_t grpc_gcp_NextHandshakeMessageReq_fields[2] = {
PB_FIELD( 1, BYTES , OPTIONAL, CALLBACK, FIRST, grpc_gcp_NextHandshakeMessageReq, in_bytes, in_bytes, 0),
PB_LAST_FIELD
};
const pb_field_t grpc_gcp_HandshakerReq_fields[4] = {
PB_FIELD( 1, MESSAGE , OPTIONAL, STATIC , FIRST, grpc_gcp_HandshakerReq, client_start, client_start, &grpc_gcp_StartClientHandshakeReq_fields),
PB_FIELD( 2, MESSAGE , OPTIONAL, STATIC , OTHER, grpc_gcp_HandshakerReq, server_start, client_start, &grpc_gcp_StartServerHandshakeReq_fields),
PB_FIELD( 3, MESSAGE , OPTIONAL, STATIC , OTHER, grpc_gcp_HandshakerReq, next, server_start, &grpc_gcp_NextHandshakeMessageReq_fields),
PB_LAST_FIELD
};
const pb_field_t grpc_gcp_HandshakerResult_fields[8] = {
PB_FIELD( 1, STRING , OPTIONAL, CALLBACK, FIRST, grpc_gcp_HandshakerResult, application_protocol, application_protocol, 0),
PB_FIELD( 2, STRING , OPTIONAL, CALLBACK, OTHER, grpc_gcp_HandshakerResult, record_protocol, application_protocol, 0),
PB_FIELD( 3, BYTES , OPTIONAL, CALLBACK, OTHER, grpc_gcp_HandshakerResult, key_data, record_protocol, 0),
PB_FIELD( 4, MESSAGE , OPTIONAL, STATIC , OTHER, grpc_gcp_HandshakerResult, peer_identity, key_data, &grpc_gcp_Identity_fields),
PB_FIELD( 5, MESSAGE , OPTIONAL, STATIC , OTHER, grpc_gcp_HandshakerResult, local_identity, peer_identity, &grpc_gcp_Identity_fields),
PB_FIELD( 6, BOOL , OPTIONAL, STATIC , OTHER, grpc_gcp_HandshakerResult, keep_channel_open, local_identity, 0),
PB_FIELD( 7, MESSAGE , OPTIONAL, STATIC , OTHER, grpc_gcp_HandshakerResult, peer_rpc_versions, keep_channel_open, &grpc_gcp_RpcProtocolVersions_fields),
PB_LAST_FIELD
};
const pb_field_t grpc_gcp_HandshakerStatus_fields[3] = {
PB_FIELD( 1, UINT32 , OPTIONAL, STATIC , FIRST, grpc_gcp_HandshakerStatus, code, code, 0),
PB_FIELD( 2, STRING , OPTIONAL, CALLBACK, OTHER, grpc_gcp_HandshakerStatus, details, code, 0),
PB_LAST_FIELD
};
const pb_field_t grpc_gcp_HandshakerResp_fields[5] = {
PB_FIELD( 1, BYTES , OPTIONAL, CALLBACK, FIRST, grpc_gcp_HandshakerResp, out_frames, out_frames, 0),
PB_FIELD( 2, UINT32 , OPTIONAL, STATIC , OTHER, grpc_gcp_HandshakerResp, bytes_consumed, out_frames, 0),
PB_FIELD( 3, MESSAGE , OPTIONAL, STATIC , OTHER, grpc_gcp_HandshakerResp, result, bytes_consumed, &grpc_gcp_HandshakerResult_fields),
PB_FIELD( 4, MESSAGE , OPTIONAL, STATIC , OTHER, grpc_gcp_HandshakerResp, status, result, &grpc_gcp_HandshakerStatus_fields),
PB_LAST_FIELD
};
/* Check that field information fits in pb_field_t */
#if !defined(PB_FIELD_32BIT)
/* If you get an error here, it means that you need to define PB_FIELD_32BIT
* compile-time option. You can do that in pb.h or on compiler command line.
*
* The reason you need to do this is that some of your messages contain tag
* numbers or field sizes that are larger than what can fit in 8 or 16 bit
* field descriptors.
*/
PB_STATIC_ASSERT((pb_membersize(grpc_gcp_StartClientHandshakeReq, target_identities) < 65536 && pb_membersize(grpc_gcp_StartClientHandshakeReq, local_identity) < 65536 && pb_membersize(grpc_gcp_StartClientHandshakeReq, local_endpoint) < 65536 && pb_membersize(grpc_gcp_StartClientHandshakeReq, remote_endpoint) < 65536 && pb_membersize(grpc_gcp_StartClientHandshakeReq, rpc_versions) < 65536 && pb_membersize(grpc_gcp_ServerHandshakeParameters, local_identities) < 65536 && pb_membersize(grpc_gcp_StartServerHandshakeReq, handshake_parameters[0]) < 65536 && pb_membersize(grpc_gcp_StartServerHandshakeReq, local_endpoint) < 65536 && pb_membersize(grpc_gcp_StartServerHandshakeReq, remote_endpoint) < 65536 && pb_membersize(grpc_gcp_StartServerHandshakeReq, rpc_versions) < 65536 && pb_membersize(grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry, value) < 65536 && pb_membersize(grpc_gcp_HandshakerReq, client_start) < 65536 && pb_membersize(grpc_gcp_HandshakerReq, server_start) < 65536 && pb_membersize(grpc_gcp_HandshakerReq, next) < 65536 && pb_membersize(grpc_gcp_HandshakerResult, peer_identity) < 65536 && pb_membersize(grpc_gcp_HandshakerResult, local_identity) < 65536 && pb_membersize(grpc_gcp_HandshakerResult, peer_rpc_versions) < 65536 && pb_membersize(grpc_gcp_HandshakerResp, result) < 65536 && pb_membersize(grpc_gcp_HandshakerResp, status) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_grpc_gcp_Endpoint_grpc_gcp_Identity_grpc_gcp_StartClientHandshakeReq_grpc_gcp_ServerHandshakeParameters_grpc_gcp_StartServerHandshakeReq_grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry_grpc_gcp_NextHandshakeMessageReq_grpc_gcp_HandshakerReq_grpc_gcp_HandshakerResult_grpc_gcp_HandshakerStatus_grpc_gcp_HandshakerResp)
#endif
#if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT)
/* If you get an error here, it means that you need to define PB_FIELD_16BIT
* compile-time option. You can do that in pb.h or on compiler command line.
*
* The reason you need to do this is that some of your messages contain tag
* numbers or field sizes that are larger than what can fit in the default
* 8 bit descriptors.
*/
PB_STATIC_ASSERT((pb_membersize(grpc_gcp_StartClientHandshakeReq, target_identities) < 256 && pb_membersize(grpc_gcp_StartClientHandshakeReq, local_identity) < 256 && pb_membersize(grpc_gcp_StartClientHandshakeReq, local_endpoint) < 256 && pb_membersize(grpc_gcp_StartClientHandshakeReq, remote_endpoint) < 256 && pb_membersize(grpc_gcp_StartClientHandshakeReq, rpc_versions) < 256 && pb_membersize(grpc_gcp_ServerHandshakeParameters, local_identities) < 256 && pb_membersize(grpc_gcp_StartServerHandshakeReq, handshake_parameters[0]) < 256 && pb_membersize(grpc_gcp_StartServerHandshakeReq, local_endpoint) < 256 && pb_membersize(grpc_gcp_StartServerHandshakeReq, remote_endpoint) < 256 && pb_membersize(grpc_gcp_StartServerHandshakeReq, rpc_versions) < 256 && pb_membersize(grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry, value) < 256 && pb_membersize(grpc_gcp_HandshakerReq, client_start) < 256 && pb_membersize(grpc_gcp_HandshakerReq, server_start) < 256 && pb_membersize(grpc_gcp_HandshakerReq, next) < 256 && pb_membersize(grpc_gcp_HandshakerResult, peer_identity) < 256 && pb_membersize(grpc_gcp_HandshakerResult, local_identity) < 256 && pb_membersize(grpc_gcp_HandshakerResult, peer_rpc_versions) < 256 && pb_membersize(grpc_gcp_HandshakerResp, result) < 256 && pb_membersize(grpc_gcp_HandshakerResp, status) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_grpc_gcp_Endpoint_grpc_gcp_Identity_grpc_gcp_StartClientHandshakeReq_grpc_gcp_ServerHandshakeParameters_grpc_gcp_StartServerHandshakeReq_grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry_grpc_gcp_NextHandshakeMessageReq_grpc_gcp_HandshakerReq_grpc_gcp_HandshakerResult_grpc_gcp_HandshakerStatus_grpc_gcp_HandshakerResp)
#endif
/* @@protoc_insertion_point(eof) */

@ -0,0 +1,255 @@
/* Automatically generated nanopb header */
/* Generated by nanopb-0.3.7-dev */
#ifndef PB_GRPC_GCP_HANDSHAKER_PB_H_INCLUDED
#define PB_GRPC_GCP_HANDSHAKER_PB_H_INCLUDED
#include "third_party/nanopb/pb.h"
#include "src/core/tsi/alts/handshaker/transport_security_common.pb.h"
/* @@protoc_insertion_point(includes) */
#if PB_PROTO_HEADER_VERSION != 30
#error Regenerate this file with the current version of nanopb generator.
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* Enum definitions */
typedef enum _grpc_gcp_HandshakeProtocol {
grpc_gcp_HandshakeProtocol_HANDSHAKE_PROTOCOL_UNSPECIFIED = 0,
grpc_gcp_HandshakeProtocol_TLS = 1,
grpc_gcp_HandshakeProtocol_ALTS = 2
} grpc_gcp_HandshakeProtocol;
#define _grpc_gcp_HandshakeProtocol_MIN grpc_gcp_HandshakeProtocol_HANDSHAKE_PROTOCOL_UNSPECIFIED
#define _grpc_gcp_HandshakeProtocol_MAX grpc_gcp_HandshakeProtocol_ALTS
#define _grpc_gcp_HandshakeProtocol_ARRAYSIZE ((grpc_gcp_HandshakeProtocol)(grpc_gcp_HandshakeProtocol_ALTS+1))
typedef enum _grpc_gcp_NetworkProtocol {
grpc_gcp_NetworkProtocol_NETWORK_PROTOCOL_UNSPECIFIED = 0,
grpc_gcp_NetworkProtocol_TCP = 1,
grpc_gcp_NetworkProtocol_UDP = 2
} grpc_gcp_NetworkProtocol;
#define _grpc_gcp_NetworkProtocol_MIN grpc_gcp_NetworkProtocol_NETWORK_PROTOCOL_UNSPECIFIED
#define _grpc_gcp_NetworkProtocol_MAX grpc_gcp_NetworkProtocol_UDP
#define _grpc_gcp_NetworkProtocol_ARRAYSIZE ((grpc_gcp_NetworkProtocol)(grpc_gcp_NetworkProtocol_UDP+1))
/* Struct definitions */
typedef struct _grpc_gcp_Identity {
pb_callback_t service_account;
pb_callback_t hostname;
/* @@protoc_insertion_point(struct:grpc_gcp_Identity) */
} grpc_gcp_Identity;
typedef struct _grpc_gcp_NextHandshakeMessageReq {
pb_callback_t in_bytes;
/* @@protoc_insertion_point(struct:grpc_gcp_NextHandshakeMessageReq) */
} grpc_gcp_NextHandshakeMessageReq;
typedef struct _grpc_gcp_ServerHandshakeParameters {
pb_callback_t record_protocols;
pb_callback_t local_identities;
/* @@protoc_insertion_point(struct:grpc_gcp_ServerHandshakeParameters) */
} grpc_gcp_ServerHandshakeParameters;
typedef struct _grpc_gcp_Endpoint {
pb_callback_t ip_address;
bool has_port;
int32_t port;
bool has_protocol;
grpc_gcp_NetworkProtocol protocol;
/* @@protoc_insertion_point(struct:grpc_gcp_Endpoint) */
} grpc_gcp_Endpoint;
typedef struct _grpc_gcp_HandshakerResult {
pb_callback_t application_protocol;
pb_callback_t record_protocol;
pb_callback_t key_data;
bool has_peer_identity;
grpc_gcp_Identity peer_identity;
bool has_local_identity;
grpc_gcp_Identity local_identity;
bool has_keep_channel_open;
bool keep_channel_open;
bool has_peer_rpc_versions;
grpc_gcp_RpcProtocolVersions peer_rpc_versions;
/* @@protoc_insertion_point(struct:grpc_gcp_HandshakerResult) */
} grpc_gcp_HandshakerResult;
typedef struct _grpc_gcp_HandshakerStatus {
bool has_code;
uint32_t code;
pb_callback_t details;
/* @@protoc_insertion_point(struct:grpc_gcp_HandshakerStatus) */
} grpc_gcp_HandshakerStatus;
typedef struct _grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry {
bool has_key;
int32_t key;
bool has_value;
grpc_gcp_ServerHandshakeParameters value;
/* @@protoc_insertion_point(struct:grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry) */
} grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry;
typedef struct _grpc_gcp_HandshakerResp {
pb_callback_t out_frames;
bool has_bytes_consumed;
uint32_t bytes_consumed;
bool has_result;
grpc_gcp_HandshakerResult result;
bool has_status;
grpc_gcp_HandshakerStatus status;
/* @@protoc_insertion_point(struct:grpc_gcp_HandshakerResp) */
} grpc_gcp_HandshakerResp;
typedef struct _grpc_gcp_StartClientHandshakeReq {
bool has_handshake_security_protocol;
grpc_gcp_HandshakeProtocol handshake_security_protocol;
pb_callback_t application_protocols;
pb_callback_t record_protocols;
pb_callback_t target_identities;
bool has_local_identity;
grpc_gcp_Identity local_identity;
bool has_local_endpoint;
grpc_gcp_Endpoint local_endpoint;
bool has_remote_endpoint;
grpc_gcp_Endpoint remote_endpoint;
pb_callback_t target_name;
bool has_rpc_versions;
grpc_gcp_RpcProtocolVersions rpc_versions;
/* @@protoc_insertion_point(struct:grpc_gcp_StartClientHandshakeReq) */
} grpc_gcp_StartClientHandshakeReq;
typedef struct _grpc_gcp_StartServerHandshakeReq {
pb_callback_t application_protocols;
pb_size_t handshake_parameters_count;
grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry handshake_parameters[3];
pb_callback_t in_bytes;
bool has_local_endpoint;
grpc_gcp_Endpoint local_endpoint;
bool has_remote_endpoint;
grpc_gcp_Endpoint remote_endpoint;
bool has_rpc_versions;
grpc_gcp_RpcProtocolVersions rpc_versions;
/* @@protoc_insertion_point(struct:grpc_gcp_StartServerHandshakeReq) */
} grpc_gcp_StartServerHandshakeReq;
typedef struct _grpc_gcp_HandshakerReq {
bool has_client_start;
grpc_gcp_StartClientHandshakeReq client_start;
bool has_server_start;
grpc_gcp_StartServerHandshakeReq server_start;
bool has_next;
grpc_gcp_NextHandshakeMessageReq next;
/* @@protoc_insertion_point(struct:grpc_gcp_HandshakerReq) */
} grpc_gcp_HandshakerReq;
/* Default values for struct fields */
/* Initializer values for message structs */
#define grpc_gcp_Endpoint_init_default {{{NULL}, NULL}, false, 0, false, (grpc_gcp_NetworkProtocol)0}
#define grpc_gcp_Identity_init_default {{{NULL}, NULL}, {{NULL}, NULL}}
#define grpc_gcp_StartClientHandshakeReq_init_default {false, (grpc_gcp_HandshakeProtocol)0, {{NULL}, NULL}, {{NULL}, NULL}, {{NULL}, NULL}, false, grpc_gcp_Identity_init_default, false, grpc_gcp_Endpoint_init_default, false, grpc_gcp_Endpoint_init_default, {{NULL}, NULL}, false, grpc_gcp_RpcProtocolVersions_init_default}
#define grpc_gcp_ServerHandshakeParameters_init_default {{{NULL}, NULL}, {{NULL}, NULL}}
#define grpc_gcp_StartServerHandshakeReq_init_default {{{NULL}, NULL}, 0, {grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry_init_default, grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry_init_default, grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry_init_default}, {{NULL}, NULL}, false, grpc_gcp_Endpoint_init_default, false, grpc_gcp_Endpoint_init_default, false, grpc_gcp_RpcProtocolVersions_init_default}
#define grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry_init_default {false, 0, false, grpc_gcp_ServerHandshakeParameters_init_default}
#define grpc_gcp_NextHandshakeMessageReq_init_default {{{NULL}, NULL}}
#define grpc_gcp_HandshakerReq_init_default {false, grpc_gcp_StartClientHandshakeReq_init_default, false, grpc_gcp_StartServerHandshakeReq_init_default, false, grpc_gcp_NextHandshakeMessageReq_init_default}
#define grpc_gcp_HandshakerResult_init_default {{{NULL}, NULL}, {{NULL}, NULL}, {{NULL}, NULL}, false, grpc_gcp_Identity_init_default, false, grpc_gcp_Identity_init_default, false, 0, false, grpc_gcp_RpcProtocolVersions_init_default}
#define grpc_gcp_HandshakerStatus_init_default {false, 0, {{NULL}, NULL}}
#define grpc_gcp_HandshakerResp_init_default {{{NULL}, NULL}, false, 0, false, grpc_gcp_HandshakerResult_init_default, false, grpc_gcp_HandshakerStatus_init_default}
#define grpc_gcp_Endpoint_init_zero {{{NULL}, NULL}, false, 0, false, (grpc_gcp_NetworkProtocol)0}
#define grpc_gcp_Identity_init_zero {{{NULL}, NULL}, {{NULL}, NULL}}
#define grpc_gcp_StartClientHandshakeReq_init_zero {false, (grpc_gcp_HandshakeProtocol)0, {{NULL}, NULL}, {{NULL}, NULL}, {{NULL}, NULL}, false, grpc_gcp_Identity_init_zero, false, grpc_gcp_Endpoint_init_zero, false, grpc_gcp_Endpoint_init_zero, {{NULL}, NULL}, false, grpc_gcp_RpcProtocolVersions_init_zero}
#define grpc_gcp_ServerHandshakeParameters_init_zero {{{NULL}, NULL}, {{NULL}, NULL}}
#define grpc_gcp_StartServerHandshakeReq_init_zero {{{NULL}, NULL}, 0, {grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry_init_zero, grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry_init_zero, grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry_init_zero}, {{NULL}, NULL}, false, grpc_gcp_Endpoint_init_zero, false, grpc_gcp_Endpoint_init_zero, false, grpc_gcp_RpcProtocolVersions_init_zero}
#define grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry_init_zero {false, 0, false, grpc_gcp_ServerHandshakeParameters_init_zero}
#define grpc_gcp_NextHandshakeMessageReq_init_zero {{{NULL}, NULL}}
#define grpc_gcp_HandshakerReq_init_zero {false, grpc_gcp_StartClientHandshakeReq_init_zero, false, grpc_gcp_StartServerHandshakeReq_init_zero, false, grpc_gcp_NextHandshakeMessageReq_init_zero}
#define grpc_gcp_HandshakerResult_init_zero {{{NULL}, NULL}, {{NULL}, NULL}, {{NULL}, NULL}, false, grpc_gcp_Identity_init_zero, false, grpc_gcp_Identity_init_zero, false, 0, false, grpc_gcp_RpcProtocolVersions_init_zero}
#define grpc_gcp_HandshakerStatus_init_zero {false, 0, {{NULL}, NULL}}
#define grpc_gcp_HandshakerResp_init_zero {{{NULL}, NULL}, false, 0, false, grpc_gcp_HandshakerResult_init_zero, false, grpc_gcp_HandshakerStatus_init_zero}
/* Field tags (for use in manual encoding/decoding) */
#define grpc_gcp_Identity_service_account_tag 1
#define grpc_gcp_Identity_hostname_tag 2
#define grpc_gcp_NextHandshakeMessageReq_in_bytes_tag 1
#define grpc_gcp_ServerHandshakeParameters_record_protocols_tag 1
#define grpc_gcp_ServerHandshakeParameters_local_identities_tag 2
#define grpc_gcp_Endpoint_ip_address_tag 1
#define grpc_gcp_Endpoint_port_tag 2
#define grpc_gcp_Endpoint_protocol_tag 3
#define grpc_gcp_HandshakerResult_application_protocol_tag 1
#define grpc_gcp_HandshakerResult_record_protocol_tag 2
#define grpc_gcp_HandshakerResult_key_data_tag 3
#define grpc_gcp_HandshakerResult_peer_identity_tag 4
#define grpc_gcp_HandshakerResult_local_identity_tag 5
#define grpc_gcp_HandshakerResult_keep_channel_open_tag 6
#define grpc_gcp_HandshakerResult_peer_rpc_versions_tag 7
#define grpc_gcp_HandshakerStatus_code_tag 1
#define grpc_gcp_HandshakerStatus_details_tag 2
#define grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry_key_tag 1
#define grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry_value_tag 2
#define grpc_gcp_HandshakerResp_out_frames_tag 1
#define grpc_gcp_HandshakerResp_bytes_consumed_tag 2
#define grpc_gcp_HandshakerResp_result_tag 3
#define grpc_gcp_HandshakerResp_status_tag 4
#define grpc_gcp_StartClientHandshakeReq_handshake_security_protocol_tag 1
#define grpc_gcp_StartClientHandshakeReq_application_protocols_tag 2
#define grpc_gcp_StartClientHandshakeReq_record_protocols_tag 3
#define grpc_gcp_StartClientHandshakeReq_target_identities_tag 4
#define grpc_gcp_StartClientHandshakeReq_local_identity_tag 5
#define grpc_gcp_StartClientHandshakeReq_local_endpoint_tag 6
#define grpc_gcp_StartClientHandshakeReq_remote_endpoint_tag 7
#define grpc_gcp_StartClientHandshakeReq_target_name_tag 8
#define grpc_gcp_StartClientHandshakeReq_rpc_versions_tag 9
#define grpc_gcp_StartServerHandshakeReq_application_protocols_tag 1
#define grpc_gcp_StartServerHandshakeReq_handshake_parameters_tag 2
#define grpc_gcp_StartServerHandshakeReq_in_bytes_tag 3
#define grpc_gcp_StartServerHandshakeReq_local_endpoint_tag 4
#define grpc_gcp_StartServerHandshakeReq_remote_endpoint_tag 5
#define grpc_gcp_StartServerHandshakeReq_rpc_versions_tag 6
#define grpc_gcp_HandshakerReq_client_start_tag 1
#define grpc_gcp_HandshakerReq_server_start_tag 2
#define grpc_gcp_HandshakerReq_next_tag 3
/* Struct field encoding specification for nanopb */
extern const pb_field_t grpc_gcp_Endpoint_fields[4];
extern const pb_field_t grpc_gcp_Identity_fields[3];
extern const pb_field_t grpc_gcp_StartClientHandshakeReq_fields[10];
extern const pb_field_t grpc_gcp_ServerHandshakeParameters_fields[3];
extern const pb_field_t grpc_gcp_StartServerHandshakeReq_fields[7];
extern const pb_field_t grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry_fields[3];
extern const pb_field_t grpc_gcp_NextHandshakeMessageReq_fields[2];
extern const pb_field_t grpc_gcp_HandshakerReq_fields[4];
extern const pb_field_t grpc_gcp_HandshakerResult_fields[8];
extern const pb_field_t grpc_gcp_HandshakerStatus_fields[3];
extern const pb_field_t grpc_gcp_HandshakerResp_fields[5];
/* Maximum encoded size of messages (where known) */
/* grpc_gcp_Endpoint_size depends on runtime parameters */
/* grpc_gcp_Identity_size depends on runtime parameters */
/* grpc_gcp_StartClientHandshakeReq_size depends on runtime parameters */
/* grpc_gcp_ServerHandshakeParameters_size depends on runtime parameters */
/* grpc_gcp_StartServerHandshakeReq_size depends on runtime parameters */
#define grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry_size (17 + grpc_gcp_ServerHandshakeParameters_size)
/* grpc_gcp_NextHandshakeMessageReq_size depends on runtime parameters */
#define grpc_gcp_HandshakerReq_size (18 + grpc_gcp_StartClientHandshakeReq_size + grpc_gcp_StartServerHandshakeReq_size + grpc_gcp_NextHandshakeMessageReq_size)
/* grpc_gcp_HandshakerResult_size depends on runtime parameters */
/* grpc_gcp_HandshakerStatus_size depends on runtime parameters */
/* grpc_gcp_HandshakerResp_size depends on runtime parameters */
/* Message IDs (where set with "msgid" option) */
#ifdef PB_MSGID
#define HANDSHAKER_MESSAGES \
#endif
#ifdef __cplusplus
} /* extern "C" */
#endif
/* @@protoc_insertion_point(eof) */
#endif

@ -0,0 +1,41 @@
// 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.
syntax = "proto3";
import "transport_security_common.proto";
package grpc.gcp;
option java_package = "io.grpc.alts";
message AltsContext {
// The application protocol negotiated for this connection.
string application_protocol = 1;
// The record protocol negotiated for this connection.
string record_protocol = 2;
// The security level of the created secure channel.
SecurityLevel security_level = 3;
// The peer service account.
string peer_service_account = 4;
// The local service account.
string local_service_account = 5;
// The RPC protocol versions supported by the peer.
RpcProtocolVersions peer_rpc_versions = 6;
}

@ -0,0 +1,2 @@
handshaker.proto no_unions:true
grpc.gcp.StartServerHandshakeReq.handshake_parameters max_count:3

@ -0,0 +1,220 @@
// 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.
syntax = "proto3";
import "transport_security_common.proto";
package grpc.gcp;
option java_package = "io.grpc.alts";
enum HandshakeProtocol {
// Default value.
HANDSHAKE_PROTOCOL_UNSPECIFIED = 0;
// TLS handshake protocol.
TLS = 1;
// Application Layer Transport Security handshake protocol.
ALTS = 2;
}
enum NetworkProtocol {
NETWORK_PROTOCOL_UNSPECIFIED = 0;
TCP = 1;
UDP = 2;
}
message Endpoint {
// IP address. It should contain an IPv4 or IPv6 string literal, e.g.
// "192.168.0.1" or "2001:db8::1".
string ip_address = 1;
// Port number.
int32 port = 2;
// Network protocol (e.g., TCP, UDP) associated with this endpoint.
NetworkProtocol protocol = 3;
}
message Identity {
oneof identity_oneof {
// Service account of a connection endpoint.
string service_account = 1;
// Hostname of a connection endpoint.
string hostname = 2;
}
}
message StartClientHandshakeReq {
// Handshake security protocol requested by the client.
HandshakeProtocol handshake_security_protocol = 1;
// The application protocols supported by the client, e.g., "h2" (for http2),
// "grpc".
repeated string application_protocols = 2;
// The record protocols supported by the client, e.g.,
// "ALTSRP_GCM_AES128".
repeated string record_protocols = 3;
// (Optional) Describes which server identities are acceptable by the client.
// If target identities are provided and none of them matches the peer
// identity of the server, handshake will fail.
repeated Identity target_identities = 4;
// (Optional) Application may specify a local identity. Otherwise, the
// handshaker chooses a default local identity.
Identity local_identity = 5;
// (Optional) Local endpoint information of the connection to the server,
// such as local IP address, port number, and network protocol.
Endpoint local_endpoint = 6;
// (Optional) Endpoint information of the remote server, such as IP address,
// port number, and network protocool.
Endpoint remote_endpoint = 7;
// (Optional) If target name is provided, a secure naming check is performed
// to verify that the peer authenticated identity is indeed authorized to run
// the target name.
string target_name = 8;
// (Optional) RPC protocol versions supported by the client.
RpcProtocolVersions rpc_versions = 9;
}
message ServerHandshakeParameters {
// The record protocols supported by the server, e.g.,
// "ALTSRP_GCM_AES128".
repeated string record_protocols = 1;
// (Optional) A list of local identities supported by the server, if
// specified. Otherwise, the handshaker chooses a default local identity.
repeated Identity local_identities = 2;
}
message StartServerHandshakeReq {
// The application protocols supported by the server, e.g., "h2" (for http2),
// "grpc".
repeated string application_protocols = 1;
// Handshake parameters (record protocols and local identities supported by
// the server) mapped by the handshake protocol. Each handshake security
// protocol (e.g., TLS or ALTS) has its own set of record protocols and local
// identities. Since protobuf does not support enum as key to the map, the key
// to handshake_parameters is the integer value of HandshakeProtocol enum.
map<int32, ServerHandshakeParameters> handshake_parameters = 2;
// Bytes in out_frames returned from the peer's HandshakerResp. It is possible
// that the peer's out_frames are split into multiple HandshakReq messages.
bytes in_bytes = 3;
// (Optional) Local endpoint information of the connection to the client,
// such as local IP address, port number, and network protocol.
Endpoint local_endpoint = 4;
// (Optional) Endpoint information of the remote client, such as IP address,
// port number, and network protocool.
Endpoint remote_endpoint = 5;
// (Optional) RPC protocol versions supported by the server.
RpcProtocolVersions rpc_versions = 6;
}
message NextHandshakeMessageReq {
// Bytes in out_frames returned from the peer's HandshakerResp. It is possible
// that the peer's out_frames are split into multiple NextHandshakerMessageReq
// messages.
bytes in_bytes = 1;
}
message HandshakerReq {
oneof req_oneof {
// The start client handshake request message.
StartClientHandshakeReq client_start = 1;
// The start server handshake request message.
StartServerHandshakeReq server_start = 2;
// The next handshake request message.
NextHandshakeMessageReq next = 3;
}
}
message HandshakerResult {
// The application protocol negotiated for this connection.
string application_protocol = 1;
// The record protocol negotiated for this connection.
string record_protocol = 2;
// Cryptographic key data. The key data may be more than the key length
// required for the record protocol, thus the client of the handshaker
// service needs to truncate the key data into the right key length.
bytes key_data = 3;
// The authenticated identity of the peer.
Identity peer_identity = 4;
// The local identity used in the handshake.
Identity local_identity = 5;
// Indicate whether the handshaker service client should keep the channel
// between the handshaker service open, e.g., in order to handle
// post-handshake messages in the future.
bool keep_channel_open = 6;
// The RPC protocol versions supported by the peer.
RpcProtocolVersions peer_rpc_versions = 7;
}
message HandshakerStatus {
// The status code. This could be the gRPC status code.
uint32 code = 1;
// The status details.
string details = 2;
}
message HandshakerResp {
// Frames to be given to the peer for the NextHandshakeMessageReq. May be
// empty if no out_frames have to be sent to the peer or if in_bytes in the
// HandshakerReq are incomplete. All the non-empty out frames must be sent to
// the peer even if the handshaker status is not OK as these frames may
// contain the alert frames.
bytes out_frames = 1;
// Number of bytes in the in_bytes consumed by the handshaker. It is possible
// that part of in_bytes in HandshakerReq was unrelated to the handshake
// process.
uint32 bytes_consumed = 2;
// This is set iff the handshake was successful. out_frames may still be set
// to frames that needs to be forwarded to the peer.
HandshakerResult result = 3;
// Status of the handshaker.
HandshakerStatus status = 4;
}
service HandshakerService {
// Accepts a stream of handshaker request, returning a stream of handshaker
// response.
rpc DoHandshake(stream HandshakerReq)
returns (stream HandshakerResp) {
}
}

@ -0,0 +1,40 @@
// 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.
syntax = "proto3";
package grpc.gcp;
option java_package = "io.grpc.alts";
// The security level of the created channel. The list is sorted in increasing
// level of security. This order must always be maintained.
enum SecurityLevel {
SECURITY_NONE = 0;
INTEGRITY_ONLY = 1;
INTEGRITY_AND_PRIVACY = 2;
}
// Max and min supported RPC protocol versions.
message RpcProtocolVersions {
// RPC version contains a major version and a minor version.
message Version {
uint32 major = 1;
uint32 minor = 2;
}
// Maximum supported RPC version.
Version max_rpc_version = 1;
// Minimum supported RPC version.
Version min_rpc_version = 2;
}

@ -0,0 +1,50 @@
/* Automatically generated nanopb constant definitions */
/* Generated by nanopb-0.3.7-dev */
#include "src/core/tsi/alts/handshaker/transport_security_common.pb.h"
/* @@protoc_insertion_point(includes) */
#if PB_PROTO_HEADER_VERSION != 30
#error Regenerate this file with the current version of nanopb generator.
#endif
const pb_field_t grpc_gcp_RpcProtocolVersions_fields[3] = {
PB_FIELD( 1, MESSAGE , OPTIONAL, STATIC , FIRST, grpc_gcp_RpcProtocolVersions, max_rpc_version, max_rpc_version, &grpc_gcp_RpcProtocolVersions_Version_fields),
PB_FIELD( 2, MESSAGE , OPTIONAL, STATIC , OTHER, grpc_gcp_RpcProtocolVersions, min_rpc_version, max_rpc_version, &grpc_gcp_RpcProtocolVersions_Version_fields),
PB_LAST_FIELD
};
const pb_field_t grpc_gcp_RpcProtocolVersions_Version_fields[3] = {
PB_FIELD( 1, UINT32 , OPTIONAL, STATIC , FIRST, grpc_gcp_RpcProtocolVersions_Version, major, major, 0),
PB_FIELD( 2, UINT32 , OPTIONAL, STATIC , OTHER, grpc_gcp_RpcProtocolVersions_Version, minor, major, 0),
PB_LAST_FIELD
};
/* Check that field information fits in pb_field_t */
#if !defined(PB_FIELD_32BIT)
/* If you get an error here, it means that you need to define PB_FIELD_32BIT
* compile-time option. You can do that in pb.h or on compiler command line.
*
* The reason you need to do this is that some of your messages contain tag
* numbers or field sizes that are larger than what can fit in 8 or 16 bit
* field descriptors.
*/
PB_STATIC_ASSERT((pb_membersize(grpc_gcp_RpcProtocolVersions, max_rpc_version) < 65536 && pb_membersize(grpc_gcp_RpcProtocolVersions, min_rpc_version) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_grpc_gcp_RpcProtocolVersions_grpc_gcp_RpcProtocolVersions_Version)
#endif
#if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT)
/* If you get an error here, it means that you need to define PB_FIELD_16BIT
* compile-time option. You can do that in pb.h or on compiler command line.
*
* The reason you need to do this is that some of your messages contain tag
* numbers or field sizes that are larger than what can fit in the default
* 8 bit descriptors.
*/
PB_STATIC_ASSERT((pb_membersize(grpc_gcp_RpcProtocolVersions, max_rpc_version) < 256 && pb_membersize(grpc_gcp_RpcProtocolVersions, min_rpc_version) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_grpc_gcp_RpcProtocolVersions_grpc_gcp_RpcProtocolVersions_Version)
#endif
/* @@protoc_insertion_point(eof) */

@ -0,0 +1,78 @@
/* Automatically generated nanopb header */
/* Generated by nanopb-0.3.7-dev */
#ifndef PB_GRPC_GCP_TRANSPORT_SECURITY_COMMON_PB_H_INCLUDED
#define PB_GRPC_GCP_TRANSPORT_SECURITY_COMMON_PB_H_INCLUDED
#include "third_party/nanopb/pb.h"
/* @@protoc_insertion_point(includes) */
#if PB_PROTO_HEADER_VERSION != 30
#error Regenerate this file with the current version of nanopb generator.
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* Enum definitions */
typedef enum _grpc_gcp_SecurityLevel {
grpc_gcp_SecurityLevel_SECURITY_NONE = 0,
grpc_gcp_SecurityLevel_INTEGRITY_ONLY = 1,
grpc_gcp_SecurityLevel_INTEGRITY_AND_PRIVACY = 2
} grpc_gcp_SecurityLevel;
#define _grpc_gcp_SecurityLevel_MIN grpc_gcp_SecurityLevel_SECURITY_NONE
#define _grpc_gcp_SecurityLevel_MAX grpc_gcp_SecurityLevel_INTEGRITY_AND_PRIVACY
#define _grpc_gcp_SecurityLevel_ARRAYSIZE ((grpc_gcp_SecurityLevel)(grpc_gcp_SecurityLevel_INTEGRITY_AND_PRIVACY+1))
/* Struct definitions */
typedef struct _grpc_gcp_RpcProtocolVersions_Version {
bool has_major;
uint32_t major;
bool has_minor;
uint32_t minor;
/* @@protoc_insertion_point(struct:grpc_gcp_RpcProtocolVersions_Version) */
} grpc_gcp_RpcProtocolVersions_Version;
typedef struct _grpc_gcp_RpcProtocolVersions {
bool has_max_rpc_version;
grpc_gcp_RpcProtocolVersions_Version max_rpc_version;
bool has_min_rpc_version;
grpc_gcp_RpcProtocolVersions_Version min_rpc_version;
/* @@protoc_insertion_point(struct:grpc_gcp_RpcProtocolVersions) */
} grpc_gcp_RpcProtocolVersions;
/* Default values for struct fields */
/* Initializer values for message structs */
#define grpc_gcp_RpcProtocolVersions_init_default {false, grpc_gcp_RpcProtocolVersions_Version_init_default, false, grpc_gcp_RpcProtocolVersions_Version_init_default}
#define grpc_gcp_RpcProtocolVersions_Version_init_default {false, 0, false, 0}
#define grpc_gcp_RpcProtocolVersions_init_zero {false, grpc_gcp_RpcProtocolVersions_Version_init_zero, false, grpc_gcp_RpcProtocolVersions_Version_init_zero}
#define grpc_gcp_RpcProtocolVersions_Version_init_zero {false, 0, false, 0}
/* Field tags (for use in manual encoding/decoding) */
#define grpc_gcp_RpcProtocolVersions_Version_major_tag 1
#define grpc_gcp_RpcProtocolVersions_Version_minor_tag 2
#define grpc_gcp_RpcProtocolVersions_max_rpc_version_tag 1
#define grpc_gcp_RpcProtocolVersions_min_rpc_version_tag 2
/* Struct field encoding specification for nanopb */
extern const pb_field_t grpc_gcp_RpcProtocolVersions_fields[3];
extern const pb_field_t grpc_gcp_RpcProtocolVersions_Version_fields[3];
/* Maximum encoded size of messages (where known) */
#define grpc_gcp_RpcProtocolVersions_size 28
#define grpc_gcp_RpcProtocolVersions_Version_size 12
/* Message IDs (where set with "msgid" option) */
#ifdef PB_MSGID
#define TRANSPORT_SECURITY_COMMON_MESSAGES \
#endif
#ifdef __cplusplus
} /* extern "C" */
#endif
/* @@protoc_insertion_point(eof) */
#endif

@ -0,0 +1,196 @@
/*
*
* 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/transport_security_common_api.h"
bool grpc_gcp_rpc_protocol_versions_set_max(
grpc_gcp_rpc_protocol_versions* versions, uint32_t max_major,
uint32_t max_minor) {
if (versions == nullptr) {
gpr_log(GPR_ERROR,
"versions is nullptr in "
"grpc_gcp_rpc_protocol_versions_set_max().");
return false;
}
versions->has_max_rpc_version = true;
versions->max_rpc_version.has_major = true;
versions->max_rpc_version.has_minor = true;
versions->max_rpc_version.major = max_major;
versions->max_rpc_version.minor = max_minor;
return true;
}
bool grpc_gcp_rpc_protocol_versions_set_min(
grpc_gcp_rpc_protocol_versions* versions, uint32_t min_major,
uint32_t min_minor) {
if (versions == nullptr) {
gpr_log(GPR_ERROR,
"versions is nullptr in "
"grpc_gcp_rpc_protocol_versions_set_min().");
return false;
}
versions->has_min_rpc_version = true;
versions->min_rpc_version.has_major = true;
versions->min_rpc_version.has_minor = true;
versions->min_rpc_version.major = min_major;
versions->min_rpc_version.minor = min_minor;
return true;
}
size_t grpc_gcp_rpc_protocol_versions_encode_length(
const grpc_gcp_rpc_protocol_versions* versions) {
if (versions == nullptr) {
gpr_log(GPR_ERROR,
"Invalid nullptr arguments to "
"grpc_gcp_rpc_protocol_versions_encode_length().");
return 0;
}
pb_ostream_t size_stream;
memset(&size_stream, 0, sizeof(pb_ostream_t));
if (!pb_encode(&size_stream, grpc_gcp_RpcProtocolVersions_fields, versions)) {
gpr_log(GPR_ERROR, "nanopb error: %s", PB_GET_ERROR(&size_stream));
return 0;
}
return size_stream.bytes_written;
}
bool grpc_gcp_rpc_protocol_versions_encode_to_raw_bytes(
const grpc_gcp_rpc_protocol_versions* versions, uint8_t* bytes,
size_t bytes_length) {
if (versions == nullptr || bytes == nullptr || bytes_length == 0) {
gpr_log(GPR_ERROR,
"Invalid nullptr arguments to "
"grpc_gcp_rpc_protocol_versions_encode_to_raw_bytes().");
return false;
}
pb_ostream_t output_stream = pb_ostream_from_buffer(bytes, bytes_length);
if (!pb_encode(&output_stream, grpc_gcp_RpcProtocolVersions_fields,
versions)) {
gpr_log(GPR_ERROR, "nanopb error: %s", PB_GET_ERROR(&output_stream));
return false;
}
return true;
}
bool grpc_gcp_rpc_protocol_versions_encode(
const grpc_gcp_rpc_protocol_versions* versions, grpc_slice* slice) {
if (versions == nullptr || slice == nullptr) {
gpr_log(GPR_ERROR,
"Invalid nullptr arguments to "
"grpc_gcp_rpc_protocol_versions_encode().");
return false;
}
size_t encoded_length =
grpc_gcp_rpc_protocol_versions_encode_length(versions);
if (encoded_length == 0) return false;
*slice = grpc_slice_malloc(encoded_length);
return grpc_gcp_rpc_protocol_versions_encode_to_raw_bytes(
versions, GRPC_SLICE_START_PTR(*slice), encoded_length);
}
bool grpc_gcp_rpc_protocol_versions_decode(
grpc_slice slice, grpc_gcp_rpc_protocol_versions* versions) {
if (versions == nullptr) {
gpr_log(GPR_ERROR,
"version is nullptr in "
"grpc_gcp_rpc_protocol_versions_decode().");
return false;
}
pb_istream_t stream = pb_istream_from_buffer(GRPC_SLICE_START_PTR(slice),
GRPC_SLICE_LENGTH(slice));
if (!pb_decode(&stream, grpc_gcp_RpcProtocolVersions_fields, versions)) {
gpr_log(GPR_ERROR, "nanopb error: %s", PB_GET_ERROR(&stream));
return false;
}
return true;
}
bool grpc_gcp_rpc_protocol_versions_copy(
const grpc_gcp_rpc_protocol_versions* src,
grpc_gcp_rpc_protocol_versions* dst) {
if ((src == nullptr && dst != nullptr) ||
(src != nullptr && dst == nullptr)) {
gpr_log(GPR_ERROR,
"Invalid arguments to "
"grpc_gcp_rpc_protocol_versions_copy().");
return false;
}
if (src == nullptr) {
return true;
}
grpc_gcp_rpc_protocol_versions_set_max(dst, src->max_rpc_version.major,
src->max_rpc_version.minor);
grpc_gcp_rpc_protocol_versions_set_min(dst, src->min_rpc_version.major,
src->min_rpc_version.minor);
return true;
}
namespace grpc_core {
namespace internal {
int grpc_gcp_rpc_protocol_version_compare(
const grpc_gcp_rpc_protocol_versions_version* v1,
const grpc_gcp_rpc_protocol_versions_version* v2) {
if ((v1->major > v2->major) ||
(v1->major == v2->major && v1->minor > v2->minor)) {
return 1;
}
if ((v1->major < v2->major) ||
(v1->major == v2->major && v1->minor < v2->minor)) {
return -1;
}
return 0;
}
} // namespace internal
} // namespace grpc_core
bool grpc_gcp_rpc_protocol_versions_check(
const grpc_gcp_rpc_protocol_versions* local_versions,
const grpc_gcp_rpc_protocol_versions* peer_versions,
grpc_gcp_rpc_protocol_versions_version* highest_common_version) {
if (local_versions == nullptr || peer_versions == nullptr) {
gpr_log(GPR_ERROR,
"Invalid arguments to "
"grpc_gcp_rpc_protocol_versions_check().");
return false;
}
/* max_common_version is MIN(local.max, peer.max) */
const grpc_gcp_rpc_protocol_versions_version* max_common_version =
grpc_core::internal::grpc_gcp_rpc_protocol_version_compare(
&local_versions->max_rpc_version, &peer_versions->max_rpc_version) > 0
? &peer_versions->max_rpc_version
: &local_versions->max_rpc_version;
/* min_common_version is MAX(local.min, peer.min) */
const grpc_gcp_rpc_protocol_versions_version* min_common_version =
grpc_core::internal::grpc_gcp_rpc_protocol_version_compare(
&local_versions->min_rpc_version, &peer_versions->min_rpc_version) > 0
? &local_versions->min_rpc_version
: &peer_versions->min_rpc_version;
bool result = grpc_core::internal::grpc_gcp_rpc_protocol_version_compare(
max_common_version, min_common_version) >= 0
? true
: false;
if (result && highest_common_version != nullptr) {
memcpy(highest_common_version, max_common_version,
sizeof(grpc_gcp_rpc_protocol_versions_version));
}
return result;
}

@ -0,0 +1,163 @@
/*
*
* 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.
*
*/
#ifndef GRPC_CORE_TSI_ALTS_HANDSHAKER_TRANSPORT_SECURITY_COMMON_API_H
#define GRPC_CORE_TSI_ALTS_HANDSHAKER_TRANSPORT_SECURITY_COMMON_API_H
#include <grpc/support/port_platform.h>
#include "third_party/nanopb/pb_decode.h"
#include "third_party/nanopb/pb_encode.h"
#include <grpc/slice.h>
#include <grpc/slice_buffer.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include "src/core/tsi/alts/handshaker/transport_security_common.pb.h"
typedef grpc_gcp_RpcProtocolVersions grpc_gcp_rpc_protocol_versions;
typedef grpc_gcp_RpcProtocolVersions_Version
grpc_gcp_rpc_protocol_versions_version;
/**
* This method sets the value for max_rpc_versions field of rpc protocol
* versions.
*
* - versions: an rpc protocol version instance.
* - max_major: a major version of maximum supported RPC version.
* - max_minor: a minor version of maximum supported RPC version.
*
* The method returns true on success and false otherwise.
*/
bool grpc_gcp_rpc_protocol_versions_set_max(
grpc_gcp_rpc_protocol_versions* versions, uint32_t max_major,
uint32_t max_minor);
/**
* This method sets the value for min_rpc_versions field of rpc protocol
* versions.
*
* - versions: an rpc protocol version instance.
* - min_major: a major version of minimum supported RPC version.
* - min_minor: a minor version of minimum supported RPC version.
*
* The method returns true on success and false otherwise.
*/
bool grpc_gcp_rpc_protocol_versions_set_min(
grpc_gcp_rpc_protocol_versions* versions, uint32_t min_major,
uint32_t min_minor);
/**
* This method computes serialized byte length of rpc protocol versions.
*
* - versions: an rpc protocol versions instance.
*
* The method returns serialized byte length. It returns 0 on failure.
*/
size_t grpc_gcp_rpc_protocol_versions_encode_length(
const grpc_gcp_rpc_protocol_versions* versions);
/**
* This method serializes rpc protocol versions and writes the result to
* the memory buffer provided by the caller. Caller is responsible for
* allocating sufficient memory to store the serialized data.
*
* - versions: an rpc protocol versions instance.
* - bytes: bytes buffer where the result will be written to.
* - bytes_length: length of the bytes buffer.
*
* The method returns true on success and false otherwise.
*/
bool grpc_gcp_rpc_protocol_versions_encode_to_raw_bytes(
const grpc_gcp_rpc_protocol_versions* versions, uint8_t* bytes,
size_t bytes_length);
/**
* This method serializes an rpc protocol version and returns serialized rpc
* versions in grpc slice.
*
* - versions: an rpc protocol versions instance.
* - slice: grpc slice where the serialized result will be written.
*
* The method returns true on success and false otherwise.
*/
bool grpc_gcp_rpc_protocol_versions_encode(
const grpc_gcp_rpc_protocol_versions* versions, grpc_slice* slice);
/**
* This method de-serializes input in grpc slice form and stores the result
* in rpc protocol versions.
*
* - slice: a data stream containing a serialized rpc protocol version.
* - versions: an rpc protocol version instance used to hold de-serialized
* result.
*
* The method returns true on success and false otherwise.
*/
bool grpc_gcp_rpc_protocol_versions_decode(
grpc_slice slice, grpc_gcp_rpc_protocol_versions* versions);
/**
* This method performs a deep copy operation on rpc protocol versions
* instance.
*
* - src: rpc protocol versions instance that needs to be copied.
* - dst: rpc protocol versions instance that stores the copied result.
*
* The method returns true on success and false otherwise.
*/
bool grpc_gcp_rpc_protocol_versions_copy(
const grpc_gcp_rpc_protocol_versions* src,
grpc_gcp_rpc_protocol_versions* dst);
/**
* This method performs a version check between local and peer rpc protocol
* versions.
*
* - local_versions: local rpc protocol versions instance.
* - peer_versions: peer rpc protocol versions instance.
* - highest_common_version: an output parameter that will store the highest
* common rpc protocol version both parties agreed on.
*
* The method returns true if the check passes which means both parties agreed
* on a common rpc protocol to use, and false otherwise.
*/
bool grpc_gcp_rpc_protocol_versions_check(
const grpc_gcp_rpc_protocol_versions* local_versions,
const grpc_gcp_rpc_protocol_versions* peer_versions,
grpc_gcp_rpc_protocol_versions_version* highest_common_version);
namespace grpc_core {
namespace internal {
/**
* Exposed for testing only.
* The method returns 0 if v1 = v2,
* returns 1 if v1 > v2,
* returns -1 if v1 < v2.
*/
int grpc_gcp_rpc_protocol_version_compare(
const grpc_gcp_rpc_protocol_versions_version* v1,
const grpc_gcp_rpc_protocol_versions_version* v2);
} // namespace internal
} // namespace grpc_core
#endif /* GRPC_CORE_TSI_ALTS_HANDSHAKER_TRANSPORT_SECURITY_COMMON_API_H */

@ -0,0 +1,180 @@
/*
*
* 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/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_common.h"
#include "src/core/tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol.h"
/* Main struct for alts_grpc_integrity_only_record_protocol. */
typedef struct alts_grpc_integrity_only_record_protocol {
alts_grpc_record_protocol base;
grpc_slice_buffer data_sb;
unsigned char* tag_buf;
} alts_grpc_integrity_only_record_protocol;
/* --- alts_grpc_record_protocol methods implementation. --- */
static tsi_result alts_grpc_integrity_only_protect(
alts_grpc_record_protocol* rp, grpc_slice_buffer* unprotected_slices,
grpc_slice_buffer* protected_slices) {
/* Input sanity check. */
if (rp == nullptr || unprotected_slices == nullptr ||
protected_slices == nullptr) {
gpr_log(GPR_ERROR,
"Invalid nullptr arguments to alts_grpc_record_protocol protect.");
return TSI_INVALID_ARGUMENT;
}
/* Allocates memory for header and tag slices. */
grpc_slice header_slice = GRPC_SLICE_MALLOC(rp->header_length);
grpc_slice tag_slice = GRPC_SLICE_MALLOC(rp->tag_length);
/* Calls alts_iovec_record_protocol protect. */
char* error_details = nullptr;
iovec_t header_iovec = {GRPC_SLICE_START_PTR(header_slice),
GRPC_SLICE_LENGTH(header_slice)};
iovec_t tag_iovec = {GRPC_SLICE_START_PTR(tag_slice),
GRPC_SLICE_LENGTH(tag_slice)};
alts_grpc_record_protocol_convert_slice_buffer_to_iovec(rp,
unprotected_slices);
grpc_status_code status = alts_iovec_record_protocol_integrity_only_protect(
rp->iovec_rp, rp->iovec_buf, unprotected_slices->count, header_iovec,
tag_iovec, &error_details);
if (status != GRPC_STATUS_OK) {
gpr_log(GPR_ERROR, "Failed to protect, %s", error_details);
gpr_free(error_details);
return TSI_INTERNAL_ERROR;
}
/* Appends result to protected_slices. */
grpc_slice_buffer_add(protected_slices, header_slice);
grpc_slice_buffer_move_into(unprotected_slices, protected_slices);
grpc_slice_buffer_add(protected_slices, tag_slice);
return TSI_OK;
}
static tsi_result alts_grpc_integrity_only_unprotect(
alts_grpc_record_protocol* rp, grpc_slice_buffer* protected_slices,
grpc_slice_buffer* unprotected_slices) {
/* Input sanity check. */
if (rp == nullptr || protected_slices == nullptr ||
unprotected_slices == nullptr) {
gpr_log(
GPR_ERROR,
"Invalid nullptr arguments to alts_grpc_record_protocol unprotect.");
return TSI_INVALID_ARGUMENT;
}
if (protected_slices->length < rp->header_length + rp->tag_length) {
gpr_log(GPR_ERROR, "Protected slices do not have sufficient data.");
return TSI_INVALID_ARGUMENT;
}
/* In this method, rp points to alts_grpc_record_protocol struct
* and integrity_only_record_protocol points to
* alts_grpc_integrity_only_record_protocol struct. */
alts_grpc_integrity_only_record_protocol* integrity_only_record_protocol =
reinterpret_cast<alts_grpc_integrity_only_record_protocol*>(rp);
/* Strips frame header from protected slices. */
grpc_slice_buffer_reset_and_unref_internal(&rp->header_sb);
grpc_slice_buffer_move_first(protected_slices, rp->header_length,
&rp->header_sb);
GPR_ASSERT(rp->header_sb.length == rp->header_length);
iovec_t header_iovec = alts_grpc_record_protocol_get_header_iovec(rp);
/* Moves protected slices data to data_sb and leaves the remaining tag. */
grpc_slice_buffer_reset_and_unref_internal(
&integrity_only_record_protocol->data_sb);
grpc_slice_buffer_move_first(protected_slices,
protected_slices->length - rp->tag_length,
&integrity_only_record_protocol->data_sb);
GPR_ASSERT(protected_slices->length == rp->tag_length);
iovec_t tag_iovec = {nullptr, rp->tag_length};
if (protected_slices->count == 1) {
tag_iovec.iov_base = GRPC_SLICE_START_PTR(protected_slices->slices[0]);
} else {
/* Frame tag is in multiple slices, copies the tag bytes from slice
* buffer to a single flat buffer. */
alts_grpc_record_protocol_copy_slice_buffer(
protected_slices, integrity_only_record_protocol->tag_buf);
tag_iovec.iov_base = integrity_only_record_protocol->tag_buf;
}
/* Calls alts_iovec_record_protocol unprotect. */
char* error_details = nullptr;
alts_grpc_record_protocol_convert_slice_buffer_to_iovec(
rp, &integrity_only_record_protocol->data_sb);
grpc_status_code status = alts_iovec_record_protocol_integrity_only_unprotect(
rp->iovec_rp, rp->iovec_buf,
integrity_only_record_protocol->data_sb.count, header_iovec, tag_iovec,
&error_details);
if (status != GRPC_STATUS_OK) {
gpr_log(GPR_ERROR, "Failed to unprotect, %s", error_details);
gpr_free(error_details);
return TSI_INTERNAL_ERROR;
}
grpc_slice_buffer_reset_and_unref_internal(&rp->header_sb);
grpc_slice_buffer_reset_and_unref_internal(protected_slices);
grpc_slice_buffer_move_into(&integrity_only_record_protocol->data_sb,
unprotected_slices);
return TSI_OK;
}
static void alts_grpc_integrity_only_destruct(alts_grpc_record_protocol* rp) {
if (rp == nullptr) {
return;
}
alts_grpc_integrity_only_record_protocol* integrity_only_rp =
reinterpret_cast<alts_grpc_integrity_only_record_protocol*>(rp);
grpc_slice_buffer_destroy_internal(&integrity_only_rp->data_sb);
gpr_free(integrity_only_rp->tag_buf);
}
static const alts_grpc_record_protocol_vtable
alts_grpc_integrity_only_record_protocol_vtable = {
alts_grpc_integrity_only_protect, alts_grpc_integrity_only_unprotect,
alts_grpc_integrity_only_destruct};
tsi_result alts_grpc_integrity_only_record_protocol_create(
gsec_aead_crypter* crypter, size_t overflow_size, bool is_client,
bool is_protect, alts_grpc_record_protocol** rp) {
if (crypter == nullptr || rp == nullptr) {
gpr_log(GPR_ERROR,
"Invalid nullptr arguments to alts_grpc_record_protocol create.");
return TSI_INVALID_ARGUMENT;
}
alts_grpc_integrity_only_record_protocol* impl =
static_cast<alts_grpc_integrity_only_record_protocol*>(
gpr_zalloc(sizeof(alts_grpc_integrity_only_record_protocol)));
/* Calls alts_grpc_record_protocol init. */
tsi_result result = alts_grpc_record_protocol_init(
&impl->base, crypter, overflow_size, is_client,
/*is_integrity_only=*/true, is_protect);
if (result != TSI_OK) {
gpr_free(impl);
return result;
}
/* Initializes slice buffer for data_sb. */
grpc_slice_buffer_init(&impl->data_sb);
/* Allocates tag buffer. */
impl->tag_buf =
static_cast<unsigned char*>(gpr_malloc(impl->base.tag_length));
impl->base.vtable = &alts_grpc_integrity_only_record_protocol_vtable;
*rp = &impl->base;
return TSI_OK;
}

@ -0,0 +1,52 @@
/*
*
* 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.
*
*/
#ifndef GRPC_CORE_TSI_ALTS_ZERO_COPY_FRAME_PROTECTOR_ALTS_GRPC_INTEGRITY_ONLY_RECORD_PROTOCOL_H
#define GRPC_CORE_TSI_ALTS_ZERO_COPY_FRAME_PROTECTOR_ALTS_GRPC_INTEGRITY_ONLY_RECORD_PROTOCOL_H
#include <grpc/support/port_platform.h>
#include <stdbool.h>
#include "src/core/tsi/alts/crypt/gsec.h"
#include "src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol.h"
/**
* This method creates an integrity-only alts_grpc_record_protocol instance,
* given a gsec_aead_crypter instance and a flag indicating if the created
* instance will be used at the client or server side. The ownership of
* gsec_aead_crypter instance is transferred to this new object.
*
* - crypter: a gsec_aead_crypter instance used to perform AEAD decryption.
* - overflow_size: overflow size of counter in bytes.
* - is_client: a flag indicating if the alts_grpc_record_protocol instance will
* be used at the client or server side.
* - is_protect: a flag indicating if the alts_grpc_record_protocol instance
* will be used for protect or unprotect.
* - rp: an alts_grpc_record_protocol instance to be returned from
* the method.
*
* This method returns TSI_OK in case of success or a specific error code in
* case of failure.
*/
tsi_result alts_grpc_integrity_only_record_protocol_create(
gsec_aead_crypter* crypter, size_t overflow_size, bool is_client,
bool is_protect, alts_grpc_record_protocol** rp);
#endif /* GRPC_CORE_TSI_ALTS_ZERO_COPY_FRAME_PROTECTOR_ALTS_GRPC_INTEGRITY_ONLY_RECORD_PROTOCOL_H \
*/

@ -0,0 +1,144 @@
/*
*
* 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/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_common.h"
#include "src/core/tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol.h"
/* Privacy-integrity alts_grpc_record_protocol object uses the same struct
* defined in alts_grpc_record_protocol_common.h. */
/* --- alts_grpc_record_protocol methods implementation. --- */
static tsi_result alts_grpc_privacy_integrity_protect(
alts_grpc_record_protocol* rp, grpc_slice_buffer* unprotected_slices,
grpc_slice_buffer* protected_slices) {
/* Input sanity check. */
if (rp == nullptr || unprotected_slices == nullptr ||
protected_slices == nullptr) {
gpr_log(GPR_ERROR,
"Invalid nullptr arguments to alts_grpc_record_protocol protect.");
return TSI_INVALID_ARGUMENT;
}
/* Allocates memory for output frame. In privacy-integrity protect, the
* protected frame is stored in a newly allocated buffer. */
size_t protected_frame_size =
unprotected_slices->length + rp->header_length +
alts_iovec_record_protocol_get_tag_length(rp->iovec_rp);
grpc_slice protected_slice = GRPC_SLICE_MALLOC(protected_frame_size);
iovec_t protected_iovec = {GRPC_SLICE_START_PTR(protected_slice),
GRPC_SLICE_LENGTH(protected_slice)};
/* Calls alts_iovec_record_protocol protect. */
char* error_details = nullptr;
alts_grpc_record_protocol_convert_slice_buffer_to_iovec(rp,
unprotected_slices);
grpc_status_code status =
alts_iovec_record_protocol_privacy_integrity_protect(
rp->iovec_rp, rp->iovec_buf, unprotected_slices->count,
protected_iovec, &error_details);
if (status != GRPC_STATUS_OK) {
gpr_log(GPR_ERROR, "Failed to protect, %s", error_details);
gpr_free(error_details);
grpc_slice_unref(protected_slice);
return TSI_INTERNAL_ERROR;
}
grpc_slice_buffer_add(protected_slices, protected_slice);
grpc_slice_buffer_reset_and_unref_internal(unprotected_slices);
return TSI_OK;
}
static tsi_result alts_grpc_privacy_integrity_unprotect(
alts_grpc_record_protocol* rp, grpc_slice_buffer* protected_slices,
grpc_slice_buffer* unprotected_slices) {
/* Input sanity check. */
if (rp == nullptr || protected_slices == nullptr ||
unprotected_slices == nullptr) {
gpr_log(
GPR_ERROR,
"Invalid nullptr arguments to alts_grpc_record_protocol unprotect.");
return TSI_INVALID_ARGUMENT;
}
/* Allocates memory for output frame. In privacy-integrity unprotect, the
* unprotected data are stored in a newly allocated buffer. */
if (protected_slices->length < rp->header_length + rp->tag_length) {
gpr_log(GPR_ERROR, "Protected slices do not have sufficient data.");
return TSI_INVALID_ARGUMENT;
}
size_t unprotected_frame_size =
protected_slices->length - rp->header_length - rp->tag_length;
grpc_slice unprotected_slice = GRPC_SLICE_MALLOC(unprotected_frame_size);
iovec_t unprotected_iovec = {GRPC_SLICE_START_PTR(unprotected_slice),
GRPC_SLICE_LENGTH(unprotected_slice)};
/* Strips frame header from protected slices. */
grpc_slice_buffer_reset_and_unref_internal(&rp->header_sb);
grpc_slice_buffer_move_first(protected_slices, rp->header_length,
&rp->header_sb);
iovec_t header_iovec = alts_grpc_record_protocol_get_header_iovec(rp);
/* Calls alts_iovec_record_protocol unprotect. */
char* error_details = nullptr;
alts_grpc_record_protocol_convert_slice_buffer_to_iovec(rp, protected_slices);
grpc_status_code status =
alts_iovec_record_protocol_privacy_integrity_unprotect(
rp->iovec_rp, header_iovec, rp->iovec_buf, protected_slices->count,
unprotected_iovec, &error_details);
if (status != GRPC_STATUS_OK) {
gpr_log(GPR_ERROR, "Failed to unprotect, %s", error_details);
gpr_free(error_details);
grpc_slice_unref(unprotected_slice);
return TSI_INTERNAL_ERROR;
}
grpc_slice_buffer_reset_and_unref_internal(&rp->header_sb);
grpc_slice_buffer_reset_and_unref_internal(protected_slices);
grpc_slice_buffer_add(unprotected_slices, unprotected_slice);
return TSI_OK;
}
static const alts_grpc_record_protocol_vtable
alts_grpc_privacy_integrity_record_protocol_vtable = {
alts_grpc_privacy_integrity_protect,
alts_grpc_privacy_integrity_unprotect, nullptr};
tsi_result alts_grpc_privacy_integrity_record_protocol_create(
gsec_aead_crypter* crypter, size_t overflow_size, bool is_client,
bool is_protect, alts_grpc_record_protocol** rp) {
if (crypter == nullptr || rp == nullptr) {
gpr_log(GPR_ERROR,
"Invalid nullptr arguments to alts_grpc_record_protocol create.");
return TSI_INVALID_ARGUMENT;
}
auto* impl = static_cast<alts_grpc_record_protocol*>(
gpr_zalloc(sizeof(alts_grpc_record_protocol)));
/* Calls alts_grpc_record_protocol init. */
tsi_result result =
alts_grpc_record_protocol_init(impl, crypter, overflow_size, is_client,
/*is_integrity_only=*/false, is_protect);
if (result != TSI_OK) {
gpr_free(impl);
return result;
}
impl->vtable = &alts_grpc_privacy_integrity_record_protocol_vtable;
*rp = impl;
return TSI_OK;
}

@ -0,0 +1,49 @@
/*
*
* 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.
*
*/
#ifndef GRPC_CORE_TSI_ALTS_ZERO_COPY_FRAME_PROTECTOR_ALTS_GRPC_PRIVACY_INTEGRITY_RECORD_PROTOCOL_H
#define GRPC_CORE_TSI_ALTS_ZERO_COPY_FRAME_PROTECTOR_ALTS_GRPC_PRIVACY_INTEGRITY_RECORD_PROTOCOL_H
#include <grpc/support/port_platform.h>
#include <stdbool.h>
#include "src/core/tsi/alts/crypt/gsec.h"
#include "src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol.h"
/**
* This method creates a privacy-integrity alts_grpc_record_protocol instance,
* given a gsec_aead_crypter instance and a flag indicating if the created
* instance will be used at the client or server side. The ownership of
* gsec_aead_crypter instance is transferred to this new object.
*
* - crypter: a gsec_aead_crypter instance used to perform AEAD decryption.
* - is_client: a flag indicating if the alts_grpc_record_protocol instance will
* be used at the client or server side.
* - rp: an alts_grpc_record_protocol instance to be returned from
* the method.
*
* This method returns TSI_OK in case of success or a specific error code in
* case of failure.
*/
tsi_result alts_grpc_privacy_integrity_record_protocol_create(
gsec_aead_crypter* crypter, size_t overflow_size, bool is_client,
bool is_protect, alts_grpc_record_protocol** rp);
#endif /* GRPC_CORE_TSI_ALTS_ZERO_COPY_FRAME_PROTECTOR_ALTS_GRPC_PRIVACY_INTEGRITY_RECORD_PROTOCOL_H \
*/

@ -0,0 +1,91 @@
/*
*
* 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.
*
*/
#ifndef GRPC_CORE_TSI_ALTS_ZERO_COPY_FRAME_PROTECTOR_ALTS_GRPC_RECORD_PROTOCOL_H
#define GRPC_CORE_TSI_ALTS_ZERO_COPY_FRAME_PROTECTOR_ALTS_GRPC_RECORD_PROTOCOL_H
#include <grpc/support/port_platform.h>
#include <grpc/slice_buffer.h>
#include "src/core/tsi/transport_security_interface.h"
/**
* This alts_grpc_record_protocol object protects and unprotects a single frame
* stored in grpc slice buffer with zero or minimized memory copy.
* Implementations of this object must be thread compatible.
*/
typedef struct alts_grpc_record_protocol alts_grpc_record_protocol;
/**
* This methods performs protect operation on unprotected data and appends the
* protected frame to protected_slices. The caller needs to ensure the length
* of unprotected data plus the frame overhead is less than or equal to the
* maximum frame length. The input unprotected data slice buffer will be
* cleared, although the actual unprotected data bytes are not modified.
*
* - self: an alts_grpc_record_protocol instance.
* - unprotected_slices: the unprotected data to be protected.
* - protected_slices: slice buffer where the protected frame is appended.
*
* This method returns TSI_OK in case of success or a specific error code in
* case of failure.
*/
tsi_result alts_grpc_record_protocol_protect(
alts_grpc_record_protocol* self, grpc_slice_buffer* unprotected_slices,
grpc_slice_buffer* protected_slices);
/**
* This methods performs unprotect operation on a full frame of protected data
* and appends unprotected data to unprotected_slices. It is the caller's
* responsibility to prepare a full frame of data before calling this method.
* The input protected frame slice buffer will be cleared, although the actual
* protected data bytes are not modified.
*
* - self: an alts_grpc_record_protocol instance.
* - protected_slices: a full frame of protected data in grpc slices.
* - unprotected_slices: slice buffer where unprotected data is appended.
*
* This method returns TSI_OK in case of success or a specific error code in
* case of failure.
*/
tsi_result alts_grpc_record_protocol_unprotect(
alts_grpc_record_protocol* self, grpc_slice_buffer* protected_slices,
grpc_slice_buffer* unprotected_slices);
/**
* This method returns maximum allowed unprotected data size, given maximum
* protected frame size.
*
* - self: an alts_grpc_record_protocol instance.
* - max_protected_frame_size: maximum protected frame size.
*
* On success, the method returns the maximum allowed unprotected data size.
* Otherwise, it returns zero.
*/
size_t alts_grpc_record_protocol_max_unprotected_data_size(
const alts_grpc_record_protocol* self, size_t max_protected_frame_size);
/**
* This method destroys an alts_grpc_record_protocol instance by de-allocating
* all of its occupied memory.
*/
void alts_grpc_record_protocol_destroy(alts_grpc_record_protocol* self);
#endif /* GRPC_CORE_TSI_ALTS_ZERO_COPY_FRAME_PROTECTOR_ALTS_GRPC_RECORD_PROTOCOL_H \
*/

@ -0,0 +1,173 @@
/*
*
* 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/zero_copy_frame_protector/alts_grpc_record_protocol_common.h"
#include <string.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include "src/core/lib/gpr/useful.h"
#include "src/core/lib/slice/slice_internal.h"
const size_t kInitialIovecBufferSize = 8;
/* Makes sure iovec_buf in alts_grpc_record_protocol is large enough. */
static void ensure_iovec_buf_size(alts_grpc_record_protocol* rp,
const grpc_slice_buffer* sb) {
GPR_ASSERT(rp != nullptr && sb != nullptr);
if (sb->count <= rp->iovec_buf_length) {
return;
}
/* At least double the iovec buffer size. */
rp->iovec_buf_length = GPR_MAX(sb->count, 2 * rp->iovec_buf_length);
rp->iovec_buf = static_cast<iovec_t*>(
gpr_realloc(rp->iovec_buf, rp->iovec_buf_length * sizeof(iovec_t)));
}
/* --- Implementation of methods defined in tsi_grpc_record_protocol_common.h.
* --- */
void alts_grpc_record_protocol_convert_slice_buffer_to_iovec(
alts_grpc_record_protocol* rp, const grpc_slice_buffer* sb) {
GPR_ASSERT(rp != nullptr && sb != nullptr);
ensure_iovec_buf_size(rp, sb);
for (size_t i = 0; i < sb->count; i++) {
rp->iovec_buf[i].iov_base = GRPC_SLICE_START_PTR(sb->slices[i]);
rp->iovec_buf[i].iov_len = GRPC_SLICE_LENGTH(sb->slices[i]);
}
}
void alts_grpc_record_protocol_copy_slice_buffer(const grpc_slice_buffer* src,
unsigned char* dst) {
GPR_ASSERT(src != nullptr && dst != nullptr);
for (size_t i = 0; i < src->count; i++) {
size_t slice_length = GRPC_SLICE_LENGTH(src->slices[i]);
memcpy(dst, GRPC_SLICE_START_PTR(src->slices[i]), slice_length);
dst += slice_length;
}
}
iovec_t alts_grpc_record_protocol_get_header_iovec(
alts_grpc_record_protocol* rp) {
iovec_t header_iovec = {nullptr, 0};
if (rp == nullptr) {
return header_iovec;
}
header_iovec.iov_len = rp->header_length;
if (rp->header_sb.count == 1) {
header_iovec.iov_base = GRPC_SLICE_START_PTR(rp->header_sb.slices[0]);
} else {
/* Frame header is in multiple slices, copies the header bytes from slice
* buffer to a single flat buffer. */
alts_grpc_record_protocol_copy_slice_buffer(&rp->header_sb, rp->header_buf);
header_iovec.iov_base = rp->header_buf;
}
return header_iovec;
}
tsi_result alts_grpc_record_protocol_init(alts_grpc_record_protocol* rp,
gsec_aead_crypter* crypter,
size_t overflow_size, bool is_client,
bool is_integrity_only,
bool is_protect) {
if (rp == nullptr || crypter == nullptr) {
gpr_log(GPR_ERROR,
"Invalid nullptr arguments to alts_grpc_record_protocol init.");
return TSI_INVALID_ARGUMENT;
}
/* Creates alts_iovec_record_protocol. */
char* error_details = nullptr;
grpc_status_code status = alts_iovec_record_protocol_create(
crypter, overflow_size, is_client, is_integrity_only, is_protect,
&rp->iovec_rp, &error_details);
if (status != GRPC_STATUS_OK) {
gpr_log(GPR_ERROR, "Failed to create alts_iovec_record_protocol, %s.",
error_details);
gpr_free(error_details);
return TSI_INTERNAL_ERROR;
}
/* Allocates header slice buffer. */
grpc_slice_buffer_init(&rp->header_sb);
/* Allocates header buffer. */
rp->header_length = alts_iovec_record_protocol_get_header_length();
rp->header_buf = static_cast<unsigned char*>(gpr_malloc(rp->header_length));
rp->tag_length = alts_iovec_record_protocol_get_tag_length(rp->iovec_rp);
/* Allocates iovec buffer. */
rp->iovec_buf_length = kInitialIovecBufferSize;
rp->iovec_buf =
static_cast<iovec_t*>(gpr_malloc(rp->iovec_buf_length * sizeof(iovec_t)));
return TSI_OK;
}
/* --- Implementation of methods defined in tsi_grpc_record_protocol.h. --- */
tsi_result alts_grpc_record_protocol_protect(
alts_grpc_record_protocol* self, grpc_slice_buffer* unprotected_slices,
grpc_slice_buffer* protected_slices) {
if (grpc_core::ExecCtx::Get() == nullptr || self == nullptr ||
self->vtable == nullptr || unprotected_slices == nullptr ||
protected_slices == nullptr) {
return TSI_INVALID_ARGUMENT;
}
if (self->vtable->protect == nullptr) {
return TSI_UNIMPLEMENTED;
}
return self->vtable->protect(self, unprotected_slices, protected_slices);
}
tsi_result alts_grpc_record_protocol_unprotect(
alts_grpc_record_protocol* self, grpc_slice_buffer* protected_slices,
grpc_slice_buffer* unprotected_slices) {
if (grpc_core::ExecCtx::Get() == nullptr || self == nullptr ||
self->vtable == nullptr || protected_slices == nullptr ||
unprotected_slices == nullptr) {
return TSI_INVALID_ARGUMENT;
}
if (self->vtable->unprotect == nullptr) {
return TSI_UNIMPLEMENTED;
}
return self->vtable->unprotect(self, protected_slices, unprotected_slices);
}
void alts_grpc_record_protocol_destroy(alts_grpc_record_protocol* self) {
if (self == nullptr) {
return;
}
if (self->vtable->destruct != nullptr) {
self->vtable->destruct(self);
}
alts_iovec_record_protocol_destroy(self->iovec_rp);
grpc_slice_buffer_destroy_internal(&self->header_sb);
gpr_free(self->header_buf);
gpr_free(self->iovec_buf);
gpr_free(self);
}
/* Integrity-only and privacy-integrity share the same implementation. No need
* to call vtable. */
size_t alts_grpc_record_protocol_max_unprotected_data_size(
const alts_grpc_record_protocol* self, size_t max_protected_frame_size) {
if (self == nullptr) {
return 0;
}
return alts_iovec_record_protocol_max_unprotected_data_size(
self->iovec_rp, max_protected_frame_size);
}

@ -0,0 +1,100 @@
/*
*
* 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.
*
*/
#ifndef GRPC_CORE_TSI_ALTS_ZERO_COPY_FRAME_PROTECTOR_ALTS_GRPC_RECORD_PROTOCOL_COMMON_H
#define GRPC_CORE_TSI_ALTS_ZERO_COPY_FRAME_PROTECTOR_ALTS_GRPC_RECORD_PROTOCOL_COMMON_H
/**
* this file contains alts_grpc_record_protocol internals and internal-only
* helper functions. The public functions of alts_grpc_record_protocol are
* defined in the alts_grpc_record_protocol.h.
*/
#include <grpc/support/port_platform.h>
#include "src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol.h"
#include "src/core/tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol.h"
/* V-table for alts_grpc_record_protocol implementations. */
typedef struct {
tsi_result (*protect)(alts_grpc_record_protocol* self,
grpc_slice_buffer* unprotected_slices,
grpc_slice_buffer* protected_slices);
tsi_result (*unprotect)(alts_grpc_record_protocol* self,
grpc_slice_buffer* protected_slices,
grpc_slice_buffer* unprotected_slices);
void (*destruct)(alts_grpc_record_protocol* self);
} alts_grpc_record_protocol_vtable;
/* Main struct for alts_grpc_record_protocol implementation, shared by both
* integrity-only record protocol and privacy-integrity record protocol.
* Integrity-only record protocol has additional data elements.
* Privacy-integrity record protocol uses this struct directly. */
struct alts_grpc_record_protocol {
const alts_grpc_record_protocol_vtable* vtable;
alts_iovec_record_protocol* iovec_rp;
grpc_slice_buffer header_sb;
unsigned char* header_buf;
size_t header_length;
size_t tag_length;
iovec_t* iovec_buf;
size_t iovec_buf_length;
};
/**
* Converts the slices of input sb into iovec_t's and puts the result into
* rp->iovec_buf. Note that the actual data are not copied, only
* pointers and lengths are copied.
*/
void alts_grpc_record_protocol_convert_slice_buffer_to_iovec(
alts_grpc_record_protocol* rp, const grpc_slice_buffer* sb);
/**
* Copies bytes from slice buffer to destination buffer. Caller is responsible
* for allocating enough memory of destination buffer. This method is used for
* copying frame header and tag in case they are stored in multiple slices.
*/
void alts_grpc_record_protocol_copy_slice_buffer(const grpc_slice_buffer* src,
unsigned char* dst);
/**
* This method returns an iovec object pointing to the frame header stored in
* rp->header_sb. If the frame header is stored in multiple slices,
* this method will copy the bytes in rp->header_sb to
* rp->header_buf, and return an iovec object pointing to
* rp->header_buf.
*/
iovec_t alts_grpc_record_protocol_get_header_iovec(
alts_grpc_record_protocol* rp);
/**
* Initializes an alts_grpc_record_protocol object, given a gsec_aead_crypter
* instance, the overflow size of the counter in bytes, a flag indicating if the
* object is used for client or server side, a flag indicating if it is used for
* integrity-only or privacy-integrity mode, and a flag indicating if it is for
* protect or unprotect. The ownership of gsec_aead_crypter object is
* transferred to the alts_grpc_record_protocol object.
*/
tsi_result alts_grpc_record_protocol_init(alts_grpc_record_protocol* rp,
gsec_aead_crypter* crypter,
size_t overflow_size, bool is_client,
bool is_integrity_only,
bool is_protect);
#endif /* GRPC_CORE_TSI_ALTS_ZERO_COPY_FRAME_PROTECTOR_ALTS_GRPC_RECORD_PROTOCOL_COMMON_H \
*/

@ -0,0 +1,476 @@
/*
*
* 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/zero_copy_frame_protector/alts_iovec_record_protocol.h"
#include <stdlib.h>
#include <string.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include "src/core/tsi/alts/frame_protector/alts_counter.h"
struct alts_iovec_record_protocol {
alts_counter* ctr;
gsec_aead_crypter* crypter;
size_t tag_length;
bool is_integrity_only;
bool is_protect;
};
/* Copies error message to destination. */
static void maybe_copy_error_msg(const char* src, char** dst) {
if (dst != nullptr && src != nullptr) {
*dst = static_cast<char*>(gpr_malloc(strlen(src) + 1));
memcpy(*dst, src, strlen(src) + 1);
}
}
/* Appends error message to destination. */
static void maybe_append_error_msg(const char* appendix, char** dst) {
if (dst != nullptr && appendix != nullptr) {
int dst_len = static_cast<int>(strlen(*dst));
*dst = static_cast<char*>(realloc(*dst, dst_len + strlen(appendix) + 1));
assert(*dst != nullptr);
memcpy(*dst + dst_len, appendix, strlen(appendix) + 1);
}
}
/* Use little endian to interpret a string of bytes as uint32_t. */
static uint32_t load_32_le(const unsigned char* buffer) {
return (((uint32_t)buffer[3]) << 24) | (((uint32_t)buffer[2]) << 16) |
(((uint32_t)buffer[1]) << 8) | ((uint32_t)buffer[0]);
}
/* Store uint32_t as a string of little endian bytes. */
static void store_32_le(uint32_t value, unsigned char* buffer) {
buffer[3] = (unsigned char)(value >> 24) & 0xFF;
buffer[2] = (unsigned char)(value >> 16) & 0xFF;
buffer[1] = (unsigned char)(value >> 8) & 0xFF;
buffer[0] = (unsigned char)(value)&0xFF;
}
/* Ensures header and tag iovec have sufficient length. */
static grpc_status_code ensure_header_and_tag_length(
const alts_iovec_record_protocol* rp, iovec_t header, iovec_t tag,
char** error_details) {
if (rp == nullptr) {
return GRPC_STATUS_FAILED_PRECONDITION;
}
if (header.iov_base == nullptr) {
maybe_copy_error_msg("Header is nullptr.", error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
if (header.iov_len != alts_iovec_record_protocol_get_header_length()) {
maybe_copy_error_msg("Header length is incorrect.", error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
if (tag.iov_base == nullptr) {
maybe_copy_error_msg("Tag is nullptr.", error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
if (tag.iov_len != rp->tag_length) {
maybe_copy_error_msg("Tag length is incorrect.", error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
return GRPC_STATUS_OK;
}
/* Increments crypter counter and checks overflow. */
static grpc_status_code increment_counter(alts_counter* counter,
char** error_details) {
if (counter == nullptr) {
return GRPC_STATUS_FAILED_PRECONDITION;
}
bool is_overflow = false;
grpc_status_code status =
alts_counter_increment(counter, &is_overflow, error_details);
if (status != GRPC_STATUS_OK) {
return status;
}
if (is_overflow) {
maybe_copy_error_msg("Crypter counter is overflowed.", error_details);
return GRPC_STATUS_INTERNAL;
}
return GRPC_STATUS_OK;
}
/* Given an array of iovec, computes the total length of buffer. */
static size_t get_total_length(const iovec_t* vec, size_t vec_length) {
size_t total_length = 0;
for (size_t i = 0; i < vec_length; ++i) {
total_length += vec[i].iov_len;
}
return total_length;
}
/* Writes frame header given data and tag length. */
static grpc_status_code write_frame_header(size_t data_length,
unsigned char* header,
char** error_details) {
if (header == nullptr) {
maybe_copy_error_msg("Header is nullptr.", error_details);
return GRPC_STATUS_FAILED_PRECONDITION;
}
size_t frame_length = kZeroCopyFrameMessageTypeFieldSize + data_length;
store_32_le(static_cast<uint32_t>(frame_length), header);
store_32_le(kZeroCopyFrameMessageType,
header + kZeroCopyFrameLengthFieldSize);
return GRPC_STATUS_OK;
}
/* Verifies frame header given protected data length. */
static grpc_status_code verify_frame_header(size_t data_length,
unsigned char* header,
char** error_details) {
if (header == nullptr) {
maybe_copy_error_msg("Header is nullptr.", error_details);
return GRPC_STATUS_FAILED_PRECONDITION;
}
size_t frame_length = load_32_le(header);
if (frame_length != kZeroCopyFrameMessageTypeFieldSize + data_length) {
maybe_copy_error_msg("Bad frame length.", error_details);
return GRPC_STATUS_INTERNAL;
}
size_t message_type = load_32_le(header + kZeroCopyFrameLengthFieldSize);
if (message_type != kZeroCopyFrameMessageType) {
maybe_copy_error_msg("Unsupported message type.", error_details);
return GRPC_STATUS_INTERNAL;
}
return GRPC_STATUS_OK;
}
/* --- alts_iovec_record_protocol methods implementation. --- */
size_t alts_iovec_record_protocol_get_header_length() {
return kZeroCopyFrameHeaderSize;
}
size_t alts_iovec_record_protocol_get_tag_length(
const alts_iovec_record_protocol* rp) {
if (rp != nullptr) {
return rp->tag_length;
}
return 0;
}
size_t alts_iovec_record_protocol_max_unprotected_data_size(
const alts_iovec_record_protocol* rp, size_t max_protected_frame_size) {
if (rp == nullptr) {
return 0;
}
size_t overhead_bytes_size =
kZeroCopyFrameMessageTypeFieldSize + rp->tag_length;
if (max_protected_frame_size <= overhead_bytes_size) return 0;
return max_protected_frame_size - overhead_bytes_size;
}
grpc_status_code alts_iovec_record_protocol_integrity_only_protect(
alts_iovec_record_protocol* rp, const iovec_t* unprotected_vec,
size_t unprotected_vec_length, iovec_t header, iovec_t tag,
char** error_details) {
/* Input sanity checks. */
if (rp == nullptr) {
maybe_copy_error_msg("Input iovec_record_protocol is nullptr.",
error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
if (!rp->is_integrity_only) {
maybe_copy_error_msg(
"Integrity-only operations are not allowed for this object.",
error_details);
return GRPC_STATUS_FAILED_PRECONDITION;
}
if (!rp->is_protect) {
maybe_copy_error_msg("Protect operations are not allowed for this object.",
error_details);
return GRPC_STATUS_FAILED_PRECONDITION;
}
grpc_status_code status =
ensure_header_and_tag_length(rp, header, tag, error_details);
if (status != GRPC_STATUS_OK) {
return status;
}
/* Unprotected data should not be zero length. */
size_t data_length =
get_total_length(unprotected_vec, unprotected_vec_length);
/* Sets frame header. */
status = write_frame_header(data_length + rp->tag_length,
static_cast<unsigned char*>(header.iov_base),
error_details);
if (status != GRPC_STATUS_OK) {
return status;
}
/* Computes frame tag by calling AEAD crypter. */
size_t bytes_written = 0;
status = gsec_aead_crypter_encrypt_iovec(
rp->crypter, alts_counter_get_counter(rp->ctr),
alts_counter_get_size(rp->ctr), unprotected_vec, unprotected_vec_length,
/* plaintext_vec = */ nullptr, /* plaintext_vec_length = */ 0, tag,
&bytes_written, error_details);
if (status != GRPC_STATUS_OK) {
return status;
}
if (bytes_written != rp->tag_length) {
maybe_copy_error_msg("Bytes written expects to be the same as tag length.",
error_details);
return GRPC_STATUS_INTERNAL;
}
/* Increments the crypter counter. */
return increment_counter(rp->ctr, error_details);
}
grpc_status_code alts_iovec_record_protocol_integrity_only_unprotect(
alts_iovec_record_protocol* rp, const iovec_t* protected_vec,
size_t protected_vec_length, iovec_t header, iovec_t tag,
char** error_details) {
/* Input sanity checks. */
if (rp == nullptr) {
maybe_copy_error_msg("Input iovec_record_protocol is nullptr.",
error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
if (!rp->is_integrity_only) {
maybe_copy_error_msg(
"Integrity-only operations are not allowed for this object.",
error_details);
return GRPC_STATUS_FAILED_PRECONDITION;
}
if (rp->is_protect) {
maybe_copy_error_msg(
"Unprotect operations are not allowed for this object.", error_details);
return GRPC_STATUS_FAILED_PRECONDITION;
}
grpc_status_code status =
ensure_header_and_tag_length(rp, header, tag, error_details);
if (status != GRPC_STATUS_OK) return status;
/* Protected data should not be zero length. */
size_t data_length = get_total_length(protected_vec, protected_vec_length);
/* Verifies frame header. */
status = verify_frame_header(data_length + rp->tag_length,
static_cast<unsigned char*>(header.iov_base),
error_details);
if (status != GRPC_STATUS_OK) {
return status;
}
/* Verifies frame tag by calling AEAD crypter. */
iovec_t plaintext = {nullptr, 0};
size_t bytes_written = 0;
status = gsec_aead_crypter_decrypt_iovec(
rp->crypter, alts_counter_get_counter(rp->ctr),
alts_counter_get_size(rp->ctr), protected_vec, protected_vec_length, &tag,
1, plaintext, &bytes_written, error_details);
if (status != GRPC_STATUS_OK || bytes_written != 0) {
maybe_append_error_msg(" Frame tag verification failed.", error_details);
return GRPC_STATUS_INTERNAL;
}
/* Increments the crypter counter. */
return increment_counter(rp->ctr, error_details);
}
grpc_status_code alts_iovec_record_protocol_privacy_integrity_protect(
alts_iovec_record_protocol* rp, const iovec_t* unprotected_vec,
size_t unprotected_vec_length, iovec_t protected_frame,
char** error_details) {
/* Input sanity checks. */
if (rp == nullptr) {
maybe_copy_error_msg("Input iovec_record_protocol is nullptr.",
error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
if (rp->is_integrity_only) {
maybe_copy_error_msg(
"Privacy-integrity operations are not allowed for this object.",
error_details);
return GRPC_STATUS_FAILED_PRECONDITION;
}
if (!rp->is_protect) {
maybe_copy_error_msg("Protect operations are not allowed for this object.",
error_details);
return GRPC_STATUS_FAILED_PRECONDITION;
}
/* Unprotected data should not be zero length. */
size_t data_length =
get_total_length(unprotected_vec, unprotected_vec_length);
/* Ensures protected frame iovec has sufficient size. */
if (protected_frame.iov_base == nullptr) {
maybe_copy_error_msg("Protected frame is nullptr.", error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
if (protected_frame.iov_len !=
alts_iovec_record_protocol_get_header_length() + data_length +
rp->tag_length) {
maybe_copy_error_msg("Protected frame size is incorrect.", error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
/* Writer frame header. */
grpc_status_code status = write_frame_header(
data_length + rp->tag_length,
static_cast<unsigned char*>(protected_frame.iov_base), error_details);
if (status != GRPC_STATUS_OK) {
return status;
}
/* Encrypt unprotected data by calling AEAD crypter. */
unsigned char* ciphertext_buffer =
static_cast<unsigned char*>(protected_frame.iov_base) +
alts_iovec_record_protocol_get_header_length();
iovec_t ciphertext = {ciphertext_buffer, data_length + rp->tag_length};
size_t bytes_written = 0;
status = gsec_aead_crypter_encrypt_iovec(
rp->crypter, alts_counter_get_counter(rp->ctr),
alts_counter_get_size(rp->ctr), /* aad_vec = */ nullptr,
/* aad_vec_length = */ 0, unprotected_vec, unprotected_vec_length,
ciphertext, &bytes_written, error_details);
if (status != GRPC_STATUS_OK) {
return status;
}
if (bytes_written != data_length + rp->tag_length) {
maybe_copy_error_msg(
"Bytes written expects to be data length plus tag length.",
error_details);
return GRPC_STATUS_INTERNAL;
}
/* Increments the crypter counter. */
return increment_counter(rp->ctr, error_details);
}
grpc_status_code alts_iovec_record_protocol_privacy_integrity_unprotect(
alts_iovec_record_protocol* rp, iovec_t header,
const iovec_t* protected_vec, size_t protected_vec_length,
iovec_t unprotected_data, char** error_details) {
/* Input sanity checks. */
if (rp == nullptr) {
maybe_copy_error_msg("Input iovec_record_protocol is nullptr.",
error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
if (rp->is_integrity_only) {
maybe_copy_error_msg(
"Privacy-integrity operations are not allowed for this object.",
error_details);
return GRPC_STATUS_FAILED_PRECONDITION;
}
if (rp->is_protect) {
maybe_copy_error_msg(
"Unprotect operations are not allowed for this object.", error_details);
return GRPC_STATUS_FAILED_PRECONDITION;
}
/* Protected data size should be no less than tag size. */
size_t protected_data_length =
get_total_length(protected_vec, protected_vec_length);
if (protected_data_length < rp->tag_length) {
maybe_copy_error_msg(
"Protected data length should be more than the tag length.",
error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
/* Ensures header has sufficient size. */
if (header.iov_base == nullptr) {
maybe_copy_error_msg("Header is nullptr.", error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
if (header.iov_len != alts_iovec_record_protocol_get_header_length()) {
maybe_copy_error_msg("Header length is incorrect.", error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
/* Ensures unprotected data iovec has sufficient size. */
if (unprotected_data.iov_len != protected_data_length - rp->tag_length) {
maybe_copy_error_msg("Unprotected data size is incorrect.", error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
/* Verify frame header. */
grpc_status_code status = verify_frame_header(
protected_data_length, static_cast<unsigned char*>(header.iov_base),
error_details);
if (status != GRPC_STATUS_OK) {
return status;
}
/* Decrypt protected data by calling AEAD crypter. */
size_t bytes_written = 0;
status = gsec_aead_crypter_decrypt_iovec(
rp->crypter, alts_counter_get_counter(rp->ctr),
alts_counter_get_size(rp->ctr), /* aad_vec = */ nullptr,
/* aad_vec_length = */ 0, protected_vec, protected_vec_length,
unprotected_data, &bytes_written, error_details);
if (status != GRPC_STATUS_OK) {
maybe_append_error_msg(" Frame decryption failed.", error_details);
return GRPC_STATUS_INTERNAL;
}
if (bytes_written != protected_data_length - rp->tag_length) {
maybe_copy_error_msg(
"Bytes written expects to be protected data length minus tag length.",
error_details);
return GRPC_STATUS_INTERNAL;
}
/* Increments the crypter counter. */
return increment_counter(rp->ctr, error_details);
}
grpc_status_code alts_iovec_record_protocol_create(
gsec_aead_crypter* crypter, size_t overflow_size, bool is_client,
bool is_integrity_only, bool is_protect, alts_iovec_record_protocol** rp,
char** error_details) {
if (crypter == nullptr || rp == nullptr) {
maybe_copy_error_msg(
"Invalid nullptr arguments to alts_iovec_record_protocol create.",
error_details);
return GRPC_STATUS_INVALID_ARGUMENT;
}
alts_iovec_record_protocol* impl = static_cast<alts_iovec_record_protocol*>(
gpr_zalloc(sizeof(alts_iovec_record_protocol)));
/* Gets counter length. */
size_t counter_length = 0;
grpc_status_code status =
gsec_aead_crypter_nonce_length(crypter, &counter_length, error_details);
if (status != GRPC_STATUS_OK) {
goto cleanup;
}
/* Creates counters. */
status =
alts_counter_create(is_protect ? !is_client : is_client, counter_length,
overflow_size, &impl->ctr, error_details);
if (status != GRPC_STATUS_OK) {
goto cleanup;
}
/* Gets tag length. */
status =
gsec_aead_crypter_tag_length(crypter, &impl->tag_length, error_details);
if (status != GRPC_STATUS_OK) {
goto cleanup;
}
impl->crypter = crypter;
impl->is_integrity_only = is_integrity_only;
impl->is_protect = is_protect;
*rp = impl;
return GRPC_STATUS_OK;
cleanup:
alts_counter_destroy(impl->ctr);
gpr_free(impl);
return GRPC_STATUS_FAILED_PRECONDITION;
}
void alts_iovec_record_protocol_destroy(alts_iovec_record_protocol* rp) {
if (rp != nullptr) {
alts_counter_destroy(rp->ctr);
gsec_aead_crypter_destroy(rp->crypter);
gpr_free(rp);
}
}

@ -0,0 +1,199 @@
/*
*
* 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.
*
*/
#ifndef GRPC_CORE_TSI_ALTS_ZERO_COPY_FRAME_PROTECTOR_ALTS_IOVEC_RECORD_PROTOCOL_H
#define GRPC_CORE_TSI_ALTS_ZERO_COPY_FRAME_PROTECTOR_ALTS_IOVEC_RECORD_PROTOCOL_H
#include <grpc/support/port_platform.h>
#include <stdbool.h>
#include "src/core/tsi/alts/crypt/gsec.h"
constexpr size_t kZeroCopyFrameMessageType = 0x06;
constexpr size_t kZeroCopyFrameLengthFieldSize = 4;
constexpr size_t kZeroCopyFrameMessageTypeFieldSize = 4;
constexpr size_t kZeroCopyFrameHeaderSize =
kZeroCopyFrameLengthFieldSize + kZeroCopyFrameMessageTypeFieldSize;
// Limit k on number of frames such that at most 2^(8 * k) frames can be sent.
constexpr size_t kAltsRecordProtocolRekeyFrameLimit = 8;
constexpr size_t kAltsRecordProtocolFrameLimit = 5;
/* An implementation of alts record protocol. The API is thread-compatible. */
typedef struct iovec iovec_t;
typedef struct alts_iovec_record_protocol alts_iovec_record_protocol;
/**
* This method gets the length of record protocol frame header.
*/
size_t alts_iovec_record_protocol_get_header_length();
/**
* This method gets the length of record protocol frame tag.
*
* - rp: an alts_iovec_record_protocol instance.
*
* On success, the method returns the length of record protocol frame tag.
* Otherwise, it returns zero.
*/
size_t alts_iovec_record_protocol_get_tag_length(
const alts_iovec_record_protocol* rp);
/**
* This method returns maximum allowed unprotected data size, given maximum
* protected frame size.
*
* - rp: an alts_iovec_record_protocol instance.
* - max_protected_frame_size: maximum protected frame size.
*
* On success, the method returns the maximum allowed unprotected data size.
* Otherwise, it returns zero.
*/
size_t alts_iovec_record_protocol_max_unprotected_data_size(
const alts_iovec_record_protocol* rp, size_t max_protected_frame_size);
/**
* This method performs integrity-only protect operation on a
* alts_iovec_record_protocol instance, i.e., compute frame header and tag. The
* caller needs to allocate the memory for header and tag prior to calling this
* method.
*
* - rp: an alts_iovec_record_protocol instance.
* - unprotected_vec: an iovec array containing unprotected data.
* - unprotected_vec_length: the array length of unprotected_vec.
* - header: an iovec containing the output frame header.
* - tag: an iovec containing the output frame tag.
* - error_details: a buffer containing an error message if the method does not
* function correctly. It is OK to pass nullptr into error_details.
*
* On success, the method returns GRPC_STATUS_OK. Otherwise, it returns an
* error status code along with its details specified in error_details (if
* error_details is not nullptr).
*/
grpc_status_code alts_iovec_record_protocol_integrity_only_protect(
alts_iovec_record_protocol* rp, const iovec_t* unprotected_vec,
size_t unprotected_vec_length, iovec_t header, iovec_t tag,
char** error_details);
/**
* This method performs integrity-only unprotect operation on a
* alts_iovec_record_protocol instance, i.e., verify frame header and tag.
*
* - rp: an alts_iovec_record_protocol instance.
* - protected_vec: an iovec array containing protected data.
* - protected_vec_length: the array length of protected_vec.
* - header: an iovec containing the frame header.
* - tag: an iovec containing the frame tag.
* - error_details: a buffer containing an error message if the method does not
* function correctly. It is OK to pass nullptr into error_details.
*
* On success, the method returns GRPC_STATUS_OK. Otherwise, it returns an
* error status code along with its details specified in error_details (if
* error_details is not nullptr).
*/
grpc_status_code alts_iovec_record_protocol_integrity_only_unprotect(
alts_iovec_record_protocol* rp, const iovec_t* protected_vec,
size_t protected_vec_length, iovec_t header, iovec_t tag,
char** error_details);
/**
* This method performs privacy-integrity protect operation on a
* alts_iovec_record_protocol instance, i.e., compute a protected frame. The
* caller needs to allocate the memory for the protected frame prior to calling
* this method.
*
* - rp: an alts_iovec_record_protocol instance.
* - unprotected_vec: an iovec array containing unprotected data.
* - unprotected_vec_length: the array length of unprotected_vec.
* - protected_frame: an iovec containing the output protected frame.
* - error_details: a buffer containing an error message if the method does not
* function correctly. It is OK to pass nullptr into error_details.
*
* On success, the method returns GRPC_STATUS_OK. Otherwise, it returns an
* error status code along with its details specified in error_details (if
* error_details is not nullptr).
*/
grpc_status_code alts_iovec_record_protocol_privacy_integrity_protect(
alts_iovec_record_protocol* rp, const iovec_t* unprotected_vec,
size_t unprotected_vec_length, iovec_t protected_frame,
char** error_details);
/**
* This method performs privacy-integrity unprotect operation on a
* alts_iovec_record_protocol instance given a full protected frame, i.e.,
* compute the unprotected data. The caller needs to allocated the memory for
* the unprotected data prior to calling this method.
*
* - rp: an alts_iovec_record_protocol instance.
* - header: an iovec containing the frame header.
* - protected_vec: an iovec array containing protected data including the tag.
* - protected_vec_length: the array length of protected_vec.
* - unprotected_data: an iovec containing the output unprotected data.
* - error_details: a buffer containing an error message if the method does not
* function correctly. It is OK to pass nullptr into error_details.
*
* On success, the method returns GRPC_STATUS_OK. Otherwise, it returns an
* error status code along with its details specified in error_details (if
* error_details is not nullptr).
*/
grpc_status_code alts_iovec_record_protocol_privacy_integrity_unprotect(
alts_iovec_record_protocol* rp, iovec_t header,
const iovec_t* protected_vec, size_t protected_vec_length,
iovec_t unprotected_data, char** error_details);
/**
* This method creates an alts_iovec_record_protocol instance, given a
* gsec_aead_crypter instance, a flag indicating if the created instance will be
* used at the client or server side, and a flag indicating if the created
* instance will be used for integrity-only mode or privacy-integrity mode. The
* ownership of gsec_aead_crypter instance is transferred to this new object.
*
* - crypter: a gsec_aead_crypter instance used to perform AEAD decryption.
* - overflow_size: overflow size of counter in bytes.
* - is_client: a flag indicating if the alts_iovec_record_protocol instance
* will be used at the client or server side.
* - is_integrity_only: a flag indicating if the alts_iovec_record_protocol
* instance will be used for integrity-only or privacy-integrity mode.
* - is_protect: a flag indicating if the alts_grpc_record_protocol instance
* will be used for protect or unprotect.
* - rp: an alts_iovec_record_protocol instance to be returned from
* the method.
* - error_details: a buffer containing an error message if the method does not
* function correctly. It is OK to pass nullptr into error_details.
*
* On success, the method returns GRPC_STATUS_OK. Otherwise, it returns an
* error status code along with its details specified in error_details (if
* error_details is not nullptr).
*/
grpc_status_code alts_iovec_record_protocol_create(
gsec_aead_crypter* crypter, size_t overflow_size, bool is_client,
bool is_integrity_only, bool is_protect, alts_iovec_record_protocol** rp,
char** error_details);
/**
* This method destroys an alts_iovec_record_protocol instance by de-allocating
* all of its occupied memory. A gsec_aead_crypter instance passed in at
* gsec_alts_crypter instance creation time will be destroyed in this method.
*/
void alts_iovec_record_protocol_destroy(alts_iovec_record_protocol* rp);
#endif /* GRPC_CORE_TSI_ALTS_ZERO_COPY_FRAME_PROTECTOR_ALTS_IOVEC_RECORD_PROTOCOL_H \
*/

@ -0,0 +1,295 @@
/*
*
* 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/zero_copy_frame_protector/alts_zero_copy_grpc_protector.h"
#include <string.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include "src/core/lib/gpr/useful.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/tsi/alts/crypt/gsec.h"
#include "src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.h"
#include "src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.h"
#include "src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol.h"
#include "src/core/tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol.h"
#include "src/core/tsi/transport_security_grpc.h"
constexpr size_t kMinFrameLength = 1024;
constexpr size_t kDefaultFrameLength = 16 * 1024;
constexpr size_t kMaxFrameLength = 1024 * 1024;
/**
* Main struct for alts_zero_copy_grpc_protector.
* We choose to have two alts_grpc_record_protocol objects and two sets of slice
* buffers: one for protect and the other for unprotect, so that protect and
* unprotect can be executed in parallel. Implementations of this object must be
* thread compatible.
*/
typedef struct alts_zero_copy_grpc_protector {
tsi_zero_copy_grpc_protector base;
alts_grpc_record_protocol* record_protocol;
alts_grpc_record_protocol* unrecord_protocol;
size_t max_protected_frame_size;
size_t max_unprotected_data_size;
grpc_slice_buffer unprotected_staging_sb;
grpc_slice_buffer protected_sb;
grpc_slice_buffer protected_staging_sb;
uint32_t parsed_frame_size;
} alts_zero_copy_grpc_protector;
/**
* Given a slice buffer, parses the first 4 bytes little-endian unsigned frame
* size and returns the total frame size including the frame field. Caller
* needs to make sure the input slice buffer has at least 4 bytes. Returns true
* on success and false on failure.
*/
static bool read_frame_size(const grpc_slice_buffer* sb,
uint32_t* total_frame_size) {
if (sb == nullptr || sb->length < kZeroCopyFrameLengthFieldSize) {
return false;
}
uint8_t frame_size_buffer[kZeroCopyFrameLengthFieldSize];
uint8_t* buf = frame_size_buffer;
/* Copies the first 4 bytes to a temporary buffer. */
size_t remaining = kZeroCopyFrameLengthFieldSize;
for (size_t i = 0; i < sb->count; i++) {
size_t slice_length = GRPC_SLICE_LENGTH(sb->slices[i]);
if (remaining <= slice_length) {
memcpy(buf, GRPC_SLICE_START_PTR(sb->slices[i]), remaining);
remaining = 0;
break;
} else {
memcpy(buf, GRPC_SLICE_START_PTR(sb->slices[i]), slice_length);
buf += slice_length;
remaining -= slice_length;
}
}
GPR_ASSERT(remaining == 0);
/* Gets little-endian frame size. */
uint32_t frame_size = (((uint32_t)frame_size_buffer[3]) << 24) |
(((uint32_t)frame_size_buffer[2]) << 16) |
(((uint32_t)frame_size_buffer[1]) << 8) |
((uint32_t)frame_size_buffer[0]);
if (frame_size > kMaxFrameLength) {
gpr_log(GPR_ERROR, "Frame size is larger than maximum frame size");
return false;
}
/* Returns frame size including frame length field. */
*total_frame_size =
static_cast<uint32_t>(frame_size + kZeroCopyFrameLengthFieldSize);
return true;
}
/**
* Creates an alts_grpc_record_protocol object, given key, key size, and flags
* to indicate whether the record_protocol object uses the rekeying AEAD,
* whether the object is for client or server, whether the object is for
* integrity-only or privacy-integrity mode, and whether the object is is used
* for protect or unprotect.
*/
static tsi_result create_alts_grpc_record_protocol(
const uint8_t* key, size_t key_size, bool is_rekey, bool is_client,
bool is_integrity_only, bool is_protect,
alts_grpc_record_protocol** record_protocol) {
if (key == nullptr || record_protocol == nullptr) {
return TSI_INVALID_ARGUMENT;
}
grpc_status_code status;
gsec_aead_crypter* crypter = nullptr;
char* error_details = nullptr;
status = gsec_aes_gcm_aead_crypter_create(key, key_size, kAesGcmNonceLength,
kAesGcmTagLength, is_rekey,
&crypter, &error_details);
if (status != GRPC_STATUS_OK) {
gpr_log(GPR_ERROR, "Failed to create AEAD crypter, %s", error_details);
gpr_free(error_details);
return TSI_INTERNAL_ERROR;
}
size_t overflow_limit = is_rekey ? kAltsRecordProtocolRekeyFrameLimit
: kAltsRecordProtocolFrameLimit;
/* Creates alts_grpc_record_protocol with AEAD crypter ownership transferred.
*/
tsi_result result =
is_integrity_only
? alts_grpc_integrity_only_record_protocol_create(
crypter, overflow_limit, is_client, is_protect, record_protocol)
: alts_grpc_privacy_integrity_record_protocol_create(
crypter, overflow_limit, is_client, is_protect,
record_protocol);
if (result != TSI_OK) {
gsec_aead_crypter_destroy(crypter);
return result;
}
return TSI_OK;
}
/* --- tsi_zero_copy_grpc_protector methods implementation. --- */
static tsi_result alts_zero_copy_grpc_protector_protect(
tsi_zero_copy_grpc_protector* self, grpc_slice_buffer* unprotected_slices,
grpc_slice_buffer* protected_slices) {
if (self == nullptr || unprotected_slices == nullptr ||
protected_slices == nullptr) {
gpr_log(GPR_ERROR, "Invalid nullptr arguments to zero-copy grpc protect.");
return TSI_INVALID_ARGUMENT;
}
alts_zero_copy_grpc_protector* protector =
reinterpret_cast<alts_zero_copy_grpc_protector*>(self);
/* Calls alts_grpc_record_protocol protect repeatly. */
while (unprotected_slices->length > protector->max_unprotected_data_size) {
grpc_slice_buffer_move_first(unprotected_slices,
protector->max_unprotected_data_size,
&protector->unprotected_staging_sb);
tsi_result status = alts_grpc_record_protocol_protect(
protector->record_protocol, &protector->unprotected_staging_sb,
protected_slices);
if (status != TSI_OK) {
return status;
}
}
return alts_grpc_record_protocol_protect(
protector->record_protocol, unprotected_slices, protected_slices);
}
static tsi_result alts_zero_copy_grpc_protector_unprotect(
tsi_zero_copy_grpc_protector* self, grpc_slice_buffer* protected_slices,
grpc_slice_buffer* unprotected_slices) {
if (self == nullptr || unprotected_slices == nullptr ||
protected_slices == nullptr) {
gpr_log(GPR_ERROR,
"Invalid nullptr arguments to zero-copy grpc unprotect.");
return TSI_INVALID_ARGUMENT;
}
alts_zero_copy_grpc_protector* protector =
reinterpret_cast<alts_zero_copy_grpc_protector*>(self);
grpc_slice_buffer_move_into(protected_slices, &protector->protected_sb);
/* Keep unprotecting each frame if possible. */
while (protector->protected_sb.length >= kZeroCopyFrameLengthFieldSize) {
if (protector->parsed_frame_size == 0) {
/* We have not parsed frame size yet. Parses frame size. */
if (!read_frame_size(&protector->protected_sb,
&protector->parsed_frame_size)) {
grpc_slice_buffer_reset_and_unref_internal(&protector->protected_sb);
return TSI_DATA_CORRUPTED;
}
}
if (protector->protected_sb.length < protector->parsed_frame_size) break;
/* At this point, protected_sb contains at least one frame of data. */
tsi_result status;
if (protector->protected_sb.length == protector->parsed_frame_size) {
status = alts_grpc_record_protocol_unprotect(protector->unrecord_protocol,
&protector->protected_sb,
unprotected_slices);
} else {
grpc_slice_buffer_move_first(&protector->protected_sb,
protector->parsed_frame_size,
&protector->protected_staging_sb);
status = alts_grpc_record_protocol_unprotect(
protector->unrecord_protocol, &protector->protected_staging_sb,
unprotected_slices);
}
protector->parsed_frame_size = 0;
if (status != TSI_OK) {
grpc_slice_buffer_reset_and_unref_internal(&protector->protected_sb);
return status;
}
}
return TSI_OK;
}
static void alts_zero_copy_grpc_protector_destroy(
tsi_zero_copy_grpc_protector* self) {
if (self == nullptr) {
return;
}
alts_zero_copy_grpc_protector* protector =
reinterpret_cast<alts_zero_copy_grpc_protector*>(self);
alts_grpc_record_protocol_destroy(protector->record_protocol);
alts_grpc_record_protocol_destroy(protector->unrecord_protocol);
grpc_slice_buffer_destroy_internal(&protector->unprotected_staging_sb);
grpc_slice_buffer_destroy_internal(&protector->protected_sb);
grpc_slice_buffer_destroy_internal(&protector->protected_staging_sb);
gpr_free(protector);
}
static const tsi_zero_copy_grpc_protector_vtable
alts_zero_copy_grpc_protector_vtable = {
alts_zero_copy_grpc_protector_protect,
alts_zero_copy_grpc_protector_unprotect,
alts_zero_copy_grpc_protector_destroy};
tsi_result alts_zero_copy_grpc_protector_create(
const uint8_t* key, size_t key_size, bool is_rekey, bool is_client,
bool is_integrity_only, size_t* max_protected_frame_size,
tsi_zero_copy_grpc_protector** protector) {
if (grpc_core::ExecCtx::Get() == nullptr || key == nullptr ||
protector == nullptr) {
gpr_log(
GPR_ERROR,
"Invalid nullptr arguments to alts_zero_copy_grpc_protector create.");
return TSI_INVALID_ARGUMENT;
}
/* Creates alts_zero_copy_protector. */
alts_zero_copy_grpc_protector* impl =
static_cast<alts_zero_copy_grpc_protector*>(
gpr_zalloc(sizeof(alts_zero_copy_grpc_protector)));
/* Creates alts_grpc_record_protocol objects. */
tsi_result status = create_alts_grpc_record_protocol(
key, key_size, is_rekey, is_client, is_integrity_only,
/*is_protect=*/true, &impl->record_protocol);
if (status == TSI_OK) {
status = create_alts_grpc_record_protocol(
key, key_size, is_rekey, is_client, is_integrity_only,
/*is_protect=*/false, &impl->unrecord_protocol);
if (status == TSI_OK) {
/* Sets maximum frame size. */
size_t max_protected_frame_size_to_set = kDefaultFrameLength;
if (max_protected_frame_size != nullptr) {
*max_protected_frame_size =
GPR_MIN(*max_protected_frame_size, kMaxFrameLength);
*max_protected_frame_size =
GPR_MAX(*max_protected_frame_size, kMinFrameLength);
max_protected_frame_size_to_set = *max_protected_frame_size;
}
impl->max_protected_frame_size = max_protected_frame_size_to_set;
impl->max_unprotected_data_size =
alts_grpc_record_protocol_max_unprotected_data_size(
impl->record_protocol, max_protected_frame_size_to_set);
GPR_ASSERT(impl->max_unprotected_data_size > 0);
/* Allocates internal slice buffers. */
grpc_slice_buffer_init(&impl->unprotected_staging_sb);
grpc_slice_buffer_init(&impl->protected_sb);
grpc_slice_buffer_init(&impl->protected_staging_sb);
impl->parsed_frame_size = 0;
impl->base.vtable = &alts_zero_copy_grpc_protector_vtable;
*protector = &impl->base;
return TSI_OK;
}
}
/* Cleanup if create failed. */
alts_grpc_record_protocol_destroy(impl->record_protocol);
alts_grpc_record_protocol_destroy(impl->unrecord_protocol);
gpr_free(impl);
return TSI_INTERNAL_ERROR;
}

@ -0,0 +1,52 @@
/*
*
* 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.
*
*/
#ifndef GRPC_CORE_TSI_ALTS_ZERO_COPY_FRAME_PROTECTOR_ALTS_ZERO_COPY_GRPC_PROTECTOR_H
#define GRPC_CORE_TSI_ALTS_ZERO_COPY_FRAME_PROTECTOR_ALTS_ZERO_COPY_GRPC_PROTECTOR_H
#include <grpc/support/port_platform.h>
#include <stdbool.h>
#include "src/core/tsi/transport_security_grpc.h"
/**
* This method creates an ALTS zero-copy grpc protector.
*
* - key: a symmetric key used to seal/unseal frames.
* - key_size: the size of symmetric key.
* - is_rekey: use rekeying AEAD crypter.
* - is_client: a flag indicating if the protector will be used at client or
* server side.
* - is_integrity_only: a flag indicating if the protector instance will be
* used for integrity-only or privacy-integrity mode.
* - max_protected_frame_size: an in/out parameter indicating max frame size
* to be used by the protector. If it is nullptr, the default frame size will
* be used. Otherwise, the provided frame size will be adjusted (if not
* falling into a valid frame range) and used.
* - protector: a pointer to the zero-copy protector returned from the method.
*
* This method returns TSI_OK on success or a specific error code otherwise.
*/
tsi_result alts_zero_copy_grpc_protector_create(
const uint8_t* key, size_t key_size, bool is_rekey, bool is_client,
bool is_integrity_only, size_t* max_protected_frame_size,
tsi_zero_copy_grpc_protector** protector);
#endif /* GRPC_CORE_TSI_ALTS_ZERO_COPY_FRAME_PROTECTOR_ALTS_ZERO_COPY_GRPC_PROTECTOR_H \
*/

@ -168,7 +168,7 @@ std::shared_ptr<CallCredentials> CompositeCallCredentials(
void MetadataCredentialsPluginWrapper::Destroy(void* wrapper) {
if (wrapper == nullptr) return;
MetadataCredentialsPluginWrapper* w =
reinterpret_cast<MetadataCredentialsPluginWrapper*>(wrapper);
static_cast<MetadataCredentialsPluginWrapper*>(wrapper);
delete w;
}
@ -180,7 +180,7 @@ int MetadataCredentialsPluginWrapper::GetMetadata(
const char** error_details) {
GPR_ASSERT(wrapper);
MetadataCredentialsPluginWrapper* w =
reinterpret_cast<MetadataCredentialsPluginWrapper*>(wrapper);
static_cast<MetadataCredentialsPluginWrapper*>(wrapper);
if (!w->plugin_) {
*num_creds_md = 0;
*status = GRPC_STATUS_OK;

@ -283,7 +283,7 @@ class ChannelFilter final {
static void DestroyChannelElement(grpc_channel_element* elem) {
ChannelDataType* channel_data =
reinterpret_cast<ChannelDataType*>(elem->channel_data);
static_cast<ChannelDataType*>(elem->channel_data);
channel_data->Destroy(elem);
channel_data->~ChannelDataType();
}
@ -291,7 +291,7 @@ class ChannelFilter final {
static void StartTransportOp(grpc_channel_element* elem,
grpc_transport_op* op) {
ChannelDataType* channel_data =
reinterpret_cast<ChannelDataType*>(elem->channel_data);
static_cast<ChannelDataType*>(elem->channel_data);
TransportOp op_wrapper(op);
channel_data->StartTransportOp(elem, &op_wrapper);
}
@ -299,7 +299,7 @@ class ChannelFilter final {
static void GetChannelInfo(grpc_channel_element* elem,
const grpc_channel_info* channel_info) {
ChannelDataType* channel_data =
reinterpret_cast<ChannelDataType*>(elem->channel_data);
static_cast<ChannelDataType*>(elem->channel_data);
channel_data->GetInfo(elem, channel_info);
}
@ -315,21 +315,21 @@ class ChannelFilter final {
static void DestroyCallElement(grpc_call_element* elem,
const grpc_call_final_info* final_info,
grpc_closure* then_call_closure) {
CallDataType* call_data = reinterpret_cast<CallDataType*>(elem->call_data);
CallDataType* call_data = static_cast<CallDataType*>(elem->call_data);
call_data->Destroy(elem, final_info, then_call_closure);
call_data->~CallDataType();
}
static void StartTransportStreamOpBatch(grpc_call_element* elem,
grpc_transport_stream_op_batch* op) {
CallDataType* call_data = reinterpret_cast<CallDataType*>(elem->call_data);
CallDataType* call_data = static_cast<CallDataType*>(elem->call_data);
TransportStreamOpBatch op_wrapper(op);
call_data->StartTransportStreamOpBatch(elem, &op_wrapper);
}
static void SetPollsetOrPollsetSet(grpc_call_element* elem,
grpc_polling_entity* pollent) {
CallDataType* call_data = reinterpret_cast<CallDataType*>(elem->call_data);
CallDataType* call_data = static_cast<CallDataType*>(elem->call_data);
call_data->SetPollsetOrPollsetSet(elem, pollent);
}
};

@ -28,10 +28,9 @@ namespace grpc {
DynamicThreadPool::DynamicThread::DynamicThread(DynamicThreadPool* pool)
: pool_(pool),
thd_("dynamic thread pool thread",
thd_("grpcpp_dynamic_pool",
[](void* th) {
reinterpret_cast<DynamicThreadPool::DynamicThread*>(th)
->ThreadFunc();
static_cast<DynamicThreadPool::DynamicThread*>(th)->ThreadFunc();
},
this) {
thd_.Start();

@ -29,14 +29,14 @@
namespace grpc {
void AuthMetadataProcessorAyncWrapper::Destroy(void* wrapper) {
auto* w = reinterpret_cast<AuthMetadataProcessorAyncWrapper*>(wrapper);
auto* w = static_cast<AuthMetadataProcessorAyncWrapper*>(wrapper);
delete w;
}
void AuthMetadataProcessorAyncWrapper::Process(
void* wrapper, grpc_auth_context* context, const grpc_metadata* md,
size_t num_md, grpc_process_auth_metadata_done_cb cb, void* user_data) {
auto* w = reinterpret_cast<AuthMetadataProcessorAyncWrapper*>(wrapper);
auto* w = static_cast<AuthMetadataProcessorAyncWrapper*>(wrapper);
if (!w->processor_) {
// Early exit.
cb(user_data, nullptr, 0, nullptr, 0, GRPC_STATUS_OK, nullptr);

@ -32,10 +32,8 @@ ThreadManager::WorkerThread::WorkerThread(ThreadManager* thd_mgr)
// Make thread creation exclusive with respect to its join happening in
// ~WorkerThread().
thd_ = grpc_core::Thread(
"sync server thread",
[](void* th) {
reinterpret_cast<ThreadManager::WorkerThread*>(th)->Run();
},
"grpcpp_sync_server",
[](void* th) { static_cast<ThreadManager::WorkerThread*>(th)->Run(); },
this);
thd_.Start();
}

@ -32,15 +32,15 @@ Slice::Slice(grpc_slice slice, StealRef) : slice_(slice) {}
Slice::Slice(size_t len) : slice_(grpc_slice_malloc(len)) {}
Slice::Slice(const void* buf, size_t len)
: slice_(grpc_slice_from_copied_buffer(reinterpret_cast<const char*>(buf),
len)) {}
: slice_(
grpc_slice_from_copied_buffer(static_cast<const char*>(buf), len)) {}
Slice::Slice(const grpc::string& str)
: slice_(grpc_slice_from_copied_buffer(str.c_str(), str.length())) {}
Slice::Slice(const void* buf, size_t len, StaticSlice)
: slice_(grpc_slice_from_static_buffer(reinterpret_cast<const char*>(buf),
len)) {}
: slice_(
grpc_slice_from_static_buffer(static_cast<const char*>(buf), len)) {}
Slice::Slice(const Slice& other) : slice_(grpc_slice_ref(other.slice_)) {}

@ -223,6 +223,7 @@ CORE_SOURCE_FILES = [
'src/core/ext/filters/http/server/http_server_filter.cc',
'src/core/lib/http/httpcli_security_connector.cc',
'src/core/lib/security/context/security_context.cc',
'src/core/lib/security/credentials/alts/alts_credentials.cc',
'src/core/lib/security/credentials/composite/composite_credentials.cc',
'src/core/lib/security/credentials/credentials.cc',
'src/core/lib/security/credentials/credentials_metadata.cc',
@ -236,6 +237,7 @@ CORE_SOURCE_FILES = [
'src/core/lib/security/credentials/oauth2/oauth2_credentials.cc',
'src/core/lib/security/credentials/plugin/plugin_credentials.cc',
'src/core/lib/security/credentials/ssl/ssl_credentials.cc',
'src/core/lib/security/security_connector/alts_security_connector.cc',
'src/core/lib/security/security_connector/security_connector.cc',
'src/core/lib/security/transport/client_auth_filter.cc',
'src/core/lib/security/transport/secure_endpoint.cc',
@ -245,14 +247,45 @@ CORE_SOURCE_FILES = [
'src/core/lib/security/transport/tsi_error.cc',
'src/core/lib/security/util/json_util.cc',
'src/core/lib/surface/init_secure.cc',
'src/core/tsi/alts_transport_security.cc',
'src/core/tsi/fake_transport_security.cc',
'src/core/tsi/ssl_transport_security.cc',
'src/core/tsi/transport_security_grpc.cc',
'src/core/tsi/alts/crypt/aes_gcm.cc',
'src/core/tsi/alts/crypt/gsec.cc',
'src/core/tsi/alts/frame_protector/alts_counter.cc',
'src/core/tsi/alts/frame_protector/alts_crypter.cc',
'src/core/tsi/alts/frame_protector/alts_frame_protector.cc',
'src/core/tsi/alts/frame_protector/alts_record_protocol_crypter_common.cc',
'src/core/tsi/alts/frame_protector/alts_seal_privacy_integrity_crypter.cc',
'src/core/tsi/alts/frame_protector/alts_unseal_privacy_integrity_crypter.cc',
'src/core/tsi/alts/frame_protector/frame_handler.cc',
'src/core/tsi/alts/handshaker/alts_handshaker_client.cc',
'src/core/tsi/alts/handshaker/alts_tsi_event.cc',
'src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc',
'src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.cc',
'src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.cc',
'src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_common.cc',
'src/core/tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol.cc',
'src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc',
'src/core/lib/security/credentials/alts/check_gcp_environment.cc',
'src/core/lib/security/credentials/alts/check_gcp_environment_linux.cc',
'src/core/lib/security/credentials/alts/check_gcp_environment_no_op.cc',
'src/core/lib/security/credentials/alts/check_gcp_environment_windows.cc',
'src/core/lib/security/credentials/alts/grpc_alts_credentials_client_options.cc',
'src/core/lib/security/credentials/alts/grpc_alts_credentials_options.cc',
'src/core/lib/security/credentials/alts/grpc_alts_credentials_server_options.cc',
'src/core/tsi/alts/handshaker/alts_handshaker_service_api.cc',
'src/core/tsi/alts/handshaker/alts_handshaker_service_api_util.cc',
'src/core/tsi/alts/handshaker/alts_tsi_utils.cc',
'src/core/tsi/alts/handshaker/transport_security_common_api.cc',
'src/core/tsi/alts/handshaker/altscontext.pb.c',
'src/core/tsi/alts/handshaker/handshaker.pb.c',
'src/core/tsi/alts/handshaker/transport_security_common.pb.c',
'third_party/nanopb/pb_common.c',
'third_party/nanopb/pb_decode.c',
'third_party/nanopb/pb_encode.c',
'src/core/tsi/transport_security.cc',
'src/core/tsi/transport_security_adapter.cc',
'src/core/ext/transport/chttp2/server/chttp2_server.cc',
'src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc',
'src/core/ext/transport/chttp2/client/insecure/channel_create.cc',
'src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc',
'src/core/ext/transport/chttp2/client/chttp2_connector.cc',
'src/core/ext/filters/client_channel/backup_poller.cc',
'src/core/ext/filters/client_channel/channel_connectivity.cc',
'src/core/ext/filters/client_channel/client_channel.cc',
@ -275,11 +308,14 @@ CORE_SOURCE_FILES = [
'src/core/ext/filters/client_channel/subchannel_index.cc',
'src/core/ext/filters/client_channel/uri_parser.cc',
'src/core/ext/filters/deadline/deadline_filter.cc',
'src/core/ext/transport/chttp2/client/chttp2_connector.cc',
'src/core/tsi/alts_transport_security.cc',
'src/core/tsi/fake_transport_security.cc',
'src/core/tsi/ssl_transport_security.cc',
'src/core/tsi/transport_security_grpc.cc',
'src/core/ext/transport/chttp2/server/chttp2_server.cc',
'src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc',
'src/core/ext/transport/chttp2/server/insecure/server_chttp2.cc',
'src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc',
'src/core/ext/transport/chttp2/client/insecure/channel_create.cc',
'src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc',
'src/core/ext/transport/inproc/inproc_plugin.cc',
'src/core/ext/transport/inproc/inproc_transport.cc',
'src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc',
@ -288,9 +324,6 @@ CORE_SOURCE_FILES = [
'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc',
'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc',
'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c',
'third_party/nanopb/pb_common.c',
'third_party/nanopb/pb_decode.c',
'third_party/nanopb/pb_encode.c',
'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc',
'src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc',
'src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc',

@ -138,6 +138,8 @@
## Some libraries are shared even with BUILD_SHARED_LIBRARIES=OFF
set(CMAKE_POSITION_INDEPENDENT_CODE TRUE)
add_definitions(-DPB_FIELD_16BIT)
if (MSVC)
include(cmake/msvc_static_runtime.cmake)

@ -221,6 +221,8 @@
% endif
% endfor
DEFINES += PB_FIELD_16BIT
CPPFLAGS += $(CPPFLAGS_$(CONFIG))
CFLAGS += $(CFLAGS_$(CONFIG))
CXXFLAGS += $(CXXFLAGS_$(CONFIG))

@ -144,7 +144,7 @@
}
s.default_subspecs = 'Interface', 'Implementation'
s.compiler_flags = '-DGRPC_ARES=0'
s.compiler_flags = '-DGRPC_ARES=0', '-DPB_FIELD_16BIT'
s.libraries = 'c++'
# Like many other C libraries, gRPC-Core has its public headers under `include/<libname>/` and its

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save