diff options
-rw-r--r-- | include/grpc++/server_credentials.h | 1 | ||||
-rw-r--r-- | include/grpc/grpc_security.h | 9 | ||||
-rw-r--r-- | src/core/security/credentials.c | 8 | ||||
-rw-r--r-- | src/core/security/security_connector.c | 7 | ||||
-rw-r--r-- | src/core/security/security_connector.h | 1 | ||||
-rw-r--r-- | src/core/tsi/ssl_transport_security.c | 8 | ||||
-rw-r--r-- | src/core/tsi/ssl_transport_security.h | 16 | ||||
-rw-r--r-- | src/cpp/server/secure_server_credentials.cc | 3 | ||||
-rw-r--r-- | src/csharp/ext/grpc_csharp_ext.c | 3 | ||||
-rw-r--r-- | src/node/ext/server_credentials.cc | 4 | ||||
-rw-r--r-- | src/php/ext/grpc/server_credentials.c | 6 | ||||
-rw-r--r-- | src/python/src/grpc/_adapter/_c/types/server_credentials.c | 4 | ||||
-rw-r--r-- | src/ruby/ext/grpc/rb_server_credentials.c | 5 | ||||
-rw-r--r-- | test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c | 2 | ||||
-rw-r--r-- | test/core/end2end/fixtures/chttp2_simple_ssl_fullstack_with_poll.c | 2 | ||||
-rw-r--r-- | test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c | 2 | ||||
-rw-r--r-- | test/core/fling/server.c | 2 |
17 files changed, 53 insertions, 30 deletions
diff --git a/include/grpc++/server_credentials.h b/include/grpc++/server_credentials.h index 83ae9fd1eb..94041c7757 100644 --- a/include/grpc++/server_credentials.h +++ b/include/grpc++/server_credentials.h @@ -64,6 +64,7 @@ struct SslServerCredentialsOptions { }; grpc::string pem_root_certs; std::vector<PemKeyCertPair> pem_key_cert_pairs; + bool force_client_auth; }; // Builds SSL ServerCredentials given SSL specific options diff --git a/include/grpc/grpc_security.h b/include/grpc/grpc_security.h index 37d66c04ae..7c5bd6433f 100644 --- a/include/grpc/grpc_security.h +++ b/include/grpc/grpc_security.h @@ -87,7 +87,7 @@ typedef struct { directory). - pem_key_cert_pair is a pointer on the object containing client's private key and certificate chain. This parameter can be NULL if the client does - not have such a key/cert pair. */ + not have such a key/cert pair. */ grpc_credentials *grpc_ssl_credentials_create( const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pair); @@ -177,10 +177,13 @@ void grpc_server_credentials_release(grpc_server_credentials *creds); - pem_key_cert_pairs is an array private key / certificate chains of the server. This parameter cannot be NULL. - num_key_cert_pairs indicates the number of items in the private_key_files - and cert_chain_files parameters. It should be at least 1. */ + and cert_chain_files parameters. It should be at least 1. + - force_client_auth, if set to non-zero will force the client to authenticate + with an SSL cert. Note that this option is ignored if pem_root_certs is + NULL. */ grpc_server_credentials *grpc_ssl_server_credentials_create( const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs, - size_t num_key_cert_pairs); + size_t num_key_cert_pairs, int force_client_auth); /* Creates a fake server transport security credentials object for testing. */ grpc_server_credentials *grpc_fake_transport_security_server_credentials_create( diff --git a/src/core/security/credentials.c b/src/core/security/credentials.c index fb59fa4b0e..a4d998a429 100644 --- a/src/core/security/credentials.c +++ b/src/core/security/credentials.c @@ -259,8 +259,10 @@ static void ssl_build_config(const char *pem_root_certs, static void ssl_build_server_config( const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs, - size_t num_key_cert_pairs, grpc_ssl_server_config *config) { + size_t num_key_cert_pairs, int force_client_auth, + grpc_ssl_server_config *config) { size_t i; + config->force_client_auth = force_client_auth; if (pem_root_certs != NULL) { ssl_copy_key_material(pem_root_certs, &config->pem_root_certs, &config->pem_root_certs_size); @@ -302,14 +304,14 @@ grpc_credentials *grpc_ssl_credentials_create( grpc_server_credentials *grpc_ssl_server_credentials_create( const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs, - size_t num_key_cert_pairs) { + size_t num_key_cert_pairs, int force_client_auth) { grpc_ssl_server_credentials *c = gpr_malloc(sizeof(grpc_ssl_server_credentials)); memset(c, 0, sizeof(grpc_ssl_server_credentials)); c->base.type = GRPC_CREDENTIALS_TYPE_SSL; c->base.vtable = &ssl_server_vtable; ssl_build_server_config(pem_root_certs, pem_key_cert_pairs, - num_key_cert_pairs, &c->config); + num_key_cert_pairs, force_client_auth, &c->config); return &c->base; } diff --git a/src/core/security/security_connector.c b/src/core/security/security_connector.c index f6e423eb27..726b4c1e12 100644 --- a/src/core/security/security_connector.c +++ b/src/core/security/security_connector.c @@ -653,9 +653,10 @@ grpc_security_status grpc_ssl_server_security_connector_create( config->pem_private_keys_sizes, (const unsigned char **)config->pem_cert_chains, config->pem_cert_chains_sizes, config->num_key_cert_pairs, - config->pem_root_certs, config->pem_root_certs_size, ssl_cipher_suites(), - alpn_protocol_strings, alpn_protocol_string_lengths, - (uint16_t)num_alpn_protocols, &c->handshaker_factory); + config->pem_root_certs, config->pem_root_certs_size, + config->force_client_auth, ssl_cipher_suites(), alpn_protocol_strings, + alpn_protocol_string_lengths, (uint16_t)num_alpn_protocols, + &c->handshaker_factory); if (result != TSI_OK) { gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", tsi_result_to_string(result)); diff --git a/src/core/security/security_connector.h b/src/core/security/security_connector.h index a4c723f026..2c9aa1c5a4 100644 --- a/src/core/security/security_connector.h +++ b/src/core/security/security_connector.h @@ -201,6 +201,7 @@ typedef struct { size_t num_key_cert_pairs; unsigned char *pem_root_certs; size_t pem_root_certs_size; + int force_client_auth; } grpc_ssl_server_config; /* Creates an SSL server_security_connector. diff --git a/src/core/tsi/ssl_transport_security.c b/src/core/tsi/ssl_transport_security.c index 6156a39d09..609fc06ed5 100644 --- a/src/core/tsi/ssl_transport_security.c +++ b/src/core/tsi/ssl_transport_security.c @@ -1293,8 +1293,8 @@ tsi_result tsi_create_ssl_server_handshaker_factory( const size_t* pem_private_keys_sizes, const unsigned char** pem_cert_chains, const size_t* pem_cert_chains_sizes, size_t key_cert_pair_count, const unsigned char* pem_client_root_certs, - size_t pem_client_root_certs_size, const char* cipher_list, - const unsigned char** alpn_protocols, + 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* impl = NULL; @@ -1349,6 +1349,7 @@ tsi_result tsi_create_ssl_server_handshaker_factory( if (result != TSI_OK) break; if (pem_client_root_certs != NULL) { + int flags = SSL_VERIFY_PEER; STACK_OF(X509_NAME)* root_names = NULL; result = ssl_ctx_load_verification_certs( impl->ssl_contexts[i], pem_client_root_certs, @@ -1358,7 +1359,8 @@ tsi_result tsi_create_ssl_server_handshaker_factory( break; } SSL_CTX_set_client_CA_list(impl->ssl_contexts[i], root_names); - SSL_CTX_set_verify(impl->ssl_contexts[i], SSL_VERIFY_PEER, NULL); + if (force_client_auth) flags |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT; + SSL_CTX_set_verify(impl->ssl_contexts[i], flags, NULL); /* TODO(jboeuf): Add revocation verification. */ } diff --git a/src/core/tsi/ssl_transport_security.h b/src/core/tsi/ssl_transport_security.h index b2aa2f393e..4bf6c81b75 100644 --- a/src/core/tsi/ssl_transport_security.h +++ b/src/core/tsi/ssl_transport_security.h @@ -107,10 +107,14 @@ tsi_result tsi_create_ssl_client_handshaker_factory( - key_cert_pair_count indicates the number of items in the private_key_files and cert_chain_files parameters. - pem_client_roots is the buffer containing the PEM encoding of the client - root certificates. This parameter may be NULL in which case the server - will not ask the client to authenticate itself with a certificate (server- - only authentication mode). - - pem_client_roots_size is the size of the associated buffer. + root certificates. This parameter may be NULL in which case the server will + not authenticate the client. If not NULL, the force_client_auth parameter + specifies if the server will accept only authenticated clients or both + authenticated and non-authenticated clients. + - pem_client_root_certs_size is the size of the associated buffer. + - force_client_auth, if set to non-zero will force the client to authenticate + with an SSL cert. Note that this option is ignored if pem_client_root_certs + is NULL or pem_client_roots_certs_size is 0 - cipher_suites contains an optional list of the ciphers that the server supports. The format of this string is described in: https://www.openssl.org/docs/apps/ciphers.html. @@ -131,8 +135,8 @@ tsi_result tsi_create_ssl_server_handshaker_factory( const size_t* pem_private_keys_sizes, const unsigned char** pem_cert_chains, const size_t* pem_cert_chains_sizes, size_t key_cert_pair_count, const unsigned char* pem_client_root_certs, - size_t pem_client_root_certs_size, const char* cipher_suites, - const unsigned char** alpn_protocols, + size_t pem_client_root_certs_size, int force_client_auth, + const char* cipher_suites, const unsigned char** alpn_protocols, const unsigned char* alpn_protocols_lengths, uint16_t num_alpn_protocols, tsi_ssl_handshaker_factory** factory); diff --git a/src/cpp/server/secure_server_credentials.cc b/src/cpp/server/secure_server_credentials.cc index 3e262dd74f..32c45e2280 100644 --- a/src/cpp/server/secure_server_credentials.cc +++ b/src/cpp/server/secure_server_credentials.cc @@ -51,7 +51,8 @@ std::shared_ptr<ServerCredentials> SslServerCredentials( } grpc_server_credentials* c_creds = grpc_ssl_server_credentials_create( options.pem_root_certs.empty() ? nullptr : options.pem_root_certs.c_str(), - &pem_key_cert_pairs[0], pem_key_cert_pairs.size()); + &pem_key_cert_pairs[0], pem_key_cert_pairs.size(), + options.force_client_auth); return std::shared_ptr<ServerCredentials>( new SecureServerCredentials(c_creds)); } diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c index 7dd1959a5f..3c0035d453 100644 --- a/src/csharp/ext/grpc_csharp_ext.c +++ b/src/csharp/ext/grpc_csharp_ext.c @@ -718,8 +718,9 @@ grpcsharp_ssl_server_credentials_create( key_cert_pairs[i].private_key = key_cert_pair_private_key_array[i]; } } + /* TODO: Add a force_client_auth parameter and pass it here. */ creds = grpc_ssl_server_credentials_create(pem_root_certs, key_cert_pairs, - num_key_cert_pairs); + num_key_cert_pairs, 0); gpr_free(key_cert_pairs); return creds; } diff --git a/src/node/ext/server_credentials.cc b/src/node/ext/server_credentials.cc index d2b63cdc4e..709105c72f 100644 --- a/src/node/ext/server_credentials.cc +++ b/src/node/ext/server_credentials.cc @@ -140,8 +140,10 @@ NAN_METHOD(ServerCredentials::CreateSsl) { return NanThrowTypeError("createSsl's third argument must be a Buffer"); } key_cert_pair.cert_chain = ::node::Buffer::Data(args[2]); + // TODO Add a force_client_auth parameter and pass it as the last parameter + // here. NanReturnValue(WrapStruct( - grpc_ssl_server_credentials_create(root_certs, &key_cert_pair, 1))); + grpc_ssl_server_credentials_create(root_certs, &key_cert_pair, 1, 0))); } NAN_METHOD(ServerCredentials::CreateFake) { diff --git a/src/php/ext/grpc/server_credentials.c b/src/php/ext/grpc/server_credentials.c index c4c1fabb1a..ec1c3c4f52 100644 --- a/src/php/ext/grpc/server_credentials.c +++ b/src/php/ext/grpc/server_credentials.c @@ -115,8 +115,10 @@ PHP_METHOD(ServerCredentials, createSsl) { "createSsl expects 3 strings", 1 TSRMLS_CC); return; } - grpc_server_credentials *creds = - grpc_ssl_server_credentials_create(pem_root_certs, &pem_key_cert_pair, 1); + /* TODO: add a force_client_auth field in ServerCredentials and pass it as + * the last parameter. */ + grpc_server_credentials *creds = grpc_ssl_server_credentials_create( + pem_root_certs, &pem_key_cert_pair, 1, 0); zval *creds_object = grpc_php_wrap_server_credentials(creds); RETURN_DESTROY_ZVAL(creds_object); } diff --git a/src/python/src/grpc/_adapter/_c/types/server_credentials.c b/src/python/src/grpc/_adapter/_c/types/server_credentials.c index 2e02c8fe81..2277b5b907 100644 --- a/src/python/src/grpc/_adapter/_c/types/server_credentials.c +++ b/src/python/src/grpc/_adapter/_c/types/server_credentials.c @@ -131,8 +131,10 @@ ServerCredentials *pygrpc_ServerCredentials_ssl( } self = (ServerCredentials *)type->tp_alloc(type, 0); + /* TODO: Add a force_client_auth parameter in the python object and pass it + here as the last arg. */ self->c_creds = grpc_ssl_server_credentials_create( - root_certs, key_cert_pairs, num_key_cert_pairs); + root_certs, key_cert_pairs, num_key_cert_pairs, 0); gpr_free(key_cert_pairs); return self; } diff --git a/src/ruby/ext/grpc/rb_server_credentials.c b/src/ruby/ext/grpc/rb_server_credentials.c index 5f40935890..62c211d769 100644 --- a/src/ruby/ext/grpc/rb_server_credentials.c +++ b/src/ruby/ext/grpc/rb_server_credentials.c @@ -176,11 +176,12 @@ static VALUE grpc_rb_server_credentials_init(VALUE self, VALUE pem_root_certs, } key_cert_pair.private_key = RSTRING_PTR(pem_private_key); key_cert_pair.cert_chain = RSTRING_PTR(pem_cert_chain); + /* TODO Add a force_client_auth parameter and pass it here. */ if (pem_root_certs == Qnil) { - creds = grpc_ssl_server_credentials_create(NULL, &key_cert_pair, 1); + creds = grpc_ssl_server_credentials_create(NULL, &key_cert_pair, 1, 0); } else { creds = grpc_ssl_server_credentials_create(RSTRING_PTR(pem_root_certs), - &key_cert_pair, 1); + &key_cert_pair, 1, 0); } if (creds == NULL) { rb_raise(rb_eRuntimeError, "could not create a credentials, not sure why"); diff --git a/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c b/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c index 73a36116fb..6d5669d05a 100644 --- a/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c +++ b/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c @@ -115,7 +115,7 @@ static void chttp2_init_server_simple_ssl_secure_fullstack( grpc_ssl_pem_key_cert_pair pem_cert_key_pair = {test_server1_key, test_server1_cert}; grpc_server_credentials *ssl_creds = - grpc_ssl_server_credentials_create(NULL, &pem_cert_key_pair, 1); + grpc_ssl_server_credentials_create(NULL, &pem_cert_key_pair, 1, 0); chttp2_init_server_secure_fullstack(f, server_args, ssl_creds); } diff --git a/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack_with_poll.c b/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack_with_poll.c index b1ac3e535f..d0cc3dd74a 100644 --- a/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack_with_poll.c +++ b/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack_with_poll.c @@ -115,7 +115,7 @@ static void chttp2_init_server_simple_ssl_secure_fullstack( grpc_ssl_pem_key_cert_pair pem_cert_key_pair = {test_server1_key, test_server1_cert}; grpc_server_credentials *ssl_creds = - grpc_ssl_server_credentials_create(NULL, &pem_cert_key_pair, 1); + grpc_ssl_server_credentials_create(NULL, &pem_cert_key_pair, 1, 0); chttp2_init_server_secure_fullstack(f, server_args, ssl_creds); } diff --git a/test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c b/test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c index de418bf7ee..f74ed9365f 100644 --- a/test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c +++ b/test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c @@ -120,7 +120,7 @@ static void chttp2_init_server_simple_ssl_secure_fullstack( grpc_ssl_pem_key_cert_pair pem_key_cert_pair = {test_server1_key, test_server1_cert}; grpc_server_credentials *ssl_creds = - grpc_ssl_server_credentials_create(NULL, &pem_key_cert_pair, 1); + grpc_ssl_server_credentials_create(NULL, &pem_key_cert_pair, 1, 0); chttp2_init_server_secure_fullstack(f, server_args, ssl_creds); } diff --git a/test/core/fling/server.c b/test/core/fling/server.c index 082bbd368a..8f349044d9 100644 --- a/test/core/fling/server.c +++ b/test/core/fling/server.c @@ -210,7 +210,7 @@ int main(int argc, char **argv) { grpc_ssl_pem_key_cert_pair pem_key_cert_pair = {test_server1_key, test_server1_cert}; grpc_server_credentials *ssl_creds = - grpc_ssl_server_credentials_create(NULL, &pem_key_cert_pair, 1); + grpc_ssl_server_credentials_create(NULL, &pem_key_cert_pair, 1, 0); server = grpc_server_create(NULL); GPR_ASSERT(grpc_server_add_secure_http2_port(server, addr, ssl_creds)); grpc_server_credentials_release(ssl_creds); |