grpc 1.74.1 → 1.75.0.pre1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (368) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +83 -41
  3. data/include/grpc/credentials.h +7 -1
  4. data/src/core/call/client_call.cc +4 -4
  5. data/src/core/call/filter_fusion.h +1230 -0
  6. data/src/core/call/metadata.cc +22 -0
  7. data/src/core/call/metadata.h +24 -2
  8. data/src/core/channelz/channelz.cc +10 -17
  9. data/src/core/channelz/channelz.h +58 -19
  10. data/src/core/channelz/channelz_registry.cc +0 -162
  11. data/src/core/channelz/channelz_registry.h +14 -7
  12. data/src/core/channelz/property_list.cc +19 -23
  13. data/src/core/channelz/property_list.h +3 -1
  14. data/src/core/channelz/v2tov1/convert.cc +683 -0
  15. data/src/core/channelz/v2tov1/convert.h +58 -0
  16. data/src/core/channelz/v2tov1/legacy_api.cc +425 -0
  17. data/src/core/channelz/v2tov1/legacy_api.h +32 -0
  18. data/src/core/channelz/v2tov1/property_list.cc +118 -0
  19. data/src/core/channelz/v2tov1/property_list.h +52 -0
  20. data/src/core/client_channel/client_channel_filter.cc +5 -4
  21. data/src/core/client_channel/client_channel_filter.h +2 -2
  22. data/src/core/client_channel/client_channel_internal.h +2 -1
  23. data/src/core/client_channel/load_balanced_call_destination.cc +6 -5
  24. data/src/core/client_channel/subchannel.cc +14 -6
  25. data/src/core/client_channel/subchannel.h +2 -0
  26. data/src/core/config/core_configuration.cc +3 -1
  27. data/src/core/config/core_configuration.h +12 -0
  28. data/src/core/credentials/transport/alts/alts_credentials.cc +5 -0
  29. data/src/core/credentials/transport/alts/check_gcp_environment_windows.cc +2 -0
  30. data/src/core/credentials/transport/channel_creds_registry_init.cc +3 -1
  31. data/src/core/credentials/transport/ssl/ssl_credentials.cc +1 -1
  32. data/src/core/credentials/transport/ssl/ssl_security_connector.cc +8 -3
  33. data/src/core/credentials/transport/tls/grpc_tls_certificate_distributor.cc +29 -24
  34. data/src/core/credentials/transport/tls/grpc_tls_certificate_distributor.h +19 -8
  35. data/src/core/credentials/transport/tls/grpc_tls_certificate_provider.cc +96 -54
  36. data/src/core/credentials/transport/tls/grpc_tls_certificate_provider.h +15 -2
  37. data/src/core/credentials/transport/tls/spiffe_utils.cc +371 -0
  38. data/src/core/credentials/transport/tls/spiffe_utils.h +171 -0
  39. data/src/core/credentials/transport/tls/ssl_utils.cc +11 -10
  40. data/src/core/credentials/transport/tls/ssl_utils.h +4 -2
  41. data/src/core/credentials/transport/tls/tls_credentials.cc +2 -0
  42. data/src/core/credentials/transport/tls/tls_security_connector.cc +11 -26
  43. data/src/core/credentials/transport/tls/tls_security_connector.h +12 -12
  44. data/src/core/ext/filters/backend_metrics/backend_metric_filter.cc +1 -2
  45. data/src/core/ext/filters/http/client/http_client_filter.cc +3 -6
  46. data/src/core/ext/filters/http/client_authority_filter.cc +1 -2
  47. data/src/core/ext/filters/http/message_compress/compression_filter.cc +8 -8
  48. data/src/core/ext/filters/http/server/http_server_filter.cc +3 -6
  49. data/src/core/ext/filters/message_size/message_size_filter.cc +4 -4
  50. data/src/core/ext/filters/rbac/rbac_filter.cc +1 -1
  51. data/src/core/ext/filters/stateful_session/stateful_session_filter.cc +3 -5
  52. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +3 -2
  53. data/src/core/ext/transport/chttp2/transport/flow_control.cc +1 -0
  54. data/src/core/ext/transport/chttp2/transport/flow_control.h +1 -0
  55. data/src/core/ext/transport/chttp2/transport/frame.cc +89 -6
  56. data/src/core/ext/transport/chttp2/transport/frame.h +38 -0
  57. data/src/core/ext/transport/chttp2/transport/header_assembler.h +5 -14
  58. data/src/core/ext/transport/chttp2/transport/hpack_parser.h +4 -1
  59. data/src/core/ext/transport/chttp2/transport/http2_client_transport.cc +294 -78
  60. data/src/core/ext/transport/chttp2/transport/http2_client_transport.h +128 -9
  61. data/src/core/ext/transport/chttp2/transport/http2_settings.cc +11 -38
  62. data/src/core/ext/transport/chttp2/transport/http2_settings.h +52 -35
  63. data/src/core/ext/transport/chttp2/transport/http2_settings_manager.cc +61 -0
  64. data/src/core/ext/transport/chttp2/transport/http2_settings_manager.h +142 -0
  65. data/src/core/ext/transport/chttp2/transport/http2_transport.cc +81 -3
  66. data/src/core/ext/transport/chttp2/transport/http2_transport.h +12 -1
  67. data/src/core/ext/transport/chttp2/transport/message_assembler.h +2 -2
  68. data/src/core/ext/transport/chttp2/transport/parsing.cc +2 -1
  69. data/src/core/ext/transport/chttp2/transport/ping_promise.cc +2 -1
  70. data/src/core/ext/transport/chttp2/transport/ping_promise.h +22 -5
  71. data/src/core/ext/transport/chttp2/transport/stream_data_queue.h +607 -0
  72. data/src/core/ext/transport/chttp2/transport/writable_streams.h +254 -0
  73. data/src/core/ext/transport/chttp2/transport/writing.cc +6 -4
  74. data/src/core/ext/upb-gen/src/proto/grpc/channelz/channelz.upb.h +4959 -0
  75. data/src/core/ext/upb-gen/src/proto/grpc/channelz/channelz.upb_minitable.c +1111 -0
  76. data/src/core/ext/upb-gen/src/proto/grpc/channelz/channelz.upb_minitable.h +108 -0
  77. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/property_list.upb.h +142 -54
  78. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/property_list.upb_minitable.c +18 -14
  79. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/property_list.upb_minitable.h +2 -2
  80. data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/channelz.upbdefs.c +716 -0
  81. data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/channelz.upbdefs.h +227 -0
  82. data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/property_list.upbdefs.c +86 -88
  83. data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/property_list.upbdefs.h +2 -2
  84. data/src/core/filter/auth/auth_filters.h +2 -2
  85. data/src/core/filter/fused_filters.cc +154 -0
  86. data/src/core/handshaker/security/legacy_secure_endpoint.cc +1 -1
  87. data/src/core/handshaker/security/pipelined_secure_endpoint.cc +965 -0
  88. data/src/core/handshaker/security/secure_endpoint.cc +28 -13
  89. data/src/core/handshaker/security/secure_endpoint.h +8 -0
  90. data/src/core/lib/channel/promise_based_filter.cc +15 -25
  91. data/src/core/lib/channel/promise_based_filter.h +6 -5
  92. data/src/core/lib/event_engine/ares_resolver.h +3 -1
  93. data/src/core/lib/event_engine/cf_engine/cf_engine.cc +9 -5
  94. data/src/core/lib/event_engine/cf_engine/cf_engine.h +2 -1
  95. data/src/core/lib/event_engine/cf_engine/cfsocket_listener.cc +263 -0
  96. data/src/core/lib/event_engine/cf_engine/cfsocket_listener.h +107 -0
  97. data/src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc +31 -3
  98. data/src/core/lib/event_engine/cf_engine/cfstream_endpoint.h +12 -0
  99. data/src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc +12 -10
  100. data/src/core/lib/event_engine/posix_engine/ev_epoll1_linux.h +6 -4
  101. data/src/core/lib/event_engine/posix_engine/ev_poll_posix.cc +15 -14
  102. data/src/core/lib/event_engine/posix_engine/ev_poll_posix.h +7 -5
  103. data/src/core/lib/event_engine/posix_engine/event_poller.h +0 -8
  104. data/src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc +11 -5
  105. data/src/core/lib/event_engine/posix_engine/event_poller_posix_default.h +3 -2
  106. data/src/core/lib/event_engine/posix_engine/grpc_polled_fd_posix.h +1 -0
  107. data/src/core/lib/event_engine/posix_engine/lockfree_event.cc +4 -4
  108. data/src/core/lib/event_engine/posix_engine/lockfree_event.h +3 -4
  109. data/src/core/lib/event_engine/posix_engine/posix_endpoint.cc +2 -2
  110. data/src/core/lib/event_engine/posix_engine/posix_engine.cc +188 -199
  111. data/src/core/lib/event_engine/posix_engine/posix_engine.h +30 -45
  112. data/src/core/lib/event_engine/posix_engine/posix_engine_listener.cc +1 -1
  113. data/src/core/lib/event_engine/posix_engine/tcp_socket_utils.h +1 -1
  114. data/src/core/lib/event_engine/windows/grpc_polled_fd_windows.cc +2 -1
  115. data/src/core/lib/experiments/experiments.cc +120 -6
  116. data/src/core/lib/experiments/experiments.h +46 -3
  117. data/src/core/lib/iomgr/combiner.cc +1 -1
  118. data/src/core/lib/iomgr/exec_ctx.h +3 -9
  119. data/src/core/lib/iomgr/socket_mutator.cc +1 -1
  120. data/src/core/lib/iomgr/socket_utils_posix.cc +1 -1
  121. data/src/core/lib/iomgr/socket_utils_posix.h +1 -1
  122. data/src/core/lib/iomgr/tcp_client_posix.cc +1 -1
  123. data/src/core/lib/iomgr/tcp_posix.cc +3 -3
  124. data/src/core/lib/promise/activity.h +2 -2
  125. data/src/core/lib/promise/mpsc.cc +8 -8
  126. data/src/core/lib/promise/party.cc +7 -7
  127. data/src/core/lib/promise/party.h +4 -4
  128. data/src/core/lib/promise/poll.h +10 -0
  129. data/src/core/lib/resource_quota/memory_quota.cc +90 -3
  130. data/src/core/lib/resource_quota/memory_quota.h +20 -9
  131. data/src/core/lib/resource_quota/periodic_update.cc +14 -0
  132. data/src/core/lib/resource_quota/periodic_update.h +8 -0
  133. data/src/core/lib/resource_quota/resource_quota.cc +15 -4
  134. data/src/core/lib/resource_quota/resource_quota.h +3 -0
  135. data/src/core/lib/security/authorization/grpc_server_authz_filter.cc +1 -2
  136. data/src/core/lib/surface/call.cc +5 -5
  137. data/src/core/lib/surface/call.h +6 -5
  138. data/src/core/lib/surface/completion_queue.cc +2 -4
  139. data/src/core/lib/surface/filter_stack_call.cc +1 -1
  140. data/src/core/lib/surface/version.cc +2 -2
  141. data/src/core/lib/transport/promise_endpoint.cc +2 -2
  142. data/src/core/lib/transport/promise_endpoint.h +3 -3
  143. data/src/core/load_balancing/endpoint_list.cc +29 -2
  144. data/src/core/load_balancing/grpclb/client_load_reporting_filter.cc +3 -3
  145. data/src/core/load_balancing/grpclb/client_load_reporting_filter.h +1 -1
  146. data/src/core/load_balancing/pick_first/pick_first.cc +12 -5
  147. data/src/core/load_balancing/xds/xds_cluster_impl.cc +5 -3
  148. data/src/core/net/socket_mutator.cc +19 -0
  149. data/src/core/net/socket_mutator.h +25 -0
  150. data/src/core/plugin_registry/grpc_plugin_registry.cc +6 -0
  151. data/src/core/resolver/dns/c_ares/grpc_ares_ev_driver.h +6 -1
  152. data/src/core/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +2 -1
  153. data/src/core/resolver/dns/c_ares/grpc_ares_wrapper.cc +8 -5
  154. data/src/core/resolver/dns/c_ares/grpc_ares_wrapper.h +2 -1
  155. data/src/core/resolver/xds/xds_dependency_manager.cc +1 -1
  156. data/src/core/server/server.cc +1 -1
  157. data/src/core/server/server_call_tracer_filter.cc +0 -66
  158. data/src/core/server/server_call_tracer_filter.h +64 -0
  159. data/src/core/server/server_config_selector_filter.cc +1 -1
  160. data/src/core/service_config/service_config_channel_arg_filter.cc +3 -60
  161. data/src/core/service_config/service_config_channel_arg_filter.h +82 -0
  162. data/src/core/telemetry/call_tracer.cc +20 -14
  163. data/src/core/telemetry/call_tracer.h +22 -17
  164. data/src/core/telemetry/metrics.h +8 -8
  165. data/src/core/telemetry/stats_data.cc +151 -151
  166. data/src/core/telemetry/stats_data.h +87 -87
  167. data/src/core/transport/auth_context.cc +20 -0
  168. data/src/core/transport/auth_context.h +4 -0
  169. data/src/core/transport/auth_context_comparator_registry.h +69 -0
  170. data/src/core/tsi/alts/handshaker/alts_handshaker_client.cc +2 -3
  171. data/src/core/tsi/ssl_transport_security.cc +202 -32
  172. data/src/core/tsi/ssl_transport_security.h +19 -10
  173. data/src/core/tsi/ssl_transport_security_utils.cc +21 -0
  174. data/src/core/tsi/ssl_transport_security_utils.h +4 -0
  175. data/src/core/util/http_client/httpcli_security_connector.cc +3 -1
  176. data/src/core/util/latent_see.cc +178 -146
  177. data/src/core/util/latent_see.h +245 -188
  178. data/src/core/util/single_set_ptr.h +5 -2
  179. data/src/core/util/useful.h +91 -0
  180. data/src/core/util/windows/directory_reader.cc +1 -0
  181. data/src/core/util/windows/thd.cc +1 -3
  182. data/src/core/util/work_serializer.cc +1 -1
  183. data/src/core/xds/grpc/file_watcher_certificate_provider_factory.cc +32 -5
  184. data/src/core/xds/grpc/file_watcher_certificate_provider_factory.h +5 -0
  185. data/src/core/xds/grpc/xds_certificate_provider.cc +5 -6
  186. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +1 -1
  187. data/src/ruby/lib/grpc/version.rb +1 -1
  188. data/third_party/cares/cares/include/ares.h +925 -460
  189. data/third_party/cares/cares/include/ares_dns.h +86 -71
  190. data/third_party/cares/cares/include/ares_dns_record.h +1118 -0
  191. data/third_party/cares/cares/include/ares_nameser.h +215 -189
  192. data/third_party/cares/cares/include/ares_version.h +37 -14
  193. data/third_party/cares/cares/src/lib/ares_addrinfo2hostent.c +305 -0
  194. data/third_party/cares/cares/src/lib/ares_addrinfo_localhost.c +245 -0
  195. data/third_party/cares/cares/src/lib/ares_android.c +216 -164
  196. data/third_party/cares/cares/src/lib/ares_android.h +25 -14
  197. data/third_party/cares/cares/src/lib/ares_cancel.c +68 -44
  198. data/third_party/cares/cares/src/lib/ares_close_sockets.c +137 -0
  199. data/third_party/cares/cares/src/lib/ares_conn.c +511 -0
  200. data/third_party/cares/cares/src/lib/ares_conn.h +196 -0
  201. data/third_party/cares/cares/src/lib/ares_cookie.c +461 -0
  202. data/third_party/cares/cares/src/lib/ares_data.c +93 -181
  203. data/third_party/cares/cares/src/lib/ares_data.h +50 -39
  204. data/third_party/cares/cares/src/lib/ares_destroy.c +127 -89
  205. data/third_party/cares/cares/src/lib/ares_free_hostent.c +35 -24
  206. data/third_party/cares/cares/src/lib/ares_free_string.c +24 -16
  207. data/third_party/cares/cares/src/lib/ares_freeaddrinfo.c +45 -38
  208. data/third_party/cares/cares/src/lib/ares_getaddrinfo.c +549 -663
  209. data/third_party/cares/cares/src/lib/ares_getenv.c +25 -15
  210. data/third_party/cares/cares/src/lib/ares_getenv.h +26 -18
  211. data/third_party/cares/cares/src/lib/ares_gethostbyaddr.c +163 -221
  212. data/third_party/cares/cares/src/lib/ares_gethostbyname.c +222 -223
  213. data/third_party/cares/cares/src/lib/ares_getnameinfo.c +328 -338
  214. data/third_party/cares/cares/src/lib/ares_hosts_file.c +952 -0
  215. data/third_party/cares/cares/src/lib/ares_inet_net_pton.h +25 -19
  216. data/third_party/cares/cares/src/lib/ares_init.c +425 -2091
  217. data/third_party/cares/cares/src/lib/ares_ipv6.h +63 -33
  218. data/third_party/cares/cares/src/lib/ares_library_init.c +110 -54
  219. data/third_party/cares/cares/src/lib/ares_metrics.c +261 -0
  220. data/third_party/cares/cares/src/lib/ares_options.c +418 -332
  221. data/third_party/cares/cares/src/lib/ares_parse_into_addrinfo.c +179 -0
  222. data/third_party/cares/cares/src/lib/ares_private.h +558 -356
  223. data/third_party/cares/cares/src/lib/ares_process.c +1224 -1369
  224. data/third_party/cares/cares/src/lib/ares_qcache.c +430 -0
  225. data/third_party/cares/cares/src/lib/ares_query.c +126 -121
  226. data/third_party/cares/cares/src/lib/ares_search.c +564 -262
  227. data/third_party/cares/cares/src/lib/ares_send.c +264 -93
  228. data/third_party/cares/cares/src/lib/ares_set_socket_functions.c +588 -0
  229. data/third_party/cares/cares/src/lib/ares_setup.h +115 -111
  230. data/third_party/cares/cares/src/lib/ares_socket.c +425 -0
  231. data/third_party/cares/cares/src/lib/ares_socket.h +163 -0
  232. data/third_party/cares/cares/src/lib/ares_sortaddrinfo.c +447 -0
  233. data/third_party/cares/cares/src/lib/ares_strerror.c +83 -48
  234. data/third_party/cares/cares/src/lib/ares_sysconfig.c +639 -0
  235. data/third_party/cares/cares/src/lib/ares_sysconfig_files.c +839 -0
  236. data/third_party/cares/cares/src/lib/ares_sysconfig_mac.c +373 -0
  237. data/third_party/cares/cares/src/lib/ares_sysconfig_win.c +621 -0
  238. data/third_party/cares/cares/src/lib/ares_timeout.c +136 -73
  239. data/third_party/cares/cares/src/lib/ares_update_servers.c +1362 -0
  240. data/third_party/cares/cares/src/lib/ares_version.c +29 -4
  241. data/third_party/cares/cares/src/lib/config-dos.h +88 -89
  242. data/third_party/cares/cares/src/lib/config-win32.h +122 -77
  243. data/third_party/cares/cares/src/lib/dsa/ares_array.c +394 -0
  244. data/third_party/cares/cares/src/lib/dsa/ares_htable.c +447 -0
  245. data/third_party/cares/cares/src/lib/dsa/ares_htable.h +174 -0
  246. data/third_party/cares/cares/src/lib/dsa/ares_htable_asvp.c +224 -0
  247. data/third_party/cares/cares/src/lib/dsa/ares_htable_dict.c +228 -0
  248. data/third_party/cares/cares/src/lib/dsa/ares_htable_strvp.c +210 -0
  249. data/third_party/cares/cares/src/lib/dsa/ares_htable_szvp.c +188 -0
  250. data/third_party/cares/cares/src/lib/dsa/ares_htable_vpstr.c +186 -0
  251. data/third_party/cares/cares/src/lib/dsa/ares_htable_vpvp.c +194 -0
  252. data/third_party/cares/cares/src/lib/dsa/ares_llist.c +382 -0
  253. data/third_party/cares/cares/src/lib/dsa/ares_slist.c +479 -0
  254. data/third_party/cares/cares/src/lib/dsa/ares_slist.h +207 -0
  255. data/third_party/cares/cares/src/lib/event/ares_event.h +191 -0
  256. data/third_party/cares/cares/src/lib/event/ares_event_configchg.c +743 -0
  257. data/third_party/cares/cares/src/lib/event/ares_event_epoll.c +192 -0
  258. data/third_party/cares/cares/src/lib/event/ares_event_kqueue.c +248 -0
  259. data/third_party/cares/cares/src/lib/event/ares_event_poll.c +140 -0
  260. data/third_party/cares/cares/src/lib/event/ares_event_select.c +159 -0
  261. data/third_party/cares/cares/src/lib/event/ares_event_thread.c +567 -0
  262. data/third_party/cares/cares/src/lib/event/ares_event_wake_pipe.c +166 -0
  263. data/third_party/cares/cares/src/lib/event/ares_event_win32.c +978 -0
  264. data/third_party/cares/cares/src/lib/event/ares_event_win32.h +161 -0
  265. data/third_party/cares/cares/src/lib/include/ares_array.h +276 -0
  266. data/third_party/cares/cares/src/lib/include/ares_buf.h +732 -0
  267. data/third_party/cares/cares/src/lib/include/ares_htable_asvp.h +130 -0
  268. data/third_party/cares/cares/src/lib/include/ares_htable_dict.h +123 -0
  269. data/third_party/cares/cares/src/lib/include/ares_htable_strvp.h +130 -0
  270. data/third_party/cares/cares/src/lib/include/ares_htable_szvp.h +118 -0
  271. data/third_party/cares/cares/src/lib/include/ares_htable_vpstr.h +111 -0
  272. data/third_party/cares/cares/src/lib/include/ares_htable_vpvp.h +128 -0
  273. data/third_party/cares/cares/src/lib/include/ares_llist.h +239 -0
  274. data/third_party/cares/cares/src/lib/include/ares_mem.h +38 -0
  275. data/third_party/cares/cares/src/lib/include/ares_str.h +244 -0
  276. data/third_party/cares/cares/src/lib/inet_net_pton.c +202 -157
  277. data/third_party/cares/cares/src/lib/inet_ntop.c +87 -69
  278. data/third_party/cares/cares/src/lib/legacy/ares_create_query.c +78 -0
  279. data/third_party/cares/cares/src/lib/legacy/ares_expand_name.c +99 -0
  280. data/third_party/cares/cares/src/lib/legacy/ares_expand_string.c +107 -0
  281. data/third_party/cares/cares/src/lib/legacy/ares_fds.c +80 -0
  282. data/third_party/cares/cares/src/lib/legacy/ares_getsock.c +85 -0
  283. data/third_party/cares/cares/src/lib/legacy/ares_parse_a_reply.c +107 -0
  284. data/third_party/cares/cares/src/lib/legacy/ares_parse_aaaa_reply.c +109 -0
  285. data/third_party/cares/cares/src/lib/legacy/ares_parse_caa_reply.c +137 -0
  286. data/third_party/cares/cares/src/lib/legacy/ares_parse_mx_reply.c +110 -0
  287. data/third_party/cares/cares/src/lib/legacy/ares_parse_naptr_reply.c +132 -0
  288. data/third_party/cares/cares/src/lib/legacy/ares_parse_ns_reply.c +154 -0
  289. data/third_party/cares/cares/src/lib/legacy/ares_parse_ptr_reply.c +213 -0
  290. data/third_party/cares/cares/src/lib/legacy/ares_parse_soa_reply.c +115 -0
  291. data/third_party/cares/cares/src/lib/legacy/ares_parse_srv_reply.c +114 -0
  292. data/third_party/cares/cares/src/lib/legacy/ares_parse_txt_reply.c +144 -0
  293. data/third_party/cares/cares/src/lib/legacy/ares_parse_uri_reply.c +113 -0
  294. data/third_party/cares/cares/src/lib/record/ares_dns_mapping.c +982 -0
  295. data/third_party/cares/cares/src/lib/record/ares_dns_multistring.c +307 -0
  296. data/third_party/cares/cares/src/lib/record/ares_dns_multistring.h +72 -0
  297. data/third_party/cares/cares/src/lib/record/ares_dns_name.c +673 -0
  298. data/third_party/cares/cares/src/lib/record/ares_dns_parse.c +1329 -0
  299. data/third_party/cares/cares/src/lib/record/ares_dns_private.h +273 -0
  300. data/third_party/cares/cares/src/lib/record/ares_dns_record.c +1661 -0
  301. data/third_party/cares/cares/src/lib/record/ares_dns_write.c +1229 -0
  302. data/third_party/cares/cares/src/lib/str/ares_buf.c +1498 -0
  303. data/third_party/cares/cares/src/lib/str/ares_str.c +508 -0
  304. data/third_party/cares/cares/src/lib/str/ares_strsplit.c +90 -0
  305. data/third_party/cares/cares/src/lib/str/ares_strsplit.h +51 -0
  306. data/third_party/cares/cares/src/lib/thirdparty/apple/dnsinfo.h +122 -0
  307. data/third_party/cares/cares/src/lib/util/ares_iface_ips.c +628 -0
  308. data/third_party/cares/cares/src/lib/util/ares_iface_ips.h +139 -0
  309. data/third_party/cares/cares/src/lib/util/ares_math.c +158 -0
  310. data/third_party/cares/cares/src/lib/util/ares_math.h +45 -0
  311. data/third_party/cares/cares/src/lib/util/ares_rand.c +389 -0
  312. data/third_party/cares/cares/src/lib/util/ares_rand.h +36 -0
  313. data/third_party/cares/cares/src/lib/util/ares_threads.c +614 -0
  314. data/third_party/cares/cares/src/lib/util/ares_threads.h +60 -0
  315. data/third_party/cares/cares/src/lib/util/ares_time.h +48 -0
  316. data/third_party/cares/cares/src/lib/util/ares_timeval.c +95 -0
  317. data/third_party/cares/cares/src/lib/util/ares_uri.c +1626 -0
  318. data/third_party/cares/cares/src/lib/util/ares_uri.h +252 -0
  319. data/third_party/cares/cares/src/lib/windows_port.c +16 -9
  320. metadata +121 -49
  321. data/src/core/util/ring_buffer.h +0 -122
  322. data/third_party/cares/cares/include/ares_rules.h +0 -125
  323. data/third_party/cares/cares/src/lib/ares__addrinfo2hostent.c +0 -266
  324. data/third_party/cares/cares/src/lib/ares__addrinfo_localhost.c +0 -240
  325. data/third_party/cares/cares/src/lib/ares__close_sockets.c +0 -61
  326. data/third_party/cares/cares/src/lib/ares__get_hostent.c +0 -260
  327. data/third_party/cares/cares/src/lib/ares__parse_into_addrinfo.c +0 -229
  328. data/third_party/cares/cares/src/lib/ares__read_line.c +0 -73
  329. data/third_party/cares/cares/src/lib/ares__readaddrinfo.c +0 -258
  330. data/third_party/cares/cares/src/lib/ares__sortaddrinfo.c +0 -507
  331. data/third_party/cares/cares/src/lib/ares__timeval.c +0 -111
  332. data/third_party/cares/cares/src/lib/ares_create_query.c +0 -197
  333. data/third_party/cares/cares/src/lib/ares_expand_name.c +0 -311
  334. data/third_party/cares/cares/src/lib/ares_expand_string.c +0 -67
  335. data/third_party/cares/cares/src/lib/ares_fds.c +0 -59
  336. data/third_party/cares/cares/src/lib/ares_getsock.c +0 -66
  337. data/third_party/cares/cares/src/lib/ares_iphlpapi.h +0 -221
  338. data/third_party/cares/cares/src/lib/ares_llist.c +0 -63
  339. data/third_party/cares/cares/src/lib/ares_llist.h +0 -39
  340. data/third_party/cares/cares/src/lib/ares_mkquery.c +0 -24
  341. data/third_party/cares/cares/src/lib/ares_nowarn.c +0 -260
  342. data/third_party/cares/cares/src/lib/ares_nowarn.h +0 -61
  343. data/third_party/cares/cares/src/lib/ares_parse_a_reply.c +0 -90
  344. data/third_party/cares/cares/src/lib/ares_parse_aaaa_reply.c +0 -92
  345. data/third_party/cares/cares/src/lib/ares_parse_caa_reply.c +0 -199
  346. data/third_party/cares/cares/src/lib/ares_parse_mx_reply.c +0 -164
  347. data/third_party/cares/cares/src/lib/ares_parse_naptr_reply.c +0 -183
  348. data/third_party/cares/cares/src/lib/ares_parse_ns_reply.c +0 -177
  349. data/third_party/cares/cares/src/lib/ares_parse_ptr_reply.c +0 -228
  350. data/third_party/cares/cares/src/lib/ares_parse_soa_reply.c +0 -179
  351. data/third_party/cares/cares/src/lib/ares_parse_srv_reply.c +0 -168
  352. data/third_party/cares/cares/src/lib/ares_parse_txt_reply.c +0 -214
  353. data/third_party/cares/cares/src/lib/ares_parse_uri_reply.c +0 -184
  354. data/third_party/cares/cares/src/lib/ares_platform.c +0 -11042
  355. data/third_party/cares/cares/src/lib/ares_platform.h +0 -43
  356. data/third_party/cares/cares/src/lib/ares_rand.c +0 -279
  357. data/third_party/cares/cares/src/lib/ares_strcasecmp.c +0 -66
  358. data/third_party/cares/cares/src/lib/ares_strcasecmp.h +0 -30
  359. data/third_party/cares/cares/src/lib/ares_strdup.c +0 -42
  360. data/third_party/cares/cares/src/lib/ares_strdup.h +0 -24
  361. data/third_party/cares/cares/src/lib/ares_strsplit.c +0 -94
  362. data/third_party/cares/cares/src/lib/ares_strsplit.h +0 -42
  363. data/third_party/cares/cares/src/lib/ares_writev.c +0 -79
  364. data/third_party/cares/cares/src/lib/ares_writev.h +0 -36
  365. data/third_party/cares/cares/src/lib/bitncmp.c +0 -59
  366. data/third_party/cares/cares/src/lib/bitncmp.h +0 -26
  367. data/third_party/cares/cares/src/lib/setup_once.h +0 -554
  368. data/third_party/cares/cares/src/tools/ares_getopt.h +0 -53
