security_connector.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680
  1. /*
  2. *
  3. * Copyright 2015, Google Inc.
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions are
  8. * met:
  9. *
  10. * * Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * * Redistributions in binary form must reproduce the above
  13. * copyright notice, this list of conditions and the following disclaimer
  14. * in the documentation and/or other materials provided with the
  15. * distribution.
  16. * * Neither the name of Google Inc. nor the names of its
  17. * contributors may be used to endorse or promote products derived from
  18. * this software without specific prior written permission.
  19. *
  20. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  21. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  22. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  23. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  24. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  25. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  26. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  27. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  28. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  29. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  30. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31. *
  32. */
  33. #include "src/core/security/security_connector.h"
  34. #include <string.h>
  35. #include "src/core/security/credentials.h"
  36. #include "src/core/security/secure_endpoint.h"
  37. #include "src/core/security/security_context.h"
  38. #include "src/core/support/env.h"
  39. #include "src/core/support/file.h"
  40. #include "src/core/support/string.h"
  41. #include "src/core/transport/chttp2/alpn.h"
  42. #include <grpc/support/alloc.h>
  43. #include <grpc/support/host_port.h>
  44. #include <grpc/support/log.h>
  45. #include <grpc/support/slice_buffer.h>
  46. #include <grpc/support/string_util.h>
  47. #include "src/core/tsi/fake_transport_security.h"
  48. #include "src/core/tsi/ssl_transport_security.h"
  49. /* -- Constants. -- */
  50. #ifndef INSTALL_PREFIX
  51. static const char *installed_roots_path = "/usr/share/grpc/roots.pem";
  52. #else
  53. static const char *installed_roots_path =
  54. INSTALL_PREFIX "/share/grpc/roots.pem";
  55. #endif
  56. /* -- Cipher suites. -- */
  57. /* Defines the cipher suites that we accept by default. All these cipher suites
  58. are compliant with HTTP2. */
  59. #define GRPC_SSL_CIPHER_SUITES \
  60. "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-" \
  61. "SHA384:ECDHE-RSA-AES256-GCM-SHA384"
  62. static gpr_once cipher_suites_once = GPR_ONCE_INIT;
  63. static const char *cipher_suites = NULL;
  64. static void init_cipher_suites(void) {
  65. char *overridden = gpr_getenv("GRPC_SSL_CIPHER_SUITES");
  66. cipher_suites = overridden != NULL ? overridden : GRPC_SSL_CIPHER_SUITES;
  67. }
  68. static const char *ssl_cipher_suites(void) {
  69. gpr_once_init(&cipher_suites_once, init_cipher_suites);
  70. return cipher_suites;
  71. }
  72. /* -- Common methods. -- */
  73. /* Returns the first property with that name. */
  74. const tsi_peer_property *tsi_peer_get_property_by_name(const tsi_peer *peer,
  75. const char *name) {
  76. size_t i;
  77. if (peer == NULL) return NULL;
  78. for (i = 0; i < peer->property_count; i++) {
  79. const tsi_peer_property *property = &peer->properties[i];
  80. if (name == NULL && property->name == NULL) {
  81. return property;
  82. }
  83. if (name != NULL && property->name != NULL &&
  84. strcmp(property->name, name) == 0) {
  85. return property;
  86. }
  87. }
  88. return NULL;
  89. }
  90. grpc_security_status grpc_security_connector_create_handshaker(
  91. grpc_security_connector *sc, tsi_handshaker **handshaker) {
  92. if (sc == NULL || handshaker == NULL) return GRPC_SECURITY_ERROR;
  93. return sc->vtable->create_handshaker(sc, handshaker);
  94. }
  95. grpc_security_status grpc_security_connector_check_peer(
  96. grpc_security_connector *sc, tsi_peer peer, grpc_security_check_cb cb,
  97. void *user_data) {
  98. if (sc == NULL) {
  99. tsi_peer_destruct(&peer);
  100. return GRPC_SECURITY_ERROR;
  101. }
  102. return sc->vtable->check_peer(sc, peer, cb, user_data);
  103. }
  104. grpc_security_status grpc_channel_security_connector_check_call_host(
  105. grpc_channel_security_connector *sc, const char *host,
  106. grpc_security_check_cb cb, void *user_data) {
  107. if (sc == NULL || sc->check_call_host == NULL) return GRPC_SECURITY_ERROR;
  108. return sc->check_call_host(sc, host, cb, user_data);
  109. }
  110. #ifdef GRPC_SECURITY_CONNECTOR_REFCOUNT_DEBUG
  111. grpc_security_connector *grpc_security_connector_ref(
  112. grpc_security_connector *sc, const char *file, int line,
  113. const char *reason) {
  114. if (sc == NULL) return NULL;
  115. gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
  116. "SECURITY_CONNECTOR:%p ref %d -> %d %s", sc,
  117. (int)sc->refcount.count, (int)sc->refcount.count + 1, reason);
  118. #else
  119. grpc_security_connector *grpc_security_connector_ref(
  120. grpc_security_connector *sc) {
  121. if (sc == NULL) return NULL;
  122. #endif
  123. gpr_ref(&sc->refcount);
  124. return sc;
  125. }
  126. #ifdef GRPC_SECURITY_CONNECTOR_REFCOUNT_DEBUG
  127. void grpc_security_connector_unref(grpc_security_connector *sc,
  128. const char *file, int line,
  129. const char *reason) {
  130. if (sc == NULL) return;
  131. gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
  132. "SECURITY_CONNECTOR:%p unref %d -> %d %s", sc,
  133. (int)sc->refcount.count, (int)sc->refcount.count - 1, reason);
  134. #else
  135. void grpc_security_connector_unref(grpc_security_connector *sc) {
  136. if (sc == NULL) return;
  137. #endif
  138. if (gpr_unref(&sc->refcount)) sc->vtable->destroy(sc);
  139. }
  140. static void connector_pointer_arg_destroy(void *p) {
  141. GRPC_SECURITY_CONNECTOR_UNREF(p, "connector_pointer_arg");
  142. }
  143. static void *connector_pointer_arg_copy(void *p) {
  144. return GRPC_SECURITY_CONNECTOR_REF(p, "connector_pointer_arg");
  145. }
  146. grpc_arg grpc_security_connector_to_arg(grpc_security_connector *sc) {
  147. grpc_arg result;
  148. result.type = GRPC_ARG_POINTER;
  149. result.key = GRPC_SECURITY_CONNECTOR_ARG;
  150. result.value.pointer.destroy = connector_pointer_arg_destroy;
  151. result.value.pointer.copy = connector_pointer_arg_copy;
  152. result.value.pointer.p = sc;
  153. return result;
  154. }
  155. grpc_security_connector *grpc_security_connector_from_arg(const grpc_arg *arg) {
  156. if (strcmp(arg->key, GRPC_SECURITY_CONNECTOR_ARG)) return NULL;
  157. if (arg->type != GRPC_ARG_POINTER) {
  158. gpr_log(GPR_ERROR, "Invalid type %d for arg %s", arg->type,
  159. GRPC_SECURITY_CONNECTOR_ARG);
  160. return NULL;
  161. }
  162. return arg->value.pointer.p;
  163. }
  164. grpc_security_connector *grpc_find_security_connector_in_args(
  165. const grpc_channel_args *args) {
  166. size_t i;
  167. if (args == NULL) return NULL;
  168. for (i = 0; i < args->num_args; i++) {
  169. grpc_security_connector *sc =
  170. grpc_security_connector_from_arg(&args->args[i]);
  171. if (sc != NULL) return sc;
  172. }
  173. return NULL;
  174. }
  175. static int check_request_metadata_creds(grpc_credentials *creds) {
  176. if (creds != NULL && !grpc_credentials_has_request_metadata(creds)) {
  177. gpr_log(GPR_ERROR,
  178. "Incompatible credentials for channel security connector: needs to "
  179. "set request metadata.");
  180. return 0;
  181. }
  182. return 1;
  183. }
  184. /* -- Fake implementation. -- */
  185. typedef struct {
  186. grpc_channel_security_connector base;
  187. int call_host_check_is_async;
  188. } grpc_fake_channel_security_connector;
  189. static void fake_channel_destroy(grpc_security_connector *sc) {
  190. grpc_channel_security_connector *c = (grpc_channel_security_connector *)sc;
  191. grpc_credentials_unref(c->request_metadata_creds);
  192. GRPC_AUTH_CONTEXT_UNREF(sc->auth_context, "connector");
  193. gpr_free(sc);
  194. }
  195. static void fake_server_destroy(grpc_security_connector *sc) {
  196. GRPC_AUTH_CONTEXT_UNREF(sc->auth_context, "connector");
  197. gpr_free(sc);
  198. }
  199. static grpc_security_status fake_channel_create_handshaker(
  200. grpc_security_connector *sc, tsi_handshaker **handshaker) {
  201. *handshaker = tsi_create_fake_handshaker(1);
  202. return GRPC_SECURITY_OK;
  203. }
  204. static grpc_security_status fake_server_create_handshaker(
  205. grpc_security_connector *sc, tsi_handshaker **handshaker) {
  206. *handshaker = tsi_create_fake_handshaker(0);
  207. return GRPC_SECURITY_OK;
  208. }
  209. static grpc_security_status fake_check_peer(grpc_security_connector *sc,
  210. tsi_peer peer,
  211. grpc_security_check_cb cb,
  212. void *user_data) {
  213. const char *prop_name;
  214. grpc_security_status status = GRPC_SECURITY_OK;
  215. if (peer.property_count != 1) {
  216. gpr_log(GPR_ERROR, "Fake peers should only have 1 property.");
  217. status = GRPC_SECURITY_ERROR;
  218. goto end;
  219. }
  220. prop_name = peer.properties[0].name;
  221. if (prop_name == NULL ||
  222. strcmp(prop_name, TSI_CERTIFICATE_TYPE_PEER_PROPERTY)) {
  223. gpr_log(GPR_ERROR, "Unexpected property in fake peer: %s.",
  224. prop_name == NULL ? "<EMPTY>" : prop_name);
  225. status = GRPC_SECURITY_ERROR;
  226. goto end;
  227. }
  228. if (strncmp(peer.properties[0].value.data, TSI_FAKE_CERTIFICATE_TYPE,
  229. peer.properties[0].value.length)) {
  230. gpr_log(GPR_ERROR, "Invalid value for cert type property.");
  231. status = GRPC_SECURITY_ERROR;
  232. goto end;
  233. }
  234. GRPC_AUTH_CONTEXT_UNREF(sc->auth_context, "connector");
  235. sc->auth_context = grpc_auth_context_create(NULL);
  236. grpc_auth_context_add_cstring_property(
  237. sc->auth_context, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME,
  238. GRPC_FAKE_TRANSPORT_SECURITY_TYPE);
  239. end:
  240. tsi_peer_destruct(&peer);
  241. return status;
  242. }
  243. static grpc_security_status fake_channel_check_call_host(
  244. grpc_channel_security_connector *sc, const char *host,
  245. grpc_security_check_cb cb, void *user_data) {
  246. grpc_fake_channel_security_connector *c =
  247. (grpc_fake_channel_security_connector *)sc;
  248. if (c->call_host_check_is_async) {
  249. cb(user_data, GRPC_SECURITY_OK);
  250. return GRPC_SECURITY_PENDING;
  251. } else {
  252. return GRPC_SECURITY_OK;
  253. }
  254. }
  255. static grpc_security_connector_vtable fake_channel_vtable = {
  256. fake_channel_destroy, fake_channel_create_handshaker, fake_check_peer};
  257. static grpc_security_connector_vtable fake_server_vtable = {
  258. fake_server_destroy, fake_server_create_handshaker, fake_check_peer};
  259. grpc_channel_security_connector *grpc_fake_channel_security_connector_create(
  260. grpc_credentials *request_metadata_creds, int call_host_check_is_async) {
  261. grpc_fake_channel_security_connector *c =
  262. gpr_malloc(sizeof(grpc_fake_channel_security_connector));
  263. memset(c, 0, sizeof(grpc_fake_channel_security_connector));
  264. gpr_ref_init(&c->base.base.refcount, 1);
  265. c->base.base.is_client_side = 1;
  266. c->base.base.url_scheme = GRPC_FAKE_SECURITY_URL_SCHEME;
  267. c->base.base.vtable = &fake_channel_vtable;
  268. GPR_ASSERT(check_request_metadata_creds(request_metadata_creds));
  269. c->base.request_metadata_creds = grpc_credentials_ref(request_metadata_creds);
  270. c->base.check_call_host = fake_channel_check_call_host;
  271. c->call_host_check_is_async = call_host_check_is_async;
  272. return &c->base;
  273. }
  274. grpc_security_connector *grpc_fake_server_security_connector_create(void) {
  275. grpc_security_connector *c = gpr_malloc(sizeof(grpc_security_connector));
  276. memset(c, 0, sizeof(grpc_security_connector));
  277. gpr_ref_init(&c->refcount, 1);
  278. c->is_client_side = 0;
  279. c->vtable = &fake_server_vtable;
  280. c->url_scheme = GRPC_FAKE_SECURITY_URL_SCHEME;
  281. return c;
  282. }
  283. /* --- Ssl implementation. --- */
  284. typedef struct {
  285. grpc_channel_security_connector base;
  286. tsi_ssl_handshaker_factory *handshaker_factory;
  287. char *target_name;
  288. char *overridden_target_name;
  289. tsi_peer peer;
  290. } grpc_ssl_channel_security_connector;
  291. typedef struct {
  292. grpc_security_connector base;
  293. tsi_ssl_handshaker_factory *handshaker_factory;
  294. } grpc_ssl_server_security_connector;
  295. static void ssl_channel_destroy(grpc_security_connector *sc) {
  296. grpc_ssl_channel_security_connector *c =
  297. (grpc_ssl_channel_security_connector *)sc;
  298. grpc_credentials_unref(c->base.request_metadata_creds);
  299. if (c->handshaker_factory != NULL) {
  300. tsi_ssl_handshaker_factory_destroy(c->handshaker_factory);
  301. }
  302. if (c->target_name != NULL) gpr_free(c->target_name);
  303. if (c->overridden_target_name != NULL) gpr_free(c->overridden_target_name);
  304. tsi_peer_destruct(&c->peer);
  305. GRPC_AUTH_CONTEXT_UNREF(sc->auth_context, "connector");
  306. gpr_free(sc);
  307. }
  308. static void ssl_server_destroy(grpc_security_connector *sc) {
  309. grpc_ssl_server_security_connector *c =
  310. (grpc_ssl_server_security_connector *)sc;
  311. if (c->handshaker_factory != NULL) {
  312. tsi_ssl_handshaker_factory_destroy(c->handshaker_factory);
  313. }
  314. GRPC_AUTH_CONTEXT_UNREF(sc->auth_context, "connector");
  315. gpr_free(sc);
  316. }
  317. static grpc_security_status ssl_create_handshaker(
  318. tsi_ssl_handshaker_factory *handshaker_factory, int is_client,
  319. const char *peer_name, tsi_handshaker **handshaker) {
  320. tsi_result result = TSI_OK;
  321. if (handshaker_factory == NULL) return GRPC_SECURITY_ERROR;
  322. result = tsi_ssl_handshaker_factory_create_handshaker(
  323. handshaker_factory, is_client ? peer_name : NULL, handshaker);
  324. if (result != TSI_OK) {
  325. gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.",
  326. tsi_result_to_string(result));
  327. return GRPC_SECURITY_ERROR;
  328. }
  329. return GRPC_SECURITY_OK;
  330. }
  331. static grpc_security_status ssl_channel_create_handshaker(
  332. grpc_security_connector *sc, tsi_handshaker **handshaker) {
  333. grpc_ssl_channel_security_connector *c =
  334. (grpc_ssl_channel_security_connector *)sc;
  335. return ssl_create_handshaker(c->handshaker_factory, 1,
  336. c->overridden_target_name != NULL
  337. ? c->overridden_target_name
  338. : c->target_name,
  339. handshaker);
  340. }
  341. static grpc_security_status ssl_server_create_handshaker(
  342. grpc_security_connector *sc, tsi_handshaker **handshaker) {
  343. grpc_ssl_server_security_connector *c =
  344. (grpc_ssl_server_security_connector *)sc;
  345. return ssl_create_handshaker(c->handshaker_factory, 0, NULL, handshaker);
  346. }
  347. static int ssl_host_matches_name(const tsi_peer *peer, const char *peer_name) {
  348. char *allocated_name = NULL;
  349. int r;
  350. if (strchr(peer_name, ':') != NULL) {
  351. char *ignored_port;
  352. gpr_split_host_port(peer_name, &allocated_name, &ignored_port);
  353. gpr_free(ignored_port);
  354. peer_name = allocated_name;
  355. if (!peer_name) return 0;
  356. }
  357. r = tsi_ssl_peer_matches_name(peer, peer_name);
  358. gpr_free(allocated_name);
  359. return r;
  360. }
  361. grpc_auth_context *tsi_ssl_peer_to_auth_context(const tsi_peer *peer) {
  362. size_t i;
  363. grpc_auth_context *ctx = NULL;
  364. const char *peer_identity_property_name = NULL;
  365. /* The caller has checked the certificate type property. */
  366. GPR_ASSERT(peer->property_count >= 1);
  367. ctx = grpc_auth_context_create(NULL);
  368. grpc_auth_context_add_cstring_property(
  369. ctx, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME,
  370. GRPC_SSL_TRANSPORT_SECURITY_TYPE);
  371. for (i = 0; i < peer->property_count; i++) {
  372. const tsi_peer_property *prop = &peer->properties[i];
  373. if (prop->name == NULL) continue;
  374. if (strcmp(prop->name, TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY) == 0) {
  375. /* If there is no subject alt name, have the CN as the identity. */
  376. if (peer_identity_property_name == NULL) {
  377. peer_identity_property_name = GRPC_X509_CN_PROPERTY_NAME;
  378. }
  379. grpc_auth_context_add_property(ctx, GRPC_X509_CN_PROPERTY_NAME,
  380. prop->value.data, prop->value.length);
  381. } else if (strcmp(prop->name,
  382. TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY) == 0) {
  383. peer_identity_property_name = GRPC_X509_SAN_PROPERTY_NAME;
  384. grpc_auth_context_add_property(ctx, GRPC_X509_SAN_PROPERTY_NAME,
  385. prop->value.data, prop->value.length);
  386. }
  387. }
  388. if (peer_identity_property_name != NULL) {
  389. GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name(
  390. ctx, peer_identity_property_name) == 1);
  391. }
  392. return ctx;
  393. }
  394. static grpc_security_status ssl_check_peer(grpc_security_connector *sc,
  395. const char *peer_name,
  396. const tsi_peer *peer) {
  397. /* Check the ALPN. */
  398. const tsi_peer_property *p =
  399. tsi_peer_get_property_by_name(peer, TSI_SSL_ALPN_SELECTED_PROTOCOL);
  400. if (p == NULL) {
  401. gpr_log(GPR_ERROR, "Missing selected ALPN property.");
  402. return GRPC_SECURITY_ERROR;
  403. }
  404. if (!grpc_chttp2_is_alpn_version_supported(p->value.data, p->value.length)) {
  405. gpr_log(GPR_ERROR, "Invalid ALPN value.");
  406. return GRPC_SECURITY_ERROR;
  407. }
  408. /* Check the peer name if specified. */
  409. if (peer_name != NULL && !ssl_host_matches_name(peer, peer_name)) {
  410. gpr_log(GPR_ERROR, "Peer name %s is not in peer certificate", peer_name);
  411. return GRPC_SECURITY_ERROR;
  412. }
  413. if (sc->auth_context != NULL) {
  414. GRPC_AUTH_CONTEXT_UNREF(sc->auth_context, "connector");
  415. }
  416. sc->auth_context = tsi_ssl_peer_to_auth_context(peer);
  417. return GRPC_SECURITY_OK;
  418. }
  419. static grpc_security_status ssl_channel_check_peer(grpc_security_connector *sc,
  420. tsi_peer peer,
  421. grpc_security_check_cb cb,
  422. void *user_data) {
  423. grpc_ssl_channel_security_connector *c =
  424. (grpc_ssl_channel_security_connector *)sc;
  425. grpc_security_status status;
  426. tsi_peer_destruct(&c->peer);
  427. c->peer = peer;
  428. status = ssl_check_peer(sc, c->overridden_target_name != NULL
  429. ? c->overridden_target_name
  430. : c->target_name,
  431. &peer);
  432. return status;
  433. }
  434. static grpc_security_status ssl_server_check_peer(grpc_security_connector *sc,
  435. tsi_peer peer,
  436. grpc_security_check_cb cb,
  437. void *user_data) {
  438. grpc_security_status status = ssl_check_peer(sc, NULL, &peer);
  439. tsi_peer_destruct(&peer);
  440. return status;
  441. }
  442. static grpc_security_status ssl_channel_check_call_host(
  443. grpc_channel_security_connector *sc, const char *host,
  444. grpc_security_check_cb cb, void *user_data) {
  445. grpc_ssl_channel_security_connector *c =
  446. (grpc_ssl_channel_security_connector *)sc;
  447. if (ssl_host_matches_name(&c->peer, host)) return GRPC_SECURITY_OK;
  448. /* If the target name was overridden, then the original target_name was
  449. 'checked' transitively during the previous peer check at the end of the
  450. handshake. */
  451. if (c->overridden_target_name != NULL && strcmp(host, c->target_name) == 0) {
  452. return GRPC_SECURITY_OK;
  453. } else {
  454. return GRPC_SECURITY_ERROR;
  455. }
  456. }
  457. static grpc_security_connector_vtable ssl_channel_vtable = {
  458. ssl_channel_destroy, ssl_channel_create_handshaker, ssl_channel_check_peer};
  459. static grpc_security_connector_vtable ssl_server_vtable = {
  460. ssl_server_destroy, ssl_server_create_handshaker, ssl_server_check_peer};
  461. static gpr_slice default_pem_root_certs;
  462. static void init_default_pem_root_certs(void) {
  463. /* First try to load the roots from the environment. */
  464. char *default_root_certs_path =
  465. gpr_getenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR);
  466. if (default_root_certs_path == NULL) {
  467. default_pem_root_certs = gpr_empty_slice();
  468. } else {
  469. default_pem_root_certs = gpr_load_file(default_root_certs_path, 0, NULL);
  470. gpr_free(default_root_certs_path);
  471. }
  472. /* Fall back to installed certs if needed. */
  473. if (GPR_SLICE_IS_EMPTY(default_pem_root_certs)) {
  474. default_pem_root_certs = gpr_load_file(installed_roots_path, 0, NULL);
  475. }
  476. }
  477. size_t grpc_get_default_ssl_roots(const unsigned char **pem_root_certs) {
  478. /* TODO(jboeuf@google.com): Maybe revisit the approach which consists in
  479. loading all the roots once for the lifetime of the process. */
  480. static gpr_once once = GPR_ONCE_INIT;
  481. gpr_once_init(&once, init_default_pem_root_certs);
  482. *pem_root_certs = GPR_SLICE_START_PTR(default_pem_root_certs);
  483. return GPR_SLICE_LENGTH(default_pem_root_certs);
  484. }
  485. grpc_security_status grpc_ssl_channel_security_connector_create(
  486. grpc_credentials *request_metadata_creds, const grpc_ssl_config *config,
  487. const char *target_name, const char *overridden_target_name,
  488. grpc_channel_security_connector **sc) {
  489. size_t num_alpn_protocols = grpc_chttp2_num_alpn_versions();
  490. const unsigned char **alpn_protocol_strings =
  491. gpr_malloc(sizeof(const char *) * num_alpn_protocols);
  492. unsigned char *alpn_protocol_string_lengths =
  493. gpr_malloc(sizeof(unsigned char) * num_alpn_protocols);
  494. tsi_result result = TSI_OK;
  495. grpc_ssl_channel_security_connector *c;
  496. size_t i;
  497. const unsigned char *pem_root_certs;
  498. size_t pem_root_certs_size;
  499. char *port;
  500. for (i = 0; i < num_alpn_protocols; i++) {
  501. alpn_protocol_strings[i] =
  502. (const unsigned char *)grpc_chttp2_get_alpn_version_index(i);
  503. alpn_protocol_string_lengths[i] =
  504. (unsigned char)strlen(grpc_chttp2_get_alpn_version_index(i));
  505. }
  506. if (config == NULL || target_name == NULL) {
  507. gpr_log(GPR_ERROR, "An ssl channel needs a config and a target name.");
  508. goto error;
  509. }
  510. if (!check_request_metadata_creds(request_metadata_creds)) {
  511. goto error;
  512. }
  513. if (config->pem_root_certs == NULL) {
  514. pem_root_certs_size = grpc_get_default_ssl_roots(&pem_root_certs);
  515. if (pem_root_certs == NULL || pem_root_certs_size == 0) {
  516. gpr_log(GPR_ERROR, "Could not get default pem root certs.");
  517. goto error;
  518. }
  519. } else {
  520. pem_root_certs = config->pem_root_certs;
  521. pem_root_certs_size = config->pem_root_certs_size;
  522. }
  523. c = gpr_malloc(sizeof(grpc_ssl_channel_security_connector));
  524. memset(c, 0, sizeof(grpc_ssl_channel_security_connector));
  525. gpr_ref_init(&c->base.base.refcount, 1);
  526. c->base.base.vtable = &ssl_channel_vtable;
  527. c->base.base.is_client_side = 1;
  528. c->base.base.url_scheme = GRPC_SSL_URL_SCHEME;
  529. c->base.request_metadata_creds = grpc_credentials_ref(request_metadata_creds);
  530. c->base.check_call_host = ssl_channel_check_call_host;
  531. gpr_split_host_port(target_name, &c->target_name, &port);
  532. gpr_free(port);
  533. if (overridden_target_name != NULL) {
  534. c->overridden_target_name = gpr_strdup(overridden_target_name);
  535. }
  536. result = tsi_create_ssl_client_handshaker_factory(
  537. config->pem_private_key, config->pem_private_key_size,
  538. config->pem_cert_chain, config->pem_cert_chain_size, pem_root_certs,
  539. pem_root_certs_size, ssl_cipher_suites(), alpn_protocol_strings,
  540. alpn_protocol_string_lengths, (uint16_t)num_alpn_protocols,
  541. &c->handshaker_factory);
  542. if (result != TSI_OK) {
  543. gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
  544. tsi_result_to_string(result));
  545. ssl_channel_destroy(&c->base.base);
  546. *sc = NULL;
  547. goto error;
  548. }
  549. *sc = &c->base;
  550. gpr_free(alpn_protocol_strings);
  551. gpr_free(alpn_protocol_string_lengths);
  552. return GRPC_SECURITY_OK;
  553. error:
  554. gpr_free(alpn_protocol_strings);
  555. gpr_free(alpn_protocol_string_lengths);
  556. return GRPC_SECURITY_ERROR;
  557. }
  558. grpc_security_status grpc_ssl_server_security_connector_create(
  559. const grpc_ssl_server_config *config, grpc_security_connector **sc) {
  560. size_t num_alpn_protocols = grpc_chttp2_num_alpn_versions();
  561. const unsigned char **alpn_protocol_strings =
  562. gpr_malloc(sizeof(const char *) * num_alpn_protocols);
  563. unsigned char *alpn_protocol_string_lengths =
  564. gpr_malloc(sizeof(unsigned char) * num_alpn_protocols);
  565. tsi_result result = TSI_OK;
  566. grpc_ssl_server_security_connector *c;
  567. size_t i;
  568. for (i = 0; i < num_alpn_protocols; i++) {
  569. alpn_protocol_strings[i] =
  570. (const unsigned char *)grpc_chttp2_get_alpn_version_index(i);
  571. alpn_protocol_string_lengths[i] =
  572. (unsigned char)strlen(grpc_chttp2_get_alpn_version_index(i));
  573. }
  574. if (config == NULL || config->num_key_cert_pairs == 0) {
  575. gpr_log(GPR_ERROR, "An SSL server needs a key and a cert.");
  576. goto error;
  577. }
  578. c = gpr_malloc(sizeof(grpc_ssl_server_security_connector));
  579. memset(c, 0, sizeof(grpc_ssl_server_security_connector));
  580. gpr_ref_init(&c->base.refcount, 1);
  581. c->base.url_scheme = GRPC_SSL_URL_SCHEME;
  582. c->base.vtable = &ssl_server_vtable;
  583. result = tsi_create_ssl_server_handshaker_factory(
  584. (const unsigned char **)config->pem_private_keys,
  585. config->pem_private_keys_sizes,
  586. (const unsigned char **)config->pem_cert_chains,
  587. config->pem_cert_chains_sizes, config->num_key_cert_pairs,
  588. config->pem_root_certs, config->pem_root_certs_size,
  589. config->force_client_auth, ssl_cipher_suites(), alpn_protocol_strings,
  590. alpn_protocol_string_lengths, (uint16_t)num_alpn_protocols,
  591. &c->handshaker_factory);
  592. if (result != TSI_OK) {
  593. gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
  594. tsi_result_to_string(result));
  595. ssl_server_destroy(&c->base);
  596. *sc = NULL;
  597. goto error;
  598. }
  599. *sc = &c->base;
  600. gpr_free(alpn_protocol_strings);
  601. gpr_free(alpn_protocol_string_lengths);
  602. return GRPC_SECURITY_OK;
  603. error:
  604. gpr_free(alpn_protocol_strings);
  605. gpr_free(alpn_protocol_string_lengths);
  606. return GRPC_SECURITY_ERROR;
  607. }