|  | @@ -81,23 +81,13 @@
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  /* --- Structure definitions. ---*/
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -struct tsi_ssl_handshaker_factory {
 | 
	
		
			
				|  |  | -  tsi_result (*create_handshaker)(tsi_ssl_handshaker_factory *self,
 | 
	
		
			
				|  |  | -                                  const char *server_name_indication,
 | 
	
		
			
				|  |  | -                                  tsi_handshaker **handshaker);
 | 
	
		
			
				|  |  | -  void (*destroy)(tsi_ssl_handshaker_factory *self);
 | 
	
		
			
				|  |  | -};
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -typedef struct {
 | 
	
		
			
				|  |  | -  tsi_ssl_handshaker_factory base;
 | 
	
		
			
				|  |  | +struct tsi_ssl_client_handshaker_factory {
 | 
	
		
			
				|  |  |    SSL_CTX *ssl_context;
 | 
	
		
			
				|  |  |    unsigned char *alpn_protocol_list;
 | 
	
		
			
				|  |  |    size_t alpn_protocol_list_length;
 | 
	
		
			
				|  |  | -} tsi_ssl_client_handshaker_factory;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -typedef struct {
 | 
	
		
			
				|  |  | -  tsi_ssl_handshaker_factory base;
 | 
	
		
			
				|  |  | +};
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +struct tsi_ssl_server_handshaker_factory {
 | 
	
		
			
				|  |  |    /* Several contexts to support SNI.
 | 
	
		
			
				|  |  |       The tsi_peer array contains the subject names of the server certificates
 | 
	
		
			
				|  |  |       associated with the contexts at the same index.  */
 | 
	
	
		
			
				|  | @@ -106,7 +96,7 @@ typedef struct {
 | 
	
		
			
				|  |  |    size_t ssl_context_count;
 | 
	
		
			
				|  |  |    unsigned char *alpn_protocol_list;
 | 
	
		
			
				|  |  |    size_t alpn_protocol_list_length;
 | 
	
		
			
				|  |  | -} tsi_ssl_server_handshaker_factory;
 | 
	
		
			
				|  |  | +};
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  typedef struct {
 | 
	
		
			
				|  |  |    tsi_handshaker base;
 | 
	
	
		
			
				|  | @@ -1053,18 +1043,6 @@ static const tsi_handshaker_vtable handshaker_vtable = {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  /* --- tsi_ssl_handshaker_factory common methods. --- */
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -tsi_result tsi_ssl_handshaker_factory_create_handshaker(
 | 
	
		
			
				|  |  | -    tsi_ssl_handshaker_factory *self, const char *server_name_indication,
 | 
	
		
			
				|  |  | -    tsi_handshaker **handshaker) {
 | 
	
		
			
				|  |  | -  if (self == NULL || handshaker == NULL) return TSI_INVALID_ARGUMENT;
 | 
	
		
			
				|  |  | -  return self->create_handshaker(self, server_name_indication, handshaker);
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -void tsi_ssl_handshaker_factory_destroy(tsi_ssl_handshaker_factory *self) {
 | 
	
		
			
				|  |  | -  if (self == NULL) return;
 | 
	
		
			
				|  |  | -  self->destroy(self);
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |  static tsi_result create_tsi_ssl_handshaker(SSL_CTX *ctx, int is_client,
 | 
	
		
			
				|  |  |                                              const char *server_name_indication,
 | 
	
		
			
				|  |  |                                              tsi_handshaker **handshaker) {
 | 
	
	
		
			
				|  | @@ -1152,24 +1130,20 @@ static int select_protocol_list(const unsigned char **out,
 | 
	
		
			
				|  |  |    return SSL_TLSEXT_ERR_NOACK;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -/* --- tsi_ssl__client_handshaker_factory methods implementation. --- */
 | 
	
		
			
				|  |  | +/* --- tsi_ssl_client_handshaker_factory methods implementation. --- */
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -static tsi_result ssl_client_handshaker_factory_create_handshaker(
 | 
	
		
			
				|  |  | -    tsi_ssl_handshaker_factory *self, const char *server_name_indication,
 | 
	
		
			
				|  |  | +tsi_result tsi_ssl_client_handshaker_factory_create_handshaker(
 | 
	
		
			
				|  |  | +    tsi_ssl_client_handshaker_factory *self, const char *server_name_indication,
 | 
	
		
			
				|  |  |      tsi_handshaker **handshaker) {
 | 
	
		
			
				|  |  | -  tsi_ssl_client_handshaker_factory *impl =
 | 
	
		
			
				|  |  | -      (tsi_ssl_client_handshaker_factory *)self;
 | 
	
		
			
				|  |  | -  return create_tsi_ssl_handshaker(impl->ssl_context, 1, server_name_indication,
 | 
	
		
			
				|  |  | +  return create_tsi_ssl_handshaker(self->ssl_context, 1, server_name_indication,
 | 
	
		
			
				|  |  |                                     handshaker);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -static void ssl_client_handshaker_factory_destroy(
 | 
	
		
			
				|  |  | -    tsi_ssl_handshaker_factory *self) {
 | 
	
		
			
				|  |  | -  tsi_ssl_client_handshaker_factory *impl =
 | 
	
		
			
				|  |  | -      (tsi_ssl_client_handshaker_factory *)self;
 | 
	
		
			
				|  |  | -  if (impl->ssl_context != NULL) SSL_CTX_free(impl->ssl_context);
 | 
	
		
			
				|  |  | -  if (impl->alpn_protocol_list != NULL) gpr_free(impl->alpn_protocol_list);
 | 
	
		
			
				|  |  | -  gpr_free(impl);
 | 
	
		
			
				|  |  | +void tsi_ssl_client_handshaker_factory_destroy(
 | 
	
		
			
				|  |  | +    tsi_ssl_client_handshaker_factory *self) {
 | 
	
		
			
				|  |  | +  if (self->ssl_context != NULL) SSL_CTX_free(self->ssl_context);
 | 
	
		
			
				|  |  | +  if (self->alpn_protocol_list != NULL) gpr_free(self->alpn_protocol_list);
 | 
	
		
			
				|  |  | +  gpr_free(self);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  static int client_handshaker_factory_npn_callback(SSL *ssl, unsigned char **out,
 | 
	
	
		
			
				|  | @@ -1186,36 +1160,29 @@ static int client_handshaker_factory_npn_callback(SSL *ssl, unsigned char **out,
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  /* --- tsi_ssl_server_handshaker_factory methods implementation. --- */
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -static tsi_result ssl_server_handshaker_factory_create_handshaker(
 | 
	
		
			
				|  |  | -    tsi_ssl_handshaker_factory *self, const char *server_name_indication,
 | 
	
		
			
				|  |  | -    tsi_handshaker **handshaker) {
 | 
	
		
			
				|  |  | -  tsi_ssl_server_handshaker_factory *impl =
 | 
	
		
			
				|  |  | -      (tsi_ssl_server_handshaker_factory *)self;
 | 
	
		
			
				|  |  | -  if (impl->ssl_context_count == 0 || server_name_indication != NULL) {
 | 
	
		
			
				|  |  | -    return TSI_INVALID_ARGUMENT;
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | +tsi_result tsi_ssl_server_handshaker_factory_create_handshaker(
 | 
	
		
			
				|  |  | +    tsi_ssl_server_handshaker_factory *self, tsi_handshaker **handshaker) {
 | 
	
		
			
				|  |  | +  if (self->ssl_context_count == 0) return TSI_INVALID_ARGUMENT;
 | 
	
		
			
				|  |  |    /* Create the handshaker with the first context. We will switch if needed
 | 
	
		
			
				|  |  |       because of SNI in ssl_server_handshaker_factory_servername_callback.  */
 | 
	
		
			
				|  |  | -  return create_tsi_ssl_handshaker(impl->ssl_contexts[0], 0, NULL, handshaker);
 | 
	
		
			
				|  |  | +  return create_tsi_ssl_handshaker(self->ssl_contexts[0], 0, NULL, handshaker);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -static void ssl_server_handshaker_factory_destroy(
 | 
	
		
			
				|  |  | -    tsi_ssl_handshaker_factory *self) {
 | 
	
		
			
				|  |  | -  tsi_ssl_server_handshaker_factory *impl =
 | 
	
		
			
				|  |  | -      (tsi_ssl_server_handshaker_factory *)self;
 | 
	
		
			
				|  |  | +void tsi_ssl_server_handshaker_factory_destroy(
 | 
	
		
			
				|  |  | +    tsi_ssl_server_handshaker_factory *self) {
 | 
	
		
			
				|  |  |    size_t i;
 | 
	
		
			
				|  |  | -  for (i = 0; i < impl->ssl_context_count; i++) {
 | 
	
		
			
				|  |  | -    if (impl->ssl_contexts[i] != NULL) {
 | 
	
		
			
				|  |  | -      SSL_CTX_free(impl->ssl_contexts[i]);
 | 
	
		
			
				|  |  | -      tsi_peer_destruct(&impl->ssl_context_x509_subject_names[i]);
 | 
	
		
			
				|  |  | +  for (i = 0; i < self->ssl_context_count; i++) {
 | 
	
		
			
				|  |  | +    if (self->ssl_contexts[i] != NULL) {
 | 
	
		
			
				|  |  | +      SSL_CTX_free(self->ssl_contexts[i]);
 | 
	
		
			
				|  |  | +      tsi_peer_destruct(&self->ssl_context_x509_subject_names[i]);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | -  if (impl->ssl_contexts != NULL) gpr_free(impl->ssl_contexts);
 | 
	
		
			
				|  |  | -  if (impl->ssl_context_x509_subject_names != NULL) {
 | 
	
		
			
				|  |  | -    gpr_free(impl->ssl_context_x509_subject_names);
 | 
	
		
			
				|  |  | +  if (self->ssl_contexts != NULL) gpr_free(self->ssl_contexts);
 | 
	
		
			
				|  |  | +  if (self->ssl_context_x509_subject_names != NULL) {
 | 
	
		
			
				|  |  | +    gpr_free(self->ssl_context_x509_subject_names);
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | -  if (impl->alpn_protocol_list != NULL) gpr_free(impl->alpn_protocol_list);
 | 
	
		
			
				|  |  | -  gpr_free(impl);
 | 
	
		
			
				|  |  | +  if (self->alpn_protocol_list != NULL) gpr_free(self->alpn_protocol_list);
 | 
	
		
			
				|  |  | +  gpr_free(self);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  static int does_entry_match_name(const char *entry, size_t entry_length,
 | 
	
	
		
			
				|  | @@ -1317,7 +1284,7 @@ tsi_result tsi_create_ssl_client_handshaker_factory(
 | 
	
		
			
				|  |  |      const unsigned char *pem_root_certs, size_t pem_root_certs_size,
 | 
	
		
			
				|  |  |      const char *cipher_list, const unsigned char **alpn_protocols,
 | 
	
		
			
				|  |  |      const unsigned char *alpn_protocols_lengths, uint16_t num_alpn_protocols,
 | 
	
		
			
				|  |  | -    tsi_ssl_handshaker_factory **factory) {
 | 
	
		
			
				|  |  | +    tsi_ssl_client_handshaker_factory **factory) {
 | 
	
		
			
				|  |  |    SSL_CTX *ssl_context = NULL;
 | 
	
		
			
				|  |  |    tsi_ssl_client_handshaker_factory *impl = NULL;
 | 
	
		
			
				|  |  |    tsi_result result = TSI_OK;
 | 
	
	
		
			
				|  | @@ -1373,16 +1340,13 @@ tsi_result tsi_create_ssl_client_handshaker_factory(
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |    } while (0);
 | 
	
		
			
				|  |  |    if (result != TSI_OK) {
 | 
	
		
			
				|  |  | -    ssl_client_handshaker_factory_destroy(&impl->base);
 | 
	
		
			
				|  |  | +    tsi_ssl_client_handshaker_factory_destroy(impl);
 | 
	
		
			
				|  |  |      return result;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |    SSL_CTX_set_verify(ssl_context, SSL_VERIFY_PEER, NULL);
 | 
	
		
			
				|  |  |    /* TODO(jboeuf): Add revocation verification. */
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  impl->base.create_handshaker =
 | 
	
		
			
				|  |  | -      ssl_client_handshaker_factory_create_handshaker;
 | 
	
		
			
				|  |  | -  impl->base.destroy = ssl_client_handshaker_factory_destroy;
 | 
	
		
			
				|  |  | -  *factory = &impl->base;
 | 
	
		
			
				|  |  | +  *factory = impl;
 | 
	
		
			
				|  |  |    return TSI_OK;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -1394,7 +1358,7 @@ tsi_result tsi_create_ssl_server_handshaker_factory(
 | 
	
		
			
				|  |  |      size_t pem_client_root_certs_size, int force_client_auth,
 | 
	
		
			
				|  |  |      const char *cipher_list, const unsigned char **alpn_protocols,
 | 
	
		
			
				|  |  |      const unsigned char *alpn_protocols_lengths, uint16_t num_alpn_protocols,
 | 
	
		
			
				|  |  | -    tsi_ssl_handshaker_factory **factory) {
 | 
	
		
			
				|  |  | +    tsi_ssl_server_handshaker_factory **factory) {
 | 
	
		
			
				|  |  |    return tsi_create_ssl_server_handshaker_factory_ex(
 | 
	
		
			
				|  |  |        pem_private_keys, pem_private_keys_sizes, pem_cert_chains,
 | 
	
		
			
				|  |  |        pem_cert_chains_sizes, key_cert_pair_count, pem_client_root_certs,
 | 
	
	
		
			
				|  | @@ -1414,7 +1378,7 @@ tsi_result tsi_create_ssl_server_handshaker_factory_ex(
 | 
	
		
			
				|  |  |      tsi_client_certificate_request_type client_certificate_request,
 | 
	
		
			
				|  |  |      const char *cipher_list, const unsigned char **alpn_protocols,
 | 
	
		
			
				|  |  |      const unsigned char *alpn_protocols_lengths, uint16_t num_alpn_protocols,
 | 
	
		
			
				|  |  | -    tsi_ssl_handshaker_factory **factory) {
 | 
	
		
			
				|  |  | +    tsi_ssl_server_handshaker_factory **factory) {
 | 
	
		
			
				|  |  |    tsi_ssl_server_handshaker_factory *impl = NULL;
 | 
	
		
			
				|  |  |    tsi_result result = TSI_OK;
 | 
	
		
			
				|  |  |    size_t i = 0;
 | 
	
	
		
			
				|  | @@ -1429,15 +1393,12 @@ tsi_result tsi_create_ssl_server_handshaker_factory_ex(
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    impl = gpr_zalloc(sizeof(*impl));
 | 
	
		
			
				|  |  | -  impl->base.create_handshaker =
 | 
	
		
			
				|  |  | -      ssl_server_handshaker_factory_create_handshaker;
 | 
	
		
			
				|  |  | -  impl->base.destroy = ssl_server_handshaker_factory_destroy;
 | 
	
		
			
				|  |  |    impl->ssl_contexts = gpr_zalloc(key_cert_pair_count * sizeof(SSL_CTX *));
 | 
	
		
			
				|  |  |    impl->ssl_context_x509_subject_names =
 | 
	
		
			
				|  |  |        gpr_zalloc(key_cert_pair_count * sizeof(tsi_peer));
 | 
	
		
			
				|  |  |    if (impl->ssl_contexts == NULL ||
 | 
	
		
			
				|  |  |        impl->ssl_context_x509_subject_names == NULL) {
 | 
	
		
			
				|  |  | -    tsi_ssl_handshaker_factory_destroy(&impl->base);
 | 
	
		
			
				|  |  | +    tsi_ssl_server_handshaker_factory_destroy(impl);
 | 
	
		
			
				|  |  |      return TSI_OUT_OF_RESOURCES;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |    impl->ssl_context_count = key_cert_pair_count;
 | 
	
	
		
			
				|  | @@ -1447,7 +1408,7 @@ tsi_result tsi_create_ssl_server_handshaker_factory_ex(
 | 
	
		
			
				|  |  |          alpn_protocols, alpn_protocols_lengths, num_alpn_protocols,
 | 
	
		
			
				|  |  |          &impl->alpn_protocol_list, &impl->alpn_protocol_list_length);
 | 
	
		
			
				|  |  |      if (result != TSI_OK) {
 | 
	
		
			
				|  |  | -      tsi_ssl_handshaker_factory_destroy(&impl->base);
 | 
	
		
			
				|  |  | +      tsi_ssl_server_handshaker_factory_destroy(impl);
 | 
	
		
			
				|  |  |        return result;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |    }
 | 
	
	
		
			
				|  | @@ -1520,11 +1481,11 @@ tsi_result tsi_create_ssl_server_handshaker_factory_ex(
 | 
	
		
			
				|  |  |      } while (0);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      if (result != TSI_OK) {
 | 
	
		
			
				|  |  | -      tsi_ssl_handshaker_factory_destroy(&impl->base);
 | 
	
		
			
				|  |  | +      tsi_ssl_server_handshaker_factory_destroy(impl);
 | 
	
		
			
				|  |  |        return result;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | -  *factory = &impl->base;
 | 
	
		
			
				|  |  | +  *factory = impl;
 | 
	
		
			
				|  |  |    return TSI_OK;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 |