@@ -0,0 +1,371 @@
1
+ //
2
+ //
3
+ // Copyright 2025 gRPC authors.
4
+ //
5
+ // Licensed under the Apache License, Version 2.0 (the "License");
6
+ // you may not use this file except in compliance with the License.
7
+ // You may obtain a copy of the License at
8
+ //
9
+ // http://www.apache.org/licenses/LICENSE-2.0
10
+ //
11
+ // Unless required by applicable law or agreed to in writing, software
12
+ // distributed under the License is distributed on an "AS IS" BASIS,
13
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ // See the License for the specific language governing permissions and
15
+ // limitations under the License.
16
+ //
17
+ //
18
+
19
+ #include "src/core/credentials/transport/tls/spiffe_utils.h"
20
+
21
+ #include <openssl/x509.h>
22
+
23
+ #include <string>
24
+
25
+ #include "absl/strings/match.h"
26
+ #include "absl/strings/str_cat.h"
27
+ #include "absl/strings/str_format.h"
28
+ #include "absl/strings/str_split.h"
29
+ #include "src/core/tsi/ssl_transport_security_utils.h"
30
+ #include "src/core/util/json/json_object_loader.h"
31
+ #include "src/core/util/json/json_reader.h"
32
+ #include "src/core/util/load_file.h"
33
+ #include "src/core/util/status_helper.h"
34
+
35
+ namespace grpc_core {
36
+ namespace {
37
+ constexpr absl::string_view kAllowedUse = "x509-svid";
38
+ constexpr absl::string_view kAllowedKty = "RSA";
39
+ constexpr absl::string_view kCertificatePrefix =
40
+ "-----BEGIN CERTIFICATE-----\n";
41
+ constexpr absl::string_view kCertificateSuffix = "\n-----END CERTIFICATE-----";
42
+ constexpr int kMaxTrustDomainLength = 255;
43
+ constexpr absl::string_view kSpiffePrefix = "spiffe://";
44
+ constexpr int kX5cSize = 1;
45
+
46
+ // Checks broad conditions on the whole input before splitting into the
47
+ // pieces of a SPIFFE ID
48
+ absl::Status DoInitialUriValidation(absl::string_view uri) {
49
+ if (uri.empty()) {
50
+ return absl::InvalidArgumentError(
51
+ "SPIFFE ID cannot be parsed from empty URI");
52
+ }
53
+ if (uri.length() > 2048) {
54
+ return absl::InvalidArgumentError(absl::StrFormat(
55
+ "URI length is %d, maximum allowed for SPIFFE ID is 2048",
56
+ uri.length()));
57
+ }
58
+ if (absl::StrContains(uri, "#")) {
59
+ return absl::InvalidArgumentError(
60
+ "SPIFFE ID cannot contain query fragments");
61
+ }
62
+ if (absl::StrContains(uri, "?")) {
63
+ return absl::InvalidArgumentError(
64
+ "SPIFFE ID cannot contain query parameters");
65
+ }
66
+ for (char ch : uri) {
67
+ if (!absl::ascii_isascii(ch)) {
68
+ return absl::InvalidArgumentError(absl::StrFormat(
69
+ "SPIFFE ID URI cannot contain non-ascii characters. Contains %#x",
70
+ ch));
71
+ }
72
+ }
73
+ return absl::OkStatus();
74
+ }
75
+
76
+ absl::Status ValidateTrustDomain(absl::string_view trust_domain) {
77
+ if (trust_domain.empty()) {
78
+ return absl::InvalidArgumentError("Trust domain cannot be empty");
79
+ }
80
+ if (trust_domain.size() > kMaxTrustDomainLength) {
81
+ return absl::InvalidArgumentError(absl::StrFormat(
82
+ "Trust domain maximum length is %i characters", kMaxTrustDomainLength));
83
+ }
84
+ for (auto c : trust_domain) {
85
+ if (c >= 'a' && c <= 'z') continue;
86
+ if (c >= '0' && c <= '9') continue;
87
+ if (c == '.') continue;
88
+ if (c == '-') continue;
89
+ if (c == '_') continue;
90
+ return absl::InvalidArgumentError(absl::StrFormat(
91
+ "Trust domain contains invalid character '%c'. MUST contain only "
92
+ "lowercase letters, numbers, dots, dashes, and underscores",
93
+ c));
94
+ }
95
+ return absl::OkStatus();
96
+ }
97
+
98
+ absl::Status ValidatePathSegment(absl::string_view path_segment) {
99
+ if (path_segment.empty()) {
100
+ return absl::InvalidArgumentError("Path segment cannot be empty");
101
+ }
102
+ if (path_segment == "." || path_segment == "..") {
103
+ return absl::InvalidArgumentError(
104
+ "Path segment cannot be a relative modifier (. or ..)");
105
+ }
106
+ for (auto c : path_segment) {
107
+ if (c >= 'a' && c <= 'z') continue;
108
+ if (c >= 'A' && c <= 'Z') continue;
109
+ if (c >= '0' && c <= '9') continue;
110
+ if (c == '.') continue;
111
+ if (c == '-') continue;
112
+ if (c == '_') continue;
113
+ return absl::InvalidArgumentError(absl::StrFormat(
114
+ "Path segment contains invalid character '%c'. MUST contain only "
115
+ "letters, numbers, dots, dashes, and underscores",
116
+ c));
117
+ }
118
+ return absl::OkStatus();
119
+ }
120
+
121
+ absl::Status ValidatePath(absl::string_view path) {
122
+ if (path.empty()) {
123
+ return absl::OkStatus();
124
+ }
125
+ for (absl::string_view segment : absl::StrSplit(path, '/')) {
126
+ GRPC_RETURN_IF_ERROR(ValidatePathSegment(segment));
127
+ }
128
+ return absl::OkStatus();
129
+ }
130
+
131
+ } // namespace
132
+
133
+ std::string AddPemBlockWrapping(absl::string_view spiffe_bundle_root) {
134
+ return absl::StrCat(kCertificatePrefix, spiffe_bundle_root,
135
+ kCertificateSuffix);
136
+ }
137
+
138
+ absl::StatusOr<SpiffeId> SpiffeId::FromString(absl::string_view input) {
139
+ GRPC_RETURN_IF_ERROR(DoInitialUriValidation(input));
140
+ if (!absl::StartsWithIgnoreCase(input, kSpiffePrefix)) {
141
+ return absl::InvalidArgumentError("SPIFFE ID must start with spiffe://");
142
+ }
143
+ if (absl::EndsWith(input, /*suffix=*/"/")) {
144
+ return absl::InvalidArgumentError("SPIFFE ID cannot end with a /");
145
+ }
146
+ // The input definitely starts with spiffe://
147
+ absl::string_view trust_domain_and_path =
148
+ input.substr(kSpiffePrefix.length());
149
+ absl::string_view trust_domain;
150
+ absl::string_view path;
151
+ if (absl::StartsWith(trust_domain_and_path, "/")) {
152
+ // To be here the SPIFFE ID must look like spiffe:///path, which means the
153
+ // trust domain is empty, which is invalid
154
+ return absl::InvalidArgumentError("The trust domain cannot be empty");
155
+ }
156
+ // It's valid to have no path, e.g. spiffe://foo.bar.com - handle those two
157
+ // cases
158
+ if (absl::StrContains(trust_domain_and_path, "/")) {
159
+ std::vector<absl::string_view> split =
160
+ absl::StrSplit(trust_domain_and_path, absl::MaxSplits('/', 1));
161
+ trust_domain = split[0];
162
+ path = split[1];
163
+ } else {
164
+ trust_domain = trust_domain_and_path;
165
+ }
166
+ GRPC_RETURN_IF_ERROR(ValidateTrustDomain(trust_domain));
167
+ GRPC_RETURN_IF_ERROR(ValidatePath(path));
168
+ // If we have a path re-add the prepending `/`, otherwise leave it empty
169
+ if (path.empty()) {
170
+ return SpiffeId(trust_domain, "");
171
+ }
172
+ return SpiffeId(trust_domain, absl::StrCat("/", path));
173
+ }
174
+
175
+ const JsonLoaderInterface* SpiffeBundleKey::JsonLoader(const JsonArgs&) {
176
+ static const auto* kLoader = JsonObjectLoader<SpiffeBundleKey>().Finish();
177
+ return kLoader;
178
+ }
179
+
180
+ void SpiffeBundleKey::JsonPostLoad(const Json& json, const JsonArgs& args,
181
+ ValidationErrors* errors) {
182
+ auto use =
183
+ LoadJsonObjectField<std::string>(json.object(), args, "use", errors);
184
+ {
185
+ ValidationErrors::ScopedField field(errors, ".use");
186
+ if (use.has_value() && *use != kAllowedUse) {
187
+ errors->AddError(absl::StrFormat("value must be \"%s\", got \"%s\"",
188
+ kAllowedUse, *use));
189
+ }
190
+ }
191
+ auto kty =
192
+ LoadJsonObjectField<std::string>(json.object(), args, "kty", errors);
193
+ {
194
+ ValidationErrors::ScopedField field(errors, ".kty");
195
+ if (kty.has_value() && *kty != kAllowedKty) {
196
+ errors->AddError(absl::StrFormat("value must be \"%s\", got \"%s\"",
197
+ kAllowedKty, *kty));
198
+ }
199
+ }
200
+ auto x5c = LoadJsonObjectField<std::vector<std::string>>(json.object(), args,
201
+ "x5c", errors);
202
+ if (x5c.has_value()) {
203
+ ValidationErrors::ScopedField field(errors, ".x5c");
204
+ if (x5c->size() != kX5cSize) {
205
+ errors->AddError(
206
+ absl::StrCat("array length must be 1, got ", x5c->size()));
207
+ }
208
+ if (!x5c->empty()) {
209
+ ValidationErrors::ScopedField field(errors, "[0]");
210
+ std::string pem_cert = AddPemBlockWrapping((*x5c)[0]);
211
+ auto certs = ParsePemCertificateChain(pem_cert);
212
+ if (!certs.ok()) {
213
+ errors->AddError(certs.status().ToString());
214
+ } else {
215
+ root_ = std::move((*x5c)[0]);
216
+ for (X509* cert : *certs) {
217
+ X509_free(cert);
218
+ }
219
+ }
220
+ }
221
+ }
222
+ }
223
+
224
+ absl::string_view SpiffeBundleKey::GetRoot() { return root_; }
225
+
226
+ const JsonLoaderInterface* SpiffeBundle::JsonLoader(const JsonArgs&) {
227
+ static const auto* kLoader = JsonObjectLoader<SpiffeBundle>().Finish();
228
+ return kLoader;
229
+ }
230
+
231
+ void SpiffeBundle::JsonPostLoad(const Json& json, const JsonArgs& args,
232
+ ValidationErrors* errors) {
233
+ auto keys = LoadJsonObjectField<std::vector<SpiffeBundleKey>>(
234
+ json.object(), args, "keys", errors);
235
+ if (!keys.has_value()) {
236
+ return;
237
+ }
238
+ for (size_t i = 0; i < keys->size(); ++i) {
239
+ roots_.emplace_back((*keys)[i].GetRoot());
240
+ }
241
+ ValidationErrors::ScopedField field(errors, "keys");
242
+ absl::Status status = CreateX509Stack();
243
+ if (!status.ok()) {
244
+ errors->AddError(status.ToString());
245
+ }
246
+ }
247
+
248
+ SpiffeBundle::~SpiffeBundle() {
249
+ if (root_stack_ != nullptr) {
250
+ sk_X509_pop_free(*root_stack_, X509_free);
251
+ }
252
+ }
253
+
254
+ SpiffeBundle::SpiffeBundle(const SpiffeBundle& other) {
255
+ roots_ = other.roots_;
256
+ if (other.root_stack_ != nullptr) {
257
+ root_stack_ =
258
+ std::make_unique<STACK_OF(X509)*>(sk_X509_dup(*other.root_stack_));
259
+ for (size_t i = 0; i < sk_X509_num(*root_stack_); i++) {
260
+ X509* x = sk_X509_value(*root_stack_, i);
261
+ #if OPENSSL_VERSION_NUMBER >= 0x10100000L
262
+ CHECK(X509_up_ref(x));
263
+ #else
264
+ CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
265
+ #endif
266
+ }
267
+ }
268
+ }
269
+
270
+ SpiffeBundle& SpiffeBundle::operator=(const SpiffeBundle& other) {
271
+ if (this != &other) {
272
+ roots_ = other.roots_;
273
+ if (other.root_stack_ != nullptr) {
274
+ root_stack_ =
275
+ std::make_unique<STACK_OF(X509)*>(sk_X509_dup(*other.root_stack_));
276
+ for (size_t i = 0; i < sk_X509_num(*root_stack_); i++) {
277
+ X509* x = sk_X509_value(*root_stack_, i);
278
+ #if OPENSSL_VERSION_NUMBER >= 0x10100000L
279
+ CHECK(X509_up_ref(x));
280
+ #else
281
+ CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
282
+ #endif
283
+ }
284
+ }
285
+ }
286
+ return *this;
287
+ }
288
+
289
+ const JsonLoaderInterface* SpiffeBundleMap::JsonLoader(const JsonArgs&) {
290
+ static const auto* kLoader =
291
+ JsonObjectLoader<SpiffeBundleMap>()
292
+ .Field("trust_domains", &SpiffeBundleMap::bundles_)
293
+ .Finish();
294
+ return kLoader;
295
+ }
296
+
297
+ absl::Span<const std::string> SpiffeBundle::GetRoots() { return roots_; }
298
+
299
+ absl::StatusOr<STACK_OF(X509) *> SpiffeBundle::GetRootStack() {
300
+ if (root_stack_ == nullptr) {
301
+ return absl::FailedPreconditionError(
302
+ "root_stack_ has not been initialized");
303
+ }
304
+ return *root_stack_;
305
+ }
306
+
307
+ absl::Status SpiffeBundle::CreateX509Stack() {
308
+ root_stack_ = std::make_unique<STACK_OF(X509)*>(sk_X509_new_null());
309
+ absl::Status status = absl::OkStatus();
310
+ for (const auto& pem_cert : roots_) {
311
+ auto cert = ParsePemCertificateChain(AddPemBlockWrapping(pem_cert));
312
+ if (!cert.status().ok()) {
313
+ status = cert.status();
314
+ break;
315
+ }
316
+ if (cert->size() != 1) {
317
+ status = absl::InvalidArgumentError("Got a malformed root certificate.");
318
+ break;
319
+ }
320
+ sk_X509_push(*root_stack_, (*cert)[0]);
321
+ }
322
+ // If there was an error parsing we don't want a partially filled root stack.
323
+ if (!status.ok()) {
324
+ sk_X509_pop_free(*root_stack_, X509_free);
325
+ }
326
+ return status;
327
+ }
328
+
329
+ void SpiffeBundleMap::JsonPostLoad(const Json&, const JsonArgs&,
330
+ ValidationErrors* errors) {
331
+ {
332
+ for (auto const& [k, _] : bundles_) {
333
+ ValidationErrors::ScopedField field(
334
+ errors, absl::StrCat(".trust_domains[\"", k, "\"]"));
335
+ absl::Status status = ValidateTrustDomain(k);
336
+ if (!status.ok()) {
337
+ errors->AddError(
338
+ absl::StrCat("invalid trust domain: ", status.ToString()));
339
+ }
340
+ }
341
+ }
342
+ }
343
+
344
+ absl::StatusOr<SpiffeBundleMap> SpiffeBundleMap::FromFile(
345
+ absl::string_view file_path) {
346
+ auto slice = LoadFile(file_path.data(), /*add_null_terminator=*/false);
347
+ GRPC_RETURN_IF_ERROR(slice.status());
348
+ auto json = JsonParse(slice->as_string_view());
349
+ GRPC_RETURN_IF_ERROR(json.status());
350
+ return LoadFromJson<SpiffeBundleMap>(*json);
351
+ }
352
+
353
+ absl::StatusOr<absl::Span<const std::string>> SpiffeBundleMap::GetRoots(
354
+ const absl::string_view trust_domain) {
355
+ if (auto it = bundles_.find(trust_domain); it != bundles_.end()) {
356
+ return it->second.GetRoots();
357
+ }
358
+ return absl::NotFoundError(absl::StrFormat(
359
+ "No spiffe bundle found for trust domain %s", trust_domain));
360
+ }
361
+
362
+ absl::StatusOr<STACK_OF(X509) *> SpiffeBundleMap::GetRootStack(
363
+ absl::string_view trust_domain) {
364
+ if (auto it = bundles_.find(trust_domain); it != bundles_.end()) {
365
+ return it->second.GetRootStack();
366
+ }
367
+ return absl::NotFoundError(absl::StrFormat(
368
+ "No spiffe bundle found for trust domain %s", trust_domain));
369
+ }
370
+
371
+ } // namespace grpc_core
@@ -0,0 +1,171 @@
1
+ //
2
+ //
3
+ // Copyright 2025 gRPC authors.
4
+ //
5
+ // Licensed under the Apache License, Version 2.0 (the "License");
6
+ // you may not use this file except in compliance with the License.
7
+ // You may obtain a copy of the License at
8
+ //
9
+ // http://www.apache.org/licenses/LICENSE-2.0
10
+ //
11
+ // Unless required by applicable law or agreed to in writing, software
12
+ // distributed under the License is distributed on an "AS IS" BASIS,
13
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ // See the License for the specific language governing permissions and
15
+ // limitations under the License.
16
+ //
17
+ //
18
+
19
+ #ifndef GRPC_SRC_CORE_CREDENTIALS_TRANSPORT_TLS_SPIFFE_UTILS_H
20
+ #define GRPC_SRC_CORE_CREDENTIALS_TRANSPORT_TLS_SPIFFE_UTILS_H
21
+
22
+ #include <openssl/stack.h>
23
+ #include <openssl/x509.h>
24
+
25
+ #include <string>
26
+
27
+ #include "absl/status/statusor.h"
28
+ #include "absl/strings/string_view.h"
29
+ #include "src/core/util/json/json.h"
30
+ #include "src/core/util/json/json_object_loader.h"
31
+
32
+ namespace grpc_core {
33
+
34
+ // Adds the leading and trailing lines expected for a PEM formatted certificate
35
+ // around the raw base64 certificate data stored in a SPIFFE bundle map.
36
+ std::string AddPemBlockWrapping(absl::string_view spiffe_bundle_root);
37
+
38
+ // A representation of a SPIFFE ID per the spec:
39
+ // https://github.com/spiffe/spiffe/blob/main/standards/SPIFFE-ID.md#the-spiffe-identity-and-verifiable-identity-document
40
+ class SpiffeId final {
41
+ public:
42
+ // Parses the input string as a SPIFFE ID, and returns an error status if the
43
+ // input string is not a valid SPIFFE ID.
44
+ static absl::StatusOr<SpiffeId> FromString(absl::string_view input);
45
+ // Returns the trust domain of the SPIFFE ID
46
+ absl::string_view trust_domain() { return trust_domain_; }
47
+ // Returns the path of the SPIFFE ID
48
+ absl::string_view path() { return path_; }
49
+
50
+ private:
51
+ SpiffeId(absl::string_view trust_domain, absl::string_view path)
52
+ : trust_domain_(trust_domain), path_(path) {}
53
+ const std::string trust_domain_;
54
+ const std::string path_;
55
+ };
56
+
57
+ // An entry in the Key vector of a SPIFFE Bundle following these documents:
58
+ // https://github.com/spiffe/spiffe/blob/main/standards/SPIFFE_Trust_Domain_and_Bundle.md#3-spiffe-bundles
59
+ // https://github.com/grpc/proposal/blob/master/A87-mtls-spiffe-support.md
60
+ class SpiffeBundleKey final {
61
+ public:
62
+ static const JsonLoaderInterface* JsonLoader(const JsonArgs&);
63
+ void JsonPostLoad(const Json& json, const JsonArgs&,
64
+ ValidationErrors* errors);
65
+
66
+ // Returns the PEM x509 string for the root of trust for this SPIFFE Bundle
67
+ // entry.
68
+ absl::string_view GetRoot();
69
+
70
+ private:
71
+ // root_ is the X509 cert that is the root of trust. It is parsed from the x5c
72
+ // field per the SPIFFE Bundle Spec. In our use case, the x5c field must of of
73
+ // length 1 and represent a root of trust.
74
+ // https://github.com/spiffe/spiffe/blob/main/standards/SPIFFE_Trust_Domain_and_Bundle.md#3-spiffe-bundles
75
+ std::string root_;
76
+ };
77
+
78
+ // A SPIFFE bundle consists of a trust domain and a set of roots for that trust
79
+ // domain.
80
+ // https://github.com/spiffe/spiffe/blob/main/standards/SPIFFE_Trust_Domain_and_Bundle.md#3-spiffe-bundles
81
+ // https://github.com/grpc/proposal/blob/master/A87-mtls-spiffe-support.md
82
+ // Not thread-safe
83
+ class SpiffeBundle final {
84
+ public:
85
+ // Do not use - only exists to work with the JSON library.
86
+ // SpiffeBundles should be used by loading a SpiffeBundleMap via
87
+ // SpiffeBundleMap::FromFile
88
+ SpiffeBundle() = default;
89
+ ~SpiffeBundle();
90
+ SpiffeBundle(const SpiffeBundle& other);
91
+ SpiffeBundle& operator=(const SpiffeBundle& other);
92
+
93
+ static const JsonLoaderInterface* JsonLoader(const JsonArgs&);
94
+ void JsonPostLoad(const Json& json, const JsonArgs&,
95
+ ValidationErrors* errors);
96
+
97
+ // Returns a vector of the roots in this SPIFFE Bundle.
98
+ absl::Span<const std::string> GetRoots();
99
+
100
+ // The caller does not take ownership of the stack of roots.
101
+ // The caller MUST NOT mutate this value.
102
+ absl::StatusOr<STACK_OF(X509) *> GetRootStack();
103
+
104
+ bool operator==(const SpiffeBundle& other) const {
105
+ // For our purposes SPIFFE Bundles are equal if their roots are the same.
106
+ return roots_ == other.roots_;
107
+ }
108
+
109
+ bool operator!=(const SpiffeBundle& other) const {
110
+ return roots_ != other.roots_;
111
+ }
112
+
113
+ private:
114
+ // Constructs the `root_stack_` OpenSSL representation of the roots.
115
+ absl::Status CreateX509Stack();
116
+
117
+ std::vector<std::string> roots_;
118
+ std::unique_ptr<STACK_OF(X509)*> root_stack_;
119
+ };
120
+
121
+ // A map of SPIFFE bundles keyed to trust domains. This functions as a map of a
122
+ // given trust domain to the root certificates that should be used when
123
+ // validating certificates in this trust domain.
124
+ // https://github.com/grpc/proposal/blob/master/A87-mtls-spiffe-support.md
125
+ // https://github.com/grpc/proposal/blob/master/A87-mtls-spiffe-support.md
126
+ // Only configuring X509 roots is supported.
127
+ // Not thread-safe
128
+ class SpiffeBundleMap final {
129
+ public:
130
+ static const JsonLoaderInterface* JsonLoader(const JsonArgs&);
131
+ void JsonPostLoad(const Json& json, const JsonArgs&,
132
+ ValidationErrors* errors);
133
+
134
+ // Loads a SPIFFE Bundle Map from a json file representation. Returns a bad
135
+ // status if there is a problem while loading the file and parsing the JSON. A
136
+ // returned value represents a valid and SPIFFE Bundle Map.
137
+ // The only supported use is configuring X509 roots for a given trust domain -
138
+ // no other SPIFFE Bundle configurations are supported.
139
+ static absl::StatusOr<SpiffeBundleMap> FromFile(absl::string_view file_path);
140
+
141
+ // Returns the roots for a given trust domain in the SPIFFE Bundle Map.
142
+ absl::StatusOr<absl::Span<const std::string>> GetRoots(
143
+ absl::string_view trust_domain);
144
+
145
+ // The caller does not take ownership of the stack of roots.
146
+ absl::StatusOr<STACK_OF(X509) *> GetRootStack(
147
+ const absl::string_view trust_domain);
148
+ size_t size() const { return bundles_.size(); }
149
+
150
+ bool operator==(const SpiffeBundleMap& other) const {
151
+ return bundles_ == other.bundles_;
152
+ }
153
+
154
+ bool operator!=(const SpiffeBundleMap& other) const {
155
+ return bundles_ != other.bundles_;
156
+ }
157
+
158
+ private:
159
+ struct StringCmp {
160
+ using is_transparent = void;
161
+ bool operator()(absl::string_view a, absl::string_view b) const {
162
+ return a < b;
163
+ }
164
+ };
165
+
166
+ std::map<std::string, SpiffeBundle, StringCmp> bundles_;
167
+ };
168
+
169
+ } // namespace grpc_core
170
+
171
+ #endif // GRPC_SRC_CORE_CREDENTIALS_TRANSPORT_TLS_SPIFFE_UTILS_H
@@ -427,16 +427,19 @@ void grpc_shallow_peer_destruct(tsi_peer* peer) {
427
427
  }
