• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *
3  * Copyright 2018 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/lib/security/security_connector/tls/tls_security_connector.h"
20 
21 #include <gmock/gmock.h>
22 #include <grpc/support/alloc.h>
23 #include <grpc/support/log.h>
24 #include <grpc/support/string_util.h>
25 #include <gtest/gtest.h>
26 #include <stdlib.h>
27 #include <string.h>
28 
29 #include "src/core/lib/iomgr/load_file.h"
30 #include "src/core/tsi/transport_security.h"
31 #include "test/core/util/test_config.h"
32 
33 #define CA_CERT_PATH "src/core/tsi/test_creds/ca.pem"
34 #define SERVER_CERT_PATH "src/core/tsi/test_creds/server1.pem"
35 #define SERVER_KEY_PATH "src/core/tsi/test_creds/server1.key"
36 
37 namespace {
38 
39 enum CredReloadResult { FAIL, SUCCESS, UNCHANGED, ASYNC };
40 
SetKeyMaterials(grpc_tls_key_materials_config * config)41 void SetKeyMaterials(grpc_tls_key_materials_config* config) {
42   grpc_slice ca_slice, cert_slice, key_slice;
43   GPR_ASSERT(GRPC_LOG_IF_ERROR("load_file",
44                                grpc_load_file(CA_CERT_PATH, 1, &ca_slice)));
45   GPR_ASSERT(GRPC_LOG_IF_ERROR(
46       "load_file", grpc_load_file(SERVER_CERT_PATH, 1, &cert_slice)));
47   GPR_ASSERT(GRPC_LOG_IF_ERROR("load_file",
48                                grpc_load_file(SERVER_KEY_PATH, 1, &key_slice)));
49   const char* ca_cert =
50       reinterpret_cast<const char*> GRPC_SLICE_START_PTR(ca_slice);
51   const char* server_cert =
52       reinterpret_cast<const char*> GRPC_SLICE_START_PTR(cert_slice);
53   const char* server_key =
54       reinterpret_cast<const char*> GRPC_SLICE_START_PTR(key_slice);
55   grpc_ssl_pem_key_cert_pair pem_key_cert_pair = {server_key, server_cert};
56   const auto* pem_key_cert_pair_ptr = &pem_key_cert_pair;
57   grpc_tls_key_materials_config_set_key_materials(config, ca_cert,
58                                                   &pem_key_cert_pair_ptr, 1);
59   grpc_slice_unref(cert_slice);
60   grpc_slice_unref(key_slice);
61   grpc_slice_unref(ca_slice);
62 }
63 
CredReloadSuccess(void *,grpc_tls_credential_reload_arg * arg)64 int CredReloadSuccess(void* /*config_user_data*/,
65                       grpc_tls_credential_reload_arg* arg) {
66   SetKeyMaterials(arg->key_materials_config);
67   arg->status = GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW;
68   return 0;
69 }
70 
CredReloadFail(void *,grpc_tls_credential_reload_arg * arg)71 int CredReloadFail(void* /*config_user_data*/,
72                    grpc_tls_credential_reload_arg* arg) {
73   arg->status = GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_FAIL;
74   return 0;
75 }
76 
CredReloadUnchanged(void *,grpc_tls_credential_reload_arg * arg)77 int CredReloadUnchanged(void* /*config_user_data*/,
78                         grpc_tls_credential_reload_arg* arg) {
79   arg->status = GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED;
80   return 0;
81 }
82 
CredReloadAsync(void *,grpc_tls_credential_reload_arg *)83 int CredReloadAsync(void* /*config_user_data*/,
84                     grpc_tls_credential_reload_arg* /*arg*/) {
85   return 1;
86 }
87 
88 }  // namespace
89 
90 namespace grpc {
91 namespace testing {
92 
93 class TlsSecurityConnectorTest : public ::testing::Test {
94  protected:
TlsSecurityConnectorTest()95   TlsSecurityConnectorTest() {}
SetUp()96   void SetUp() override {
97     options_ = grpc_tls_credentials_options_create()->Ref();
98     config_ = grpc_tls_key_materials_config_create()->Ref();
99   }
TearDown()100   void TearDown() override { config_->Unref(); }
101   // Set credential reload config in options.
SetOptions(CredReloadResult type)102   void SetOptions(CredReloadResult type) {
103     grpc_tls_credential_reload_config* reload_config = nullptr;
104     switch (type) {
105       case SUCCESS:
106         reload_config = grpc_tls_credential_reload_config_create(
107             nullptr, CredReloadSuccess, nullptr, nullptr);
108         break;
109       case FAIL:
110         reload_config = grpc_tls_credential_reload_config_create(
111             nullptr, CredReloadFail, nullptr, nullptr);
112         break;
113       case UNCHANGED:
114         reload_config = grpc_tls_credential_reload_config_create(
115             nullptr, CredReloadUnchanged, nullptr, nullptr);
116         break;
117       case ASYNC:
118         reload_config = grpc_tls_credential_reload_config_create(
119             nullptr, CredReloadAsync, nullptr, nullptr);
120         break;
121       default:
122         break;
123     }
124     grpc_tls_credentials_options_set_credential_reload_config(options_.get(),
125                                                               reload_config);
126   }
127   // Set key materials config.
SetKeyMaterialsConfig()128   void SetKeyMaterialsConfig() { SetKeyMaterials(config_.get()); }
129   grpc_core::RefCountedPtr<grpc_tls_credentials_options> options_;
130   grpc_core::RefCountedPtr<grpc_tls_key_materials_config> config_;
131 };
132 
TEST_F(TlsSecurityConnectorTest,NoKeysAndConfig)133 TEST_F(TlsSecurityConnectorTest, NoKeysAndConfig) {
134   grpc_ssl_certificate_config_reload_status reload_status;
135   grpc_status_code status =
136       TlsFetchKeyMaterials(config_, *options_, true, &reload_status);
137   EXPECT_EQ(status, GRPC_STATUS_FAILED_PRECONDITION);
138   options_->Unref();
139 }
140 
TEST_F(TlsSecurityConnectorTest,NoKeysAndConfigAsAClient)141 TEST_F(TlsSecurityConnectorTest, NoKeysAndConfigAsAClient) {
142   grpc_ssl_certificate_config_reload_status reload_status;
143   grpc_status_code status =
144       TlsFetchKeyMaterials(config_, *options_, false, &reload_status);
145   EXPECT_EQ(status, GRPC_STATUS_OK);
146   options_->Unref();
147 }
148 
TEST_F(TlsSecurityConnectorTest,NoKeySuccessReload)149 TEST_F(TlsSecurityConnectorTest, NoKeySuccessReload) {
150   grpc_ssl_certificate_config_reload_status reload_status;
151   SetOptions(SUCCESS);
152   grpc_status_code status =
153       TlsFetchKeyMaterials(config_, *options_, true, &reload_status);
154   EXPECT_EQ(status, GRPC_STATUS_OK);
155   EXPECT_EQ(reload_status, GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW);
156   options_->Unref();
157 }
158 
TEST_F(TlsSecurityConnectorTest,NoKeyFailReload)159 TEST_F(TlsSecurityConnectorTest, NoKeyFailReload) {
160   grpc_ssl_certificate_config_reload_status reload_status;
161   SetOptions(FAIL);
162   grpc_status_code status =
163       TlsFetchKeyMaterials(config_, *options_, true, &reload_status);
164   EXPECT_EQ(status, GRPC_STATUS_INTERNAL);
165   EXPECT_EQ(reload_status, GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_FAIL);
166   options_->Unref();
167 }
168 
TEST_F(TlsSecurityConnectorTest,NoKeyAsyncReload)169 TEST_F(TlsSecurityConnectorTest, NoKeyAsyncReload) {
170   grpc_ssl_certificate_config_reload_status reload_status =
171       GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED;
172   SetOptions(ASYNC);
173   grpc_status_code status =
174       TlsFetchKeyMaterials(config_, *options_, true, &reload_status);
175   EXPECT_EQ(status, GRPC_STATUS_UNIMPLEMENTED);
176   EXPECT_EQ(reload_status, GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED);
177   options_->Unref();
178 }
179 
TEST_F(TlsSecurityConnectorTest,NoKeyUnchangedReload)180 TEST_F(TlsSecurityConnectorTest, NoKeyUnchangedReload) {
181   grpc_ssl_certificate_config_reload_status reload_status =
182       GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED;
183   SetOptions(UNCHANGED);
184   grpc_status_code status =
185       TlsFetchKeyMaterials(config_, *options_, true, &reload_status);
186   EXPECT_EQ(status, GRPC_STATUS_OK);
187   EXPECT_EQ(reload_status, GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED);
188   options_->Unref();
189 }
190 
TEST_F(TlsSecurityConnectorTest,WithKeyNoReload)191 TEST_F(TlsSecurityConnectorTest, WithKeyNoReload) {
192   grpc_ssl_certificate_config_reload_status reload_status =
193       GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED;
194   SetKeyMaterialsConfig();
195   grpc_status_code status =
196       TlsFetchKeyMaterials(config_, *options_, true, &reload_status);
197   EXPECT_EQ(status, GRPC_STATUS_OK);
198   options_->Unref();
199 }
200 
TEST_F(TlsSecurityConnectorTest,WithKeySuccessReload)201 TEST_F(TlsSecurityConnectorTest, WithKeySuccessReload) {
202   grpc_ssl_certificate_config_reload_status reload_status;
203   SetOptions(SUCCESS);
204   SetKeyMaterialsConfig();
205   grpc_status_code status =
206       TlsFetchKeyMaterials(config_, *options_, true, &reload_status);
207   EXPECT_EQ(status, GRPC_STATUS_OK);
208   EXPECT_EQ(reload_status, GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW);
209   options_->Unref();
210 }
211 
TEST_F(TlsSecurityConnectorTest,WithKeyFailReload)212 TEST_F(TlsSecurityConnectorTest, WithKeyFailReload) {
213   grpc_ssl_certificate_config_reload_status reload_status;
214   SetOptions(FAIL);
215   SetKeyMaterialsConfig();
216   grpc_status_code status =
217       TlsFetchKeyMaterials(config_, *options_, true, &reload_status);
218   EXPECT_EQ(status, GRPC_STATUS_OK);
219   EXPECT_EQ(reload_status, GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_FAIL);
220   options_->Unref();
221 }
222 
TEST_F(TlsSecurityConnectorTest,WithKeyAsyncReload)223 TEST_F(TlsSecurityConnectorTest, WithKeyAsyncReload) {
224   grpc_ssl_certificate_config_reload_status reload_status =
225       GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED;
226   SetOptions(ASYNC);
227   SetKeyMaterialsConfig();
228   grpc_status_code status =
229       TlsFetchKeyMaterials(config_, *options_, true, &reload_status);
230   EXPECT_EQ(status, GRPC_STATUS_OK);
231   EXPECT_EQ(reload_status, GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED);
232   options_->Unref();
233 }
234 
TEST_F(TlsSecurityConnectorTest,WithKeyUnchangedReload)235 TEST_F(TlsSecurityConnectorTest, WithKeyUnchangedReload) {
236   grpc_ssl_certificate_config_reload_status reload_status =
237       GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED;
238   SetOptions(UNCHANGED);
239   SetKeyMaterialsConfig();
240   grpc_status_code status =
241       TlsFetchKeyMaterials(config_, *options_, true, &reload_status);
242   EXPECT_EQ(status, GRPC_STATUS_OK);
243   EXPECT_EQ(reload_status, GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED);
244   options_->Unref();
245 }
246 
TEST_F(TlsSecurityConnectorTest,CreateChannelSecurityConnectorSuccess)247 TEST_F(TlsSecurityConnectorTest, CreateChannelSecurityConnectorSuccess) {
248   SetOptions(SUCCESS);
249   auto cred = std::unique_ptr<grpc_channel_credentials>(
250       grpc_tls_credentials_create(options_.get()));
251   const char* target_name = "some_target";
252   grpc_channel_args* new_args = nullptr;
253   auto connector =
254       cred->create_security_connector(nullptr, target_name, nullptr, &new_args);
255   EXPECT_NE(connector, nullptr);
256   grpc_channel_args_destroy(new_args);
257 }
258 
TEST_F(TlsSecurityConnectorTest,CreateChannelSecurityConnectorFailNoTargetName)259 TEST_F(TlsSecurityConnectorTest,
260        CreateChannelSecurityConnectorFailNoTargetName) {
261   SetOptions(SUCCESS);
262   auto cred = std::unique_ptr<grpc_channel_credentials>(
263       grpc_tls_credentials_create(options_.get()));
264   grpc_channel_args* new_args = nullptr;
265   auto connector =
266       cred->create_security_connector(nullptr, nullptr, nullptr, &new_args);
267   EXPECT_EQ(connector, nullptr);
268 }
269 
TEST_F(TlsSecurityConnectorTest,CreateChannelSecurityConnectorFailInit)270 TEST_F(TlsSecurityConnectorTest, CreateChannelSecurityConnectorFailInit) {
271   SetOptions(FAIL);
272   auto cred = std::unique_ptr<grpc_channel_credentials>(
273       grpc_tls_credentials_create(options_.get()));
274   grpc_channel_args* new_args = nullptr;
275   auto connector =
276       cred->create_security_connector(nullptr, nullptr, nullptr, &new_args);
277   EXPECT_EQ(connector, nullptr);
278 }
279 
TEST_F(TlsSecurityConnectorTest,TlsCheckHostNameSuccess)280 TEST_F(TlsSecurityConnectorTest, TlsCheckHostNameSuccess) {
281   const char* target_name = "foo.test.google.fr";
282   tsi_peer peer;
283   GPR_ASSERT(tsi_construct_peer(1, &peer) == TSI_OK);
284   GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
285                  TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY, target_name,
286                  &peer.properties[0]) == TSI_OK);
287   grpc_error* error = grpc_core::TlsCheckHostName(target_name, &peer);
288   tsi_peer_destruct(&peer);
289   EXPECT_EQ(error, GRPC_ERROR_NONE);
290   GRPC_ERROR_UNREF(error);
291   options_->Unref();
292 }
293 
TEST_F(TlsSecurityConnectorTest,TlsCheckHostNameFail)294 TEST_F(TlsSecurityConnectorTest, TlsCheckHostNameFail) {
295   const char* target_name = "foo.test.google.fr";
296   const char* another_name = "bar.test.google.fr";
297   tsi_peer peer;
298   GPR_ASSERT(tsi_construct_peer(1, &peer) == TSI_OK);
299   GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
300                  TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY, another_name,
301                  &peer.properties[0]) == TSI_OK);
302   grpc_error* error = grpc_core::TlsCheckHostName(target_name, &peer);
303   tsi_peer_destruct(&peer);
304   EXPECT_NE(error, GRPC_ERROR_NONE);
305   GRPC_ERROR_UNREF(error);
306   options_->Unref();
307 }
308 
TEST_F(TlsSecurityConnectorTest,CreateServerSecurityConnectorSuccess)309 TEST_F(TlsSecurityConnectorTest, CreateServerSecurityConnectorSuccess) {
310   SetOptions(SUCCESS);
311   auto cred = std::unique_ptr<grpc_server_credentials>(
312       grpc_tls_server_credentials_create(options_.get()));
313   auto connector = cred->create_security_connector();
314   EXPECT_NE(connector, nullptr);
315 }
316 
TEST_F(TlsSecurityConnectorTest,CreateServerSecurityConnectorFailInit)317 TEST_F(TlsSecurityConnectorTest, CreateServerSecurityConnectorFailInit) {
318   SetOptions(FAIL);
319   auto cred = std::unique_ptr<grpc_server_credentials>(
320       grpc_tls_server_credentials_create(options_.get()));
321   auto connector = cred->create_security_connector();
322   EXPECT_EQ(connector, nullptr);
323 }
324 
325 }  // namespace testing
326 }  // namespace grpc
327 
main(int argc,char ** argv)328 int main(int argc, char** argv) {
329   grpc::testing::TestEnvironment env(argc, argv);
330   ::testing::InitGoogleTest(&argc, argv);
331   grpc_init();
332   int ret = RUN_ALL_TESTS();
333   grpc_shutdown();
334   return ret;
335 }
336