Skip to content

Commit db11b94

Browse files
committed
FullChainExperimental-01-200103
1 parent 40d8986 commit db11b94

18 files changed

+295
-36
lines changed

Diff for: grpc.def

+1
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ EXPORTS
136136
grpc_local_server_credentials_create
137137
grpc_tls_credentials_options_create
138138
grpc_tls_credentials_options_set_cert_request_type
139+
grpc_tls_credentials_options_set_server_verification_option
139140
grpc_tls_credentials_options_set_key_materials_config
140141
grpc_tls_credentials_options_set_credential_reload_config
141142
grpc_tls_credentials_options_set_server_authorization_check_config

Diff for: include/grpc/grpc_security.h

+14
Original file line numberDiff line numberDiff line change
@@ -731,6 +731,19 @@ GRPCAPI int grpc_tls_credentials_options_set_cert_request_type(
731731
grpc_tls_credentials_options* options,
732732
grpc_ssl_client_certificate_request_type type);
733733

734+
/** Set grpc_tls_server_verification_option field in credentials options
735+
with the provided server_verification_option. options should not be NULL.
736+
This should be called only on the client side.
737+
If grpc_tls_server_verification_option is not
738+
GRPC_TLS_SERVER_VERIFICATION, use of a customer server
739+
authorization check (grpc_tls_server_authorization_check_config)
740+
will be mandatory.
741+
It returns 1 on success and 0 on failure. It is used for
742+
experimental purpose for now and subject to change. */
743+
GRPCAPI int grpc_tls_credentials_options_set_server_verification_option(
744+
grpc_tls_credentials_options* options,
745+
grpc_tls_server_verification_option server_verification_option);
746+
734747
/** Set grpc_tls_key_materials_config field in credentials options
735748
with the provided config struct whose ownership is transferred.
736749
Both parameters should not be NULL.
@@ -902,6 +915,7 @@ struct grpc_tls_server_authorization_check_arg {
902915
int success;
903916
const char* target_name;
904917
const char* peer_cert;
918+
const char* peer_cert_full_chain;
905919
grpc_status_code status;
906920
const char* error_details;
907921
grpc_tls_server_authorization_check_config* config;

Diff for: include/grpc/grpc_security_constants.h

+12
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ extern "C" {
2929
#define GRPC_X509_CN_PROPERTY_NAME "x509_common_name"
3030
#define GRPC_X509_SAN_PROPERTY_NAME "x509_subject_alternative_name"
3131
#define GRPC_X509_PEM_CERT_PROPERTY_NAME "x509_pem_cert"
32+
#define GRPC_X509_PEM_CERT_CHAIN_PROPERTY_NAME "x509_pem_cert_chain"
3233
#define GRPC_SSL_SESSION_REUSED_PROPERTY "ssl_session_reused"
3334

3435
/** Environment variable that points to the default SSL roots file. This file
@@ -114,6 +115,17 @@ typedef enum {
114115
GRPC_SECURITY_MAX = GRPC_PRIVACY_AND_INTEGRITY,
115116
} grpc_security_level;
116117

118+
typedef enum {
119+
/** Default option: performs server certificate verification and hostname
120+
verification */
121+
GRPC_TLS_SERVER_VERIFICATION,
122+
/** Performs server certificate verification, but skips hostname verification
123+
*/
124+
GRPC_TLS_SKIP_HOSTNAME_VERIFICATION,
125+
/** Skips both server certificate and hostname verification */
126+
GRPC_TLS_SKIP_ALL_SERVER_VERIFICATION
127+
} grpc_tls_server_verification_option;
128+
117129
/**
118130
* Type of local connections for which local channel/server credentials will be
119131
* applied. It supports UDS and local TCP connections.

Diff for: include/grpcpp/security/tls_credentials_options.h

+9
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ class TlsServerAuthorizationCheckArg {
193193
int success() const;
194194
grpc::string target_name() const;
195195
grpc::string peer_cert() const;
196+
grpc::string peer_cert_full_chain() const;
196197
grpc_status_code status() const;
197198
grpc::string error_details() const;
198199

@@ -206,6 +207,7 @@ class TlsServerAuthorizationCheckArg {
206207
void set_success(int success);
207208
void set_target_name(const grpc::string& target_name);
208209
void set_peer_cert(const grpc::string& peer_cert);
210+
void set_peer_cert_full_chain(const grpc::string& peer_cert_full_chain);
209211
void set_status(grpc_status_code status);
210212
void set_error_details(const grpc::string& error_details);
211213

@@ -287,6 +289,7 @@ class TlsCredentialsOptions {
287289
public:
288290
TlsCredentialsOptions(
289291
grpc_ssl_client_certificate_request_type cert_request_type,
292+
grpc_tls_server_verification_option server_verification_option,
290293
std::shared_ptr<TlsKeyMaterialsConfig> key_materials_config,
291294
std::shared_ptr<TlsCredentialReloadConfig> credential_reload_config,
292295
std::shared_ptr<TlsServerAuthorizationCheckConfig>
@@ -297,6 +300,9 @@ class TlsCredentialsOptions {
297300
grpc_ssl_client_certificate_request_type cert_request_type() const {
298301
return cert_request_type_;
299302
}
303+
grpc_tls_server_verification_option server_verification_option() const {
304+
return server_verification_option_;
305+
}
300306
std::shared_ptr<TlsKeyMaterialsConfig> key_materials_config() const {
301307
return key_materials_config_;
302308
}
@@ -317,6 +323,9 @@ class TlsCredentialsOptions {
317323
* goes unused when creating channel credentials, and the user can set it to
318324
* GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE. **/
319325
grpc_ssl_client_certificate_request_type cert_request_type_;
326+
/** The server_verification_option_ flag is only relevant when the
327+
* TlsCredentialsOptions are used to instantiate client credentials; **/
328+
grpc_tls_server_verification_option server_verification_option_;
320329
std::shared_ptr<TlsKeyMaterialsConfig> key_materials_config_;
321330
std::shared_ptr<TlsCredentialReloadConfig> credential_reload_config_;
322331
std::shared_ptr<TlsServerAuthorizationCheckConfig>

Diff for: src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc

+20
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,26 @@ int grpc_tls_credentials_options_set_cert_request_type(
9292
return 1;
9393
}
9494

95+
int grpc_tls_credentials_options_set_server_verification_option(
96+
grpc_tls_credentials_options* options,
97+
grpc_tls_server_verification_option server_verification_option) {
98+
if (options == nullptr) {
99+
gpr_log(GPR_ERROR,
100+
"Invalid nullptr arguments to "
101+
"grpc_tls_credentials_options_set_server_verification_option()");
102+
return 0;
103+
}
104+
if (server_verification_option != GRPC_TLS_SERVER_VERIFICATION &&
105+
options->server_authorization_check_config() == nullptr) {
106+
gpr_log(GPR_ERROR,
107+
"server_authorization_check_config needs to be specified when"
108+
"server_verification_option is not GRPC_TLS_SERVER_VERIFICATION");
109+
return 0;
110+
}
111+
options->set_server_verification_option(server_verification_option);
112+
return 1;
113+
}
114+
95115
int grpc_tls_credentials_options_set_key_materials_config(
96116
grpc_tls_credentials_options* options,
97117
grpc_tls_key_materials_config* config) {

Diff for: src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h

+8
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,9 @@ struct grpc_tls_credentials_options
234234
grpc_ssl_client_certificate_request_type cert_request_type() const {
235235
return cert_request_type_;
236236
}
237+
grpc_tls_server_verification_option server_verification_option() const {
238+
return server_verification_option_;
239+
}
237240
grpc_tls_key_materials_config* key_materials_config() const {
238241
return key_materials_config_.get();
239242
}
@@ -250,6 +253,10 @@ struct grpc_tls_credentials_options
250253
const grpc_ssl_client_certificate_request_type type) {
251254
cert_request_type_ = type;
252255
}
256+
void set_server_verification_option(
257+
const grpc_tls_server_verification_option server_verification_option) {
258+
server_verification_option_ = server_verification_option;
259+
}
253260
void set_key_materials_config(
254261
grpc_core::RefCountedPtr<grpc_tls_key_materials_config> config) {
255262
key_materials_config_ = std::move(config);
@@ -266,6 +273,7 @@ struct grpc_tls_credentials_options
266273

267274
private:
268275
grpc_ssl_client_certificate_request_type cert_request_type_;
276+
grpc_tls_server_verification_option server_verification_option_;
269277
grpc_core::RefCountedPtr<grpc_tls_key_materials_config> key_materials_config_;
270278
grpc_core::RefCountedPtr<grpc_tls_credential_reload_config>
271279
credential_reload_config_;

Diff for: src/core/lib/security/security_connector/ssl_utils.cc

+24
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,20 @@ grpc_get_tsi_client_certificate_request_type(
108108
}
109109
}
110110

111+
tsi_server_verification_option grpc_get_tsi_server_verification_option(
112+
grpc_tls_server_verification_option server_verification_option) {
113+
switch (server_verification_option) {
114+
case GRPC_TLS_SERVER_VERIFICATION:
115+
return TSI_SERVER_VERIFICATION;
116+
case GRPC_TLS_SKIP_HOSTNAME_VERIFICATION:
117+
return TSI_SKIP_HOSTNAME_VERIFICATION;
118+
case GRPC_TLS_SKIP_ALL_SERVER_VERIFICATION:
119+
return TSI_SKIP_ALL_SERVER_VERIFICATION;
120+
default:
121+
return TSI_SERVER_VERIFICATION;
122+
}
123+
}
124+
111125
grpc_error* grpc_ssl_check_alpn(const tsi_peer* peer) {
112126
#if TSI_OPENSSL_ALPN_SUPPORT
113127
/* Check the ALPN if ALPN is supported. */
@@ -225,6 +239,10 @@ grpc_core::RefCountedPtr<grpc_auth_context> grpc_ssl_peer_to_auth_context(
225239
grpc_auth_context_add_property(ctx.get(),
226240
GRPC_X509_PEM_CERT_PROPERTY_NAME,
227241
prop->value.data, prop->value.length);
242+
} else if (strcmp(prop->name, TSI_X509_PEM_CERT_CHAIN_PROPERTY) == 0) {
243+
grpc_auth_context_add_property(ctx.get(),
244+
GRPC_X509_PEM_CERT_CHAIN_PROPERTY_NAME,
245+
prop->value.data, prop->value.length);
228246
} else if (strcmp(prop->name, TSI_SSL_SESSION_REUSED_PEER_PROPERTY) == 0) {
229247
grpc_auth_context_add_property(ctx.get(),
230248
GRPC_SSL_SESSION_REUSED_PROPERTY,
@@ -272,6 +290,10 @@ tsi_peer grpc_shallow_peer_from_ssl_auth_context(
272290
} else if (strcmp(prop->name, GRPC_X509_PEM_CERT_PROPERTY_NAME) == 0) {
273291
add_shallow_auth_property_to_peer(&peer, prop,
274292
TSI_X509_PEM_CERT_PROPERTY);
293+
} else if (strcmp(prop->name, GRPC_X509_PEM_CERT_CHAIN_PROPERTY_NAME) ==
294+
0) {
295+
add_shallow_auth_property_to_peer(&peer, prop,
296+
TSI_X509_PEM_CERT_CHAIN_PROPERTY);
275297
}
276298
}
277299
}
@@ -284,6 +306,7 @@ void grpc_shallow_peer_destruct(tsi_peer* peer) {
284306

285307
grpc_security_status grpc_ssl_tsi_client_handshaker_factory_init(
286308
tsi_ssl_pem_key_cert_pair* pem_key_cert_pair, const char* pem_root_certs,
309+
tsi_server_verification_option server_verification_option,
287310
tsi_ssl_session_cache* ssl_session_cache,
288311
tsi_ssl_client_handshaker_factory** handshaker_factory) {
289312
const char* root_certs;
@@ -314,6 +337,7 @@ grpc_security_status grpc_ssl_tsi_client_handshaker_factory_init(
314337
}
315338
options.cipher_suites = grpc_get_ssl_cipher_suites();
316339
options.session_cache = ssl_session_cache;
340+
options.server_verification_option = server_verification_option;
317341
const tsi_result result =
318342
tsi_create_ssl_client_handshaker_factory_with_options(&options,
319343
handshaker_factory);

Diff for: src/core/lib/security/security_connector/ssl_utils.h

+6
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,18 @@ tsi_client_certificate_request_type
6868
grpc_get_tsi_client_certificate_request_type(
6969
grpc_ssl_client_certificate_request_type grpc_request_type);
7070

71+
/* Map from grpc_tls_server_verification_option to
72+
* tsi_server_verification_option. */
73+
tsi_server_verification_option grpc_get_tsi_server_verification_option(
74+
grpc_tls_server_verification_option server_verification_option);
75+
7176
/* Return an array of strings containing alpn protocols. */
7277
const char** grpc_fill_alpn_protocol_strings(size_t* num_alpn_protocols);
7378

7479
/* Initialize TSI SSL server/client handshaker factory. */
7580
grpc_security_status grpc_ssl_tsi_client_handshaker_factory_init(
7681
tsi_ssl_pem_key_cert_pair* key_cert_pair, const char* pem_root_certs,
82+
tsi_server_verification_option server_verification_option,
7783
tsi_ssl_session_cache* ssl_session_cache,
7884
tsi_ssl_client_handshaker_factory** handshaker_factory);
7985

Diff for: src/core/lib/security/security_connector/tls/tls_security_connector.cc

+27-10
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,13 @@ tsi_ssl_pem_key_cert_pair* ConvertToTsiPemKeyCertPair(
6666
grpc_status_code TlsFetchKeyMaterials(
6767
const grpc_core::RefCountedPtr<grpc_tls_key_materials_config>&
6868
key_materials_config,
69-
const grpc_tls_credentials_options& options,
69+
const grpc_tls_credentials_options& options, bool server_config,
7070
grpc_ssl_certificate_config_reload_status* reload_status) {
7171
GPR_ASSERT(key_materials_config != nullptr);
7272
bool is_key_materials_empty =
7373
key_materials_config->pem_key_cert_pair_list().empty();
74-
if (options.credential_reload_config() == nullptr && is_key_materials_empty) {
74+
if (options.credential_reload_config() == nullptr && is_key_materials_empty &&
75+
server_config) {
7576
gpr_log(GPR_ERROR,
7677
"Either credential reload config or key materials should be "
7778
"provisioned.");
@@ -190,9 +191,8 @@ void TlsChannelSecurityConnector::check_peer(
190191
error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
191192
"Cannot check peer: missing pem cert property.");
192193
} else {
193-
char* peer_pem = static_cast<char*>(gpr_malloc(p->value.length + 1));
194+
char* peer_pem = static_cast<char*>(gpr_zalloc(p->value.length + 1));
194195
memcpy(peer_pem, p->value.data, p->value.length);
195-
peer_pem[p->value.length] = '\0';
196196
GPR_ASSERT(check_arg_ != nullptr);
197197
check_arg_->peer_cert = check_arg_->peer_cert == nullptr
198198
? gpr_strdup(peer_pem)
@@ -202,6 +202,18 @@ void TlsChannelSecurityConnector::check_peer(
202202
: check_arg_->target_name;
203203
on_peer_checked_ = on_peer_checked;
204204
gpr_free(peer_pem);
205+
const tsi_peer_property* chain = tsi_peer_get_property_by_name(
206+
&peer, TSI_X509_PEM_CERT_CHAIN_PROPERTY);
207+
if (chain != nullptr) {
208+
char* peer_pem_chain =
209+
static_cast<char*>(gpr_zalloc(chain->value.length + 1));
210+
memcpy(peer_pem_chain, chain->value.data, chain->value.length);
211+
check_arg_->peer_cert_full_chain =
212+
check_arg_->peer_cert_full_chain == nullptr
213+
? gpr_strdup(peer_pem_chain)
214+
: check_arg_->peer_cert_full_chain;
215+
gpr_free(peer_pem_chain);
216+
}
205217
int callback_status = config->Schedule(check_arg_);
206218
/* Server authorization check is handled asynchronously. */
207219
if (callback_status) {
@@ -272,16 +284,21 @@ TlsChannelSecurityConnector::CreateTlsChannelSecurityConnector(
272284

273285
grpc_security_status TlsChannelSecurityConnector::ReplaceHandshakerFactory(
274286
tsi_ssl_session_cache* ssl_session_cache) {
287+
const TlsCredentials* creds =
288+
static_cast<const TlsCredentials*>(channel_creds());
289+
tsi_server_verification_option server_verification_option =
290+
grpc_get_tsi_server_verification_option(
291+
creds->options().server_verification_option());
275292
/* Free the client handshaker factory if exists. */
276293
if (client_handshaker_factory_) {
277294
tsi_ssl_client_handshaker_factory_unref(client_handshaker_factory_);
278295
}
279-
GPR_ASSERT(!key_materials_config_->pem_key_cert_pair_list().empty());
280296
tsi_ssl_pem_key_cert_pair* pem_key_cert_pair = ConvertToTsiPemKeyCertPair(
281297
key_materials_config_->pem_key_cert_pair_list());
282298
grpc_security_status status = grpc_ssl_tsi_client_handshaker_factory_init(
283299
pem_key_cert_pair, key_materials_config_->pem_root_certs(),
284-
ssl_session_cache, &client_handshaker_factory_);
300+
server_verification_option, ssl_session_cache,
301+
&client_handshaker_factory_);
285302
/* Free memory. */
286303
grpc_tsi_ssl_pem_key_cert_pairs_destroy(pem_key_cert_pair, 1);
287304
return status;
@@ -305,7 +322,7 @@ grpc_security_status TlsChannelSecurityConnector::InitializeHandshakerFactory(
305322
}
306323
grpc_ssl_certificate_config_reload_status reload_status =
307324
GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED;
308-
if (TlsFetchKeyMaterials(key_materials_config_, creds->options(),
325+
if (TlsFetchKeyMaterials(key_materials_config_, creds->options(), false,
309326
&reload_status) != GRPC_STATUS_OK) {
310327
/* Raise an error if key materials are not populated. */
311328
return GRPC_SECURITY_ERROR;
@@ -319,7 +336,7 @@ grpc_security_status TlsChannelSecurityConnector::RefreshHandshakerFactory() {
319336
static_cast<const TlsCredentials*>(channel_creds());
320337
grpc_ssl_certificate_config_reload_status reload_status =
321338
GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED;
322-
if (TlsFetchKeyMaterials(key_materials_config_, creds->options(),
339+
if (TlsFetchKeyMaterials(key_materials_config_, creds->options(), false,
323340
&reload_status) != GRPC_STATUS_OK) {
324341
return GRPC_SECURITY_ERROR;
325342
}
@@ -507,7 +524,7 @@ grpc_security_status TlsServerSecurityConnector::InitializeHandshakerFactory() {
507524
}
508525
grpc_ssl_certificate_config_reload_status reload_status =
509526
GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED;
510-
if (TlsFetchKeyMaterials(key_materials_config_, creds->options(),
527+
if (TlsFetchKeyMaterials(key_materials_config_, creds->options(), true,
511528
&reload_status) != GRPC_STATUS_OK) {
512529
/* Raise an error if key materials are not populated. */
513530
return GRPC_SECURITY_ERROR;
@@ -521,7 +538,7 @@ grpc_security_status TlsServerSecurityConnector::RefreshHandshakerFactory() {
521538
static_cast<const TlsServerCredentials*>(server_creds());
522539
grpc_ssl_certificate_config_reload_status reload_status =
523540
GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED;
524-
if (TlsFetchKeyMaterials(key_materials_config_, creds->options(),
541+
if (TlsFetchKeyMaterials(key_materials_config_, creds->options(), true,
525542
&reload_status) != GRPC_STATUS_OK) {
526543
return GRPC_SECURITY_ERROR;
527544
}

Diff for: src/core/lib/security/security_connector/tls/tls_security_connector.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ class TlsServerSecurityConnector final : public grpc_server_security_connector {
148148
grpc_status_code TlsFetchKeyMaterials(
149149
const grpc_core::RefCountedPtr<grpc_tls_key_materials_config>&
150150
key_materials_config,
151-
const grpc_tls_credentials_options& options,
151+
const grpc_tls_credentials_options& options, bool server_config,
152152
grpc_ssl_certificate_config_reload_status* status);
153153

154154
} // namespace grpc_core

0 commit comments

Comments
 (0)