428
428
 
429
429
  grpc_security_status grpc_ssl_tsi_client_handshaker_factory_init(
430
- tsi_ssl_pem_key_cert_pair* pem_key_cert_pair, const char* pem_root_certs,
430
+ tsi_ssl_pem_key_cert_pair* pem_key_cert_pair,
431
+ std::shared_ptr<RootCertInfo> root_cert_info,
431
432
  bool skip_server_certificate_verification, tsi_tls_version min_tls_version,
432
433
  tsi_tls_version max_tls_version, tsi_ssl_session_cache* ssl_session_cache,
433
434
  tsi::TlsSessionKeyLoggerCache::TlsSessionKeyLogger* tls_session_key_logger,
434
435
  const char* crl_directory,
435
436
  std::shared_ptr<grpc_core::experimental::CrlProvider> crl_provider,
436
437
  tsi_ssl_client_handshaker_factory** handshaker_factory) {
437
- const char* root_certs;
438
- const tsi_ssl_root_certs_store* root_store;
439
- if (pem_root_certs == nullptr && !skip_server_certificate_verification) {
438
+ const char* root_certs = nullptr;
439
+ const tsi_ssl_root_certs_store* root_store = nullptr;
440
+ tsi_ssl_client_handshaker_options options;
441
+ bool roots_are_configured = root_cert_info != nullptr;
442
+ if (!roots_are_configured && !skip_server_certificate_verification) {
440
443
  GRPC_TRACE_LOG(tsi, INFO)
441
444
  << "No root certificates specified; use ones stored in system "
442
445
  "default locations instead";
@@ -447,15 +450,13 @@ grpc_security_status grpc_ssl_tsi_client_handshaker_factory_init(
447
450
  return GRPC_SECURITY_ERROR;
448
451
  }
449
452
  root_store = grpc_core::DefaultSslRootStore::GetRootStore();
453
+ options.root_cert_info = std::make_shared<RootCertInfo>(root_certs);
450
454
  } else {
451
- root_certs = pem_root_certs;
452
- root_store = nullptr;
455
+ options.root_cert_info = std::move(root_cert_info);
453
456
  }
454
457
  bool has_key_cert_pair = pem_key_cert_pair != nullptr &&
455
458
  pem_key_cert_pair->private_key != nullptr &&
456
459
  pem_key_cert_pair->cert_chain != nullptr;
457
- tsi_ssl_client_handshaker_options options;
458
- options.pem_root_certs = root_certs;
459
460
  options.root_store = root_store;
460
461
  options.alpn_protocols =
461
462
  grpc_fill_alpn_protocol_strings(&options.num_alpn_protocols);
@@ -485,7 +486,7 @@ grpc_security_status grpc_ssl_tsi_client_handshaker_factory_init(
485
486
 
486
487
  grpc_security_status grpc_ssl_tsi_server_handshaker_factory_init(
487
488
  tsi_ssl_pem_key_cert_pair* pem_key_cert_pairs, size_t num_key_cert_pairs,
488
- const char* pem_root_certs,
489
+ std::shared_ptr<RootCertInfo> root_cert_info,
489
490
  grpc_ssl_client_certificate_request_type client_certificate_request,
490
491
  tsi_tls_version min_tls_version, tsi_tls_version max_tls_version,
491
492
  tsi::TlsSessionKeyLoggerCache::TlsSessionKeyLogger* tls_session_key_logger,
@@ -498,7 +499,6 @@ grpc_security_status grpc_ssl_tsi_server_handshaker_factory_init(
498
499
  tsi_ssl_server_handshaker_options options;
499
500
  options.pem_key_cert_pairs = pem_key_cert_pairs;
500
501
  options.num_key_cert_pairs = num_key_cert_pairs;
501
- options.pem_client_root_certs = pem_root_certs;
502
502
  options.client_certificate_request =
503
503
  grpc_get_tsi_client_certificate_request_type(client_certificate_request);
504
504
  options.cipher_suites = grpc_get_ssl_cipher_suites();
@@ -510,6 +510,7 @@ grpc_security_status grpc_ssl_tsi_server_handshaker_factory_init(
510
510
  options.crl_directory = crl_directory;
511
511
  options.crl_provider = std::move(crl_provider);
512
512
  options.send_client_ca_list = send_client_ca_list;
513
+ options.root_cert_info = std::move(root_cert_info);
513
514
  const tsi_result result =
514
515
  tsi_create_ssl_server_handshaker_factory_with_options(&options,
515
516
  handshaker_factory);
@@ -34,6 +34,7 @@
34
34
  #include "absl/status/status.h"
35
35
  #include "absl/strings/string_view.h"
36
36
  #include "src/core/credentials/transport/security_connector.h"
37
+ #include "src/core/credentials/transport/tls/spiffe_utils.h"
37
38
  #include "src/core/lib/iomgr/error.h"
38
39
  #include "src/core/tsi/ssl/key_logging/ssl_key_logging.h"
39
40
  #include "src/core/tsi/ssl_transport_security.h"
@@ -84,7 +85,8 @@ const char** ParseAlpnStringIntoArray(absl::string_view preferred_protocols,
84
85
 
85
86
  // Initialize TSI SSL server/client handshaker factory.
86
87
  grpc_security_status grpc_ssl_tsi_client_handshaker_factory_init(
87
- tsi_ssl_pem_key_cert_pair* key_cert_pair, const char* pem_root_certs,
88
+ tsi_ssl_pem_key_cert_pair* key_cert_pair,
89
+ std::shared_ptr<RootCertInfo> root_cert_info,
88
90
  bool skip_server_certificate_verification, tsi_tls_version min_tls_version,
89
91
  tsi_tls_version max_tls_version, tsi_ssl_session_cache* ssl_session_cache,
90
92
  tsi::TlsSessionKeyLoggerCache::TlsSessionKeyLogger* tls_session_key_logger,
@@ -94,7 +96,7 @@ grpc_security_status grpc_ssl_tsi_client_handshaker_factory_init(
94
96
 
95
97
  grpc_security_status grpc_ssl_tsi_server_handshaker_factory_init(
96
98
  tsi_ssl_pem_key_cert_pair* key_cert_pairs, size_t num_key_cert_pairs,
97
- const char* pem_root_certs,
99
+ std::shared_ptr<RootCertInfo> root_cert_info,
98
100
  grpc_ssl_client_certificate_request_type client_certificate_request,
99
101
  tsi_tls_version min_tls_version, tsi_tls_version max_tls_version,
100
102
  tsi::TlsSessionKeyLoggerCache::TlsSessionKeyLogger* tls_session_key_logger,
@@ -154,6 +154,7 @@ grpc_core::UniqueTypeName TlsServerCredentials::Type() {
154
154
  grpc_channel_credentials* grpc_tls_credentials_create(
155
155
  grpc_tls_credentials_options* options) {
156
156
  if (!CredentialOptionSanityCheck(options, true /* is_client */)) {
157
+ LOG(ERROR) << "TLS credentials options sanity check failed.";
157
158
  return nullptr;
158
159
  }
159
160
  return new TlsCredentials(
@@ -163,6 +164,7 @@ grpc_channel_credentials* grpc_tls_credentials_create(
163
164
  grpc_server_credentials* grpc_tls_server_credentials_create(
164
165
  grpc_tls_credentials_options* options) {
165
166
  if (!CredentialOptionSanityCheck(options, false /* is_client */)) {
167
+ LOG(ERROR) << "TLS server credentials options sanity check failed.";
166
168
  return nullptr;
167
169
  }
168
170
  return new TlsServerCredentials(