Revert "Rework version selection following David's comment."

This reverts commit 70764178bf.
pull/24955/head
Matthew Stevenson 4 years ago
parent 70764178bf
commit d660e2a47a
  1. 421
      src/core/tsi/ssl_transport_security.cc

@ -915,53 +915,39 @@ static tsi_result tsi_set_min_and_max_tls_versions(
// |SSL_CTX_set_min_proto_version| and |SSL_CTX_set_max_proto_version| APIs
// only exist in this version range.
switch (min_tls_version) {
case tsi_tls_version::TSI_TLS1_2:
SSL_CTX_set_min_proto_version(ssl_context, TLS1_2_VERSION);
break;
// If the library does not support TLS 1.3, and the caller requested a minimum
// of TLS 1.3, return an error. The caller's request cannot be satisfied.
#if defined(TLS1_3_VERSION)
case tsi_tls_version::TSI_TLS1_3:
SSL_CTX_set_min_proto_version(ssl_context, TLS1_3_VERSION);
break;
#endif
default:
gpr_log(GPR_INFO, "TLS version is not supported.");
return TSI_FAILED_PRECONDITION;
witch(min_tls_version) {}
SSL_CTX_set_min_proto_version(ssl_context, TLS1_2_VERSION);
break;
}
// Set the max TLS version of the SSL context.
switch (max_tls_version) {
case tsi_tls_version::TSI_TLS1_2:
SSL_CTX_set_max_proto_version(ssl_context, TLS1_2_VERSION);
break;
case tsi_tls_version::TSI_TLS1_3:
#if defined(TLS1_3_VERSION)
case tsi_tls_version::TSI_TLS1_3:
SSL_CTX_set_max_proto_version(ssl_context, TLS1_3_VERSION);
#else
// The library doesn't support TLS 1.3, so set a maximum of
// TLS 1.2 instead.
SSL_CTX_set_max_proto_version(ssl_context, TLS1_2_VERSION);
#endif
break;
#endif
default:
gpr_log(GPR_INFO, "TLS version is not supported.");
return TSI_FAILED_PRECONDITION;
SSL_CTX_set_max_proto_version(ssl_context, TLS1_2_VERSION);
break;
}
#endif
return TSI_OK;
}
}
/* --- tsi_ssl_root_certs_store methods implementation. ---*/
/* --- tsi_ssl_root_certs_store methods implementation. ---*/
tsi_ssl_root_certs_store* tsi_ssl_root_certs_store_create(
tsi_ssl_root_certs_store* tsi_ssl_root_certs_store_create(
const char* pem_roots) {
if (pem_roots == nullptr) {
gpr_log(GPR_ERROR, "The root certificates are empty.");
return nullptr;
}
tsi_ssl_root_certs_store* root_store =
static_cast<tsi_ssl_root_certs_store*>(
tsi_ssl_root_certs_store* root_store = static_cast<tsi_ssl_root_certs_store*>(
gpr_zalloc(sizeof(tsi_ssl_root_certs_store)));
if (root_store == nullptr) {
gpr_log(GPR_ERROR, "Could not allocate buffer for ssl_root_certs_store.");
@ -982,36 +968,37 @@ static tsi_result tsi_set_min_and_max_tls_versions(
return nullptr;
}
return root_store;
}
}
void tsi_ssl_root_certs_store_destroy(tsi_ssl_root_certs_store * self) {
void tsi_ssl_root_certs_store_destroy(tsi_ssl_root_certs_store* self) {
if (self == nullptr) return;
X509_STORE_free(self->store);
gpr_free(self);
}
}
/* --- tsi_ssl_session_cache methods implementation. ---*/
/* --- tsi_ssl_session_cache methods implementation. ---*/
tsi_ssl_session_cache* tsi_ssl_session_cache_create_lru(size_t capacity) {
tsi_ssl_session_cache* tsi_ssl_session_cache_create_lru(size_t capacity) {
/* Pointer will be dereferenced by unref call. */
return reinterpret_cast<tsi_ssl_session_cache*>(
tsi::SslSessionLRUCache::Create(capacity).release());
}
}
void tsi_ssl_session_cache_ref(tsi_ssl_session_cache * cache) {
void tsi_ssl_session_cache_ref(tsi_ssl_session_cache* cache) {
/* Pointer will be dereferenced by unref call. */
reinterpret_cast<tsi::SslSessionLRUCache*>(cache)->Ref().release();
}
}
void tsi_ssl_session_cache_unref(tsi_ssl_session_cache * cache) {
void tsi_ssl_session_cache_unref(tsi_ssl_session_cache* cache) {
reinterpret_cast<tsi::SslSessionLRUCache*>(cache)->Unref();
}
}
/* --- tsi_frame_protector methods implementation. ---*/
/* --- tsi_frame_protector methods implementation. ---*/
static tsi_result ssl_protector_protect(
tsi_frame_protector * self, const unsigned char* unprotected_bytes,
size_t* unprotected_bytes_size, unsigned char* protected_output_frames,
static tsi_result ssl_protector_protect(tsi_frame_protector* self,
const unsigned char* unprotected_bytes,
size_t* unprotected_bytes_size,
unsigned char* protected_output_frames,
size_t* protected_output_frames_size) {
tsi_ssl_frame_protector* impl =
reinterpret_cast<tsi_ssl_frame_protector*>(self);
@ -1062,10 +1049,10 @@ static tsi_result tsi_set_min_and_max_tls_versions(
*unprotected_bytes_size = available;
impl->buffer_offset = 0;
return TSI_OK;
}
}
static tsi_result ssl_protector_protect_flush(
tsi_frame_protector * self, unsigned char* protected_output_frames,
static tsi_result ssl_protector_protect_flush(
tsi_frame_protector* self, unsigned char* protected_output_frames,
size_t* protected_output_frames_size, size_t* still_pending_size) {
tsi_result result = TSI_OK;
tsi_ssl_frame_protector* impl =
@ -1096,10 +1083,10 @@ static tsi_result tsi_set_min_and_max_tls_versions(
GPR_ASSERT(pending >= 0);
*still_pending_size = static_cast<size_t>(pending);
return TSI_OK;
}
}
static tsi_result ssl_protector_unprotect(
tsi_frame_protector * self, const unsigned char* protected_frames_bytes,
static tsi_result ssl_protector_unprotect(
tsi_frame_protector* self, const unsigned char* protected_frames_bytes,
size_t* protected_frames_bytes_size, unsigned char* unprotected_bytes,
size_t* unprotected_bytes_size) {
tsi_result result = TSI_OK;
@ -1123,8 +1110,7 @@ static tsi_result tsi_set_min_and_max_tls_versions(
/* Then, try to write some data to ssl. */
GPR_ASSERT(*protected_frames_bytes_size <= INT_MAX);
written_into_ssl =
BIO_write(impl->network_io, protected_frames_bytes,
written_into_ssl = BIO_write(impl->network_io, protected_frames_bytes,
static_cast<int>(*protected_frames_bytes_size));
if (written_into_ssl < 0) {
gpr_log(GPR_ERROR, "Sending protected frame to ssl failed with %d",
@ -1140,28 +1126,28 @@ static tsi_result tsi_set_min_and_max_tls_versions(
*unprotected_bytes_size += output_bytes_offset;
}
return result;
}
}
static void ssl_protector_destroy(tsi_frame_protector * self) {
static void ssl_protector_destroy(tsi_frame_protector* self) {
tsi_ssl_frame_protector* impl =
reinterpret_cast<tsi_ssl_frame_protector*>(self);
if (impl->buffer != nullptr) gpr_free(impl->buffer);
if (impl->ssl != nullptr) SSL_free(impl->ssl);
if (impl->network_io != nullptr) BIO_free(impl->network_io);
gpr_free(self);
}
}
static const tsi_frame_protector_vtable frame_protector_vtable = {
static const tsi_frame_protector_vtable frame_protector_vtable = {
ssl_protector_protect,
ssl_protector_protect_flush,
ssl_protector_unprotect,
ssl_protector_destroy,
};
};
/* --- tsi_server_handshaker_factory methods implementation. --- */
/* --- tsi_server_handshaker_factory methods implementation. --- */
static void tsi_ssl_handshaker_factory_destroy(tsi_ssl_handshaker_factory *
factory) {
static void tsi_ssl_handshaker_factory_destroy(
tsi_ssl_handshaker_factory* factory) {
if (factory == nullptr) return;
if (factory->vtable != nullptr && factory->vtable->destroy != nullptr) {
@ -1170,40 +1156,39 @@ static tsi_result tsi_set_min_and_max_tls_versions(
/* Note, we don't free(self) here because this object is always directly
* embedded in another object. If tsi_ssl_handshaker_factory_init allocates
* any memory, it should be free'd here. */
}
}
static tsi_ssl_handshaker_factory* tsi_ssl_handshaker_factory_ref(
tsi_ssl_handshaker_factory * factory) {
static tsi_ssl_handshaker_factory* tsi_ssl_handshaker_factory_ref(
tsi_ssl_handshaker_factory* factory) {
if (factory == nullptr) return nullptr;
gpr_refn(&factory->refcount, 1);
return factory;
}
}
static void tsi_ssl_handshaker_factory_unref(tsi_ssl_handshaker_factory *
factory) {
static void tsi_ssl_handshaker_factory_unref(
tsi_ssl_handshaker_factory* factory) {
if (factory == nullptr) return;
if (gpr_unref(&factory->refcount)) {
tsi_ssl_handshaker_factory_destroy(factory);
}
}
}
static tsi_ssl_handshaker_factory_vtable handshaker_factory_vtable = {
nullptr};
static tsi_ssl_handshaker_factory_vtable handshaker_factory_vtable = {nullptr};
/* Initializes a tsi_ssl_handshaker_factory object. Caller is responsible for
/* Initializes a tsi_ssl_handshaker_factory object. Caller is responsible for
* allocating memory for the factory. */
static void tsi_ssl_handshaker_factory_init(tsi_ssl_handshaker_factory *
factory) {
static void tsi_ssl_handshaker_factory_init(
tsi_ssl_handshaker_factory* factory) {
GPR_ASSERT(factory != nullptr);
factory->vtable = &handshaker_factory_vtable;
gpr_ref_init(&factory->refcount, 1);
}
}
/* Gets the X509 cert chain in PEM format as a tsi_peer_property. */
tsi_result tsi_ssl_get_cert_chain_contents(STACK_OF(X509) * peer_chain,
tsi_peer_property * property) {
/* Gets the X509 cert chain in PEM format as a tsi_peer_property. */
tsi_result tsi_ssl_get_cert_chain_contents(STACK_OF(X509) * peer_chain,
tsi_peer_property* property) {
BIO* bio = BIO_new(BIO_s_mem());
const auto peer_chain_len = sk_X509_num(peer_chain);
for (auto i = decltype(peer_chain_len){0}; i < peer_chain_len; i++) {
@ -1223,10 +1208,10 @@ static tsi_result tsi_set_min_and_max_tls_versions(
property);
BIO_free(bio);
return result;
}
}
/* --- tsi_handshaker_result methods implementation. ---*/
static tsi_result ssl_handshaker_result_extract_peer(
/* --- tsi_handshaker_result methods implementation. ---*/
static tsi_result ssl_handshaker_result_extract_peer(
const tsi_handshaker_result* self, tsi_peer* peer) {
tsi_result result = TSI_OK;
const unsigned char* alpn_selected = nullptr;
@ -1284,19 +1269,17 @@ static tsi_result tsi_set_min_and_max_tls_versions(
if (result != TSI_OK) return result;
peer->property_count++;
const char* session_reused =
SSL_session_reused(impl->ssl) ? "true" : "false";
const char* session_reused = SSL_session_reused(impl->ssl) ? "true" : "false";
result = tsi_construct_string_peer_property_from_cstring(
TSI_SSL_SESSION_REUSED_PEER_PROPERTY, session_reused,
&peer->properties[peer->property_count]);
if (result != TSI_OK) return result;
peer->property_count++;
return result;
}
}
static tsi_result ssl_handshaker_result_create_frame_protector(
const tsi_handshaker_result* self,
size_t* max_output_protected_frame_size,
static tsi_result ssl_handshaker_result_create_frame_protector(
const tsi_handshaker_result* self, size_t* max_output_protected_frame_size,
tsi_frame_protector** protector) {
size_t actual_max_output_protected_frame_size =
TSI_SSL_MAX_PROTECTED_FRAME_SIZE_UPPER_BOUND;
@ -1319,8 +1302,8 @@ static tsi_result tsi_set_min_and_max_tls_versions(
}
actual_max_output_protected_frame_size = *max_output_protected_frame_size;
}
protector_impl->buffer_size = actual_max_output_protected_frame_size -
TSI_SSL_MAX_PROTECTION_OVERHEAD;
protector_impl->buffer_size =
actual_max_output_protected_frame_size - TSI_SSL_MAX_PROTECTION_OVERHEAD;
protector_impl->buffer =
static_cast<unsigned char*>(gpr_malloc(protector_impl->buffer_size));
if (protector_impl->buffer == nullptr) {
@ -1338,9 +1321,9 @@ static tsi_result tsi_set_min_and_max_tls_versions(
protector_impl->base.vtable = &frame_protector_vtable;
*protector = &protector_impl->base;
return TSI_OK;
}
}
static tsi_result ssl_handshaker_result_get_unused_bytes(
static tsi_result ssl_handshaker_result_get_unused_bytes(
const tsi_handshaker_result* self, const unsigned char** bytes,
size_t* bytes_size) {
const tsi_ssl_handshaker_result* impl =
@ -1348,27 +1331,27 @@ static tsi_result tsi_set_min_and_max_tls_versions(
*bytes_size = impl->unused_bytes_size;
*bytes = impl->unused_bytes;
return TSI_OK;
}
}
static void ssl_handshaker_result_destroy(tsi_handshaker_result * self) {
static void ssl_handshaker_result_destroy(tsi_handshaker_result* self) {
tsi_ssl_handshaker_result* impl =
reinterpret_cast<tsi_ssl_handshaker_result*>(self);
SSL_free(impl->ssl);
BIO_free(impl->network_io);
gpr_free(impl->unused_bytes);
gpr_free(impl);
}
}
static const tsi_handshaker_result_vtable handshaker_result_vtable = {
static const tsi_handshaker_result_vtable handshaker_result_vtable = {
ssl_handshaker_result_extract_peer,
nullptr, /* create_zero_copy_grpc_protector */
ssl_handshaker_result_create_frame_protector,
ssl_handshaker_result_get_unused_bytes,
ssl_handshaker_result_destroy,
};
};
static tsi_result ssl_handshaker_result_create(
tsi_ssl_handshaker * handshaker, unsigned char* unused_bytes,
static tsi_result ssl_handshaker_result_create(
tsi_ssl_handshaker* handshaker, unsigned char* unused_bytes,
size_t unused_bytes_size, tsi_handshaker_result** handshaker_result) {
if (handshaker == nullptr || handshaker_result == nullptr ||
(unused_bytes_size > 0 && unused_bytes == nullptr)) {
@ -1387,12 +1370,12 @@ static tsi_result tsi_set_min_and_max_tls_versions(
result->unused_bytes_size = unused_bytes_size;
*handshaker_result = &result->base;
return TSI_OK;
}
}
/* --- tsi_handshaker methods implementation. ---*/
/* --- tsi_handshaker methods implementation. ---*/
static tsi_result ssl_handshaker_get_bytes_to_send_to_peer(
tsi_ssl_handshaker * impl, unsigned char* bytes, size_t* bytes_size) {
static tsi_result ssl_handshaker_get_bytes_to_send_to_peer(
tsi_ssl_handshaker* impl, unsigned char* bytes, size_t* bytes_size) {
int bytes_read_from_ssl = 0;
if (bytes == nullptr || bytes_size == nullptr || *bytes_size == 0 ||
*bytes_size > INT_MAX) {
@ -1412,19 +1395,18 @@ static tsi_result tsi_set_min_and_max_tls_versions(
}
*bytes_size = static_cast<size_t>(bytes_read_from_ssl);
return BIO_pending(impl->network_io) == 0 ? TSI_OK : TSI_INCOMPLETE_DATA;
}
}
static tsi_result ssl_handshaker_get_result(tsi_ssl_handshaker * impl) {
static tsi_result ssl_handshaker_get_result(tsi_ssl_handshaker* impl) {
if ((impl->result == TSI_HANDSHAKE_IN_PROGRESS) &&
SSL_is_init_finished(impl->ssl)) {
impl->result = TSI_OK;
}
return impl->result;
}
}
static tsi_result ssl_handshaker_process_bytes_from_peer(
tsi_ssl_handshaker * impl, const unsigned char* bytes,
size_t* bytes_size) {
static tsi_result ssl_handshaker_process_bytes_from_peer(
tsi_ssl_handshaker* impl, const unsigned char* bytes, size_t* bytes_size) {
int bytes_written_into_ssl_size = 0;
if (bytes == nullptr || bytes_size == nullptr || *bytes_size > INT_MAX) {
return TSI_INVALID_ARGUMENT;
@ -1466,20 +1448,20 @@ static tsi_result tsi_set_min_and_max_tls_versions(
}
}
}
}
}
static void ssl_handshaker_destroy(tsi_handshaker * self) {
static void ssl_handshaker_destroy(tsi_handshaker* self) {
tsi_ssl_handshaker* impl = reinterpret_cast<tsi_ssl_handshaker*>(self);
SSL_free(impl->ssl);
BIO_free(impl->network_io);
gpr_free(impl->outgoing_bytes_buffer);
tsi_ssl_handshaker_factory_unref(impl->factory_ref);
gpr_free(impl);
}
}
// Removes the bytes remaining in |impl->SSL|'s read BIO and writes them to
// |bytes_remaining|.
static tsi_result ssl_bytes_remaining(tsi_ssl_handshaker * impl,
// Removes the bytes remaining in |impl->SSL|'s read BIO and writes them to
// |bytes_remaining|.
static tsi_result ssl_bytes_remaining(tsi_ssl_handshaker* impl,
unsigned char** bytes_remaining,
size_t* bytes_remaining_size) {
if (impl == nullptr || bytes_remaining == nullptr ||
@ -1494,8 +1476,8 @@ static tsi_result tsi_set_min_and_max_tls_versions(
*bytes_remaining = static_cast<uint8_t*>(gpr_malloc(bytes_in_ssl));
int bytes_read = BIO_read(SSL_get_rbio(impl->ssl), *bytes_remaining,
static_cast<int>(bytes_in_ssl));
// If an unexpected number of bytes were read, return an error status and
// free all of the bytes that were read.
// If an unexpected number of bytes were read, return an error status and free
// all of the bytes that were read.
if (bytes_read < 0 || static_cast<size_t>(bytes_read) != bytes_in_ssl) {
gpr_log(GPR_ERROR,
"Failed to read the expected number of bytes from SSL object.");
@ -1505,10 +1487,10 @@ static tsi_result tsi_set_min_and_max_tls_versions(
}
*bytes_remaining_size = static_cast<size_t>(bytes_read);
return TSI_OK;
}
}
static tsi_result ssl_handshaker_next(
tsi_handshaker * self, const unsigned char* received_bytes,
static tsi_result ssl_handshaker_next(
tsi_handshaker* self, const unsigned char* received_bytes,
size_t received_bytes_size, const unsigned char** bytes_to_send,
size_t* bytes_to_send_size, tsi_handshaker_result** handshaker_result,
tsi_handshaker_on_next_done_cb /*cb*/, void* /*user_data*/) {
@ -1548,9 +1530,9 @@ static tsi_result tsi_set_min_and_max_tls_versions(
*handshaker_result = nullptr;
} else {
// Any bytes that remain in |impl->ssl|'s read BIO after the handshake is
// complete must be extracted and set to the unused bytes of the
// handshaker result. This indicates to the gRPC stack that there are
// bytes from the peer that must be processed.
// complete must be extracted and set to the unused bytes of the handshaker
// result. This indicates to the gRPC stack that there are bytes from the
// peer that must be processed.
unsigned char* unused_bytes = nullptr;
size_t unused_bytes_size = 0;
status = ssl_bytes_remaining(impl, &unused_bytes, &unused_bytes_size);
@ -1560,18 +1542,18 @@ static tsi_result tsi_set_min_and_max_tls_versions(
gpr_free(unused_bytes);
return TSI_INTERNAL_ERROR;
}
status = ssl_handshaker_result_create(
impl, unused_bytes, unused_bytes_size, handshaker_result);
status = ssl_handshaker_result_create(impl, unused_bytes, unused_bytes_size,
handshaker_result);
if (status == TSI_OK) {
/* Indicates that the handshake has completed and that a
* handshaker_result has been created. */
/* Indicates that the handshake has completed and that a handshaker_result
* has been created. */
self->handshaker_result_created = true;
}
}
return status;
}
}
static const tsi_handshaker_vtable handshaker_vtable = {
static const tsi_handshaker_vtable handshaker_vtable = {
nullptr, /* get_bytes_to_send_to_peer -- deprecated */
nullptr, /* process_bytes_from_peer -- deprecated */
nullptr, /* get_result -- deprecated */
@ -1580,14 +1562,13 @@ static tsi_result tsi_set_min_and_max_tls_versions(
ssl_handshaker_destroy,
ssl_handshaker_next,
nullptr, /* shutdown */
};
};
/* --- tsi_ssl_handshaker_factory common methods. --- */
/* --- tsi_ssl_handshaker_factory common methods. --- */
static void tsi_ssl_handshaker_resume_session(
SSL * ssl, tsi::SslSessionLRUCache * session_cache) {
const char* server_name =
SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
static void tsi_ssl_handshaker_resume_session(
SSL* ssl, tsi::SslSessionLRUCache* session_cache) {
const char* server_name = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
if (server_name == nullptr) {
return;
}
@ -1596,11 +1577,12 @@ static tsi_result tsi_set_min_and_max_tls_versions(
// SSL_set_session internally increments reference counter.
SSL_set_session(ssl, session.get());
}
}
}
static tsi_result create_tsi_ssl_handshaker(
SSL_CTX * ctx, int is_client, const char* server_name_indication,
tsi_ssl_handshaker_factory* factory, tsi_handshaker** handshaker) {
static tsi_result create_tsi_ssl_handshaker(SSL_CTX* ctx, int is_client,
const char* server_name_indication,
tsi_ssl_handshaker_factory* factory,
tsi_handshaker** handshaker) {
SSL* ssl = SSL_new(ctx);
BIO* network_io = nullptr;
BIO* ssl_io = nullptr;
@ -1642,8 +1624,7 @@ static tsi_result tsi_set_min_and_max_tls_versions(
ssl_result = SSL_do_handshake(ssl);
ssl_result = SSL_get_error(ssl, ssl_result);
if (ssl_result != SSL_ERROR_WANT_READ) {
gpr_log(
GPR_ERROR,
gpr_log(GPR_ERROR,
"Unexpected error received from first SSL_do_handshake call: %s",
ssl_error_string(ssl_result));
SSL_free(ssl);
@ -1660,18 +1641,20 @@ static tsi_result tsi_set_min_and_max_tls_versions(
impl->result = TSI_HANDSHAKE_IN_PROGRESS;
impl->outgoing_bytes_buffer_size =
TSI_SSL_HANDSHAKER_OUTGOING_BUFFER_INITIAL_SIZE;
impl->outgoing_bytes_buffer = static_cast<unsigned char*>(
gpr_zalloc(impl->outgoing_bytes_buffer_size));
impl->outgoing_bytes_buffer =
static_cast<unsigned char*>(gpr_zalloc(impl->outgoing_bytes_buffer_size));
impl->base.vtable = &handshaker_vtable;
impl->factory_ref = tsi_ssl_handshaker_factory_ref(factory);
*handshaker = &impl->base;
return TSI_OK;
}
}
static int select_protocol_list(
const unsigned char** out, unsigned char* outlen,
const unsigned char* client_list, size_t client_list_len,
const unsigned char* server_list, size_t server_list_len) {
static int select_protocol_list(const unsigned char** out,
unsigned char* outlen,
const unsigned char* client_list,
size_t client_list_len,
const unsigned char* server_list,
size_t server_list_len) {
const unsigned char* client_current = client_list;
while (static_cast<unsigned int>(client_current - client_list) <
client_list_len) {
@ -1692,26 +1675,26 @@ static tsi_result tsi_set_min_and_max_tls_versions(
client_current += client_current_len;
}
return SSL_TLSEXT_ERR_NOACK;
}
}
/* --- tsi_ssl_client_handshaker_factory methods implementation. --- */
/* --- tsi_ssl_client_handshaker_factory methods implementation. --- */
tsi_result tsi_ssl_client_handshaker_factory_create_handshaker(
tsi_ssl_client_handshaker_factory * factory,
tsi_result tsi_ssl_client_handshaker_factory_create_handshaker(
tsi_ssl_client_handshaker_factory* factory,
const char* server_name_indication, tsi_handshaker** handshaker) {
return create_tsi_ssl_handshaker(factory->ssl_context, 1,
server_name_indication, &factory->base,
handshaker);
}
}
void tsi_ssl_client_handshaker_factory_unref(
tsi_ssl_client_handshaker_factory * factory) {
void tsi_ssl_client_handshaker_factory_unref(
tsi_ssl_client_handshaker_factory* factory) {
if (factory == nullptr) return;
tsi_ssl_handshaker_factory_unref(&factory->base);
}
}
static void tsi_ssl_client_handshaker_factory_destroy(
tsi_ssl_handshaker_factory * factory) {
static void tsi_ssl_client_handshaker_factory_destroy(
tsi_ssl_handshaker_factory* factory) {
if (factory == nullptr) return;
tsi_ssl_client_handshaker_factory* self =
reinterpret_cast<tsi_ssl_client_handshaker_factory*>(factory);
@ -1719,9 +1702,9 @@ static tsi_result tsi_set_min_and_max_tls_versions(
if (self->alpn_protocol_list != nullptr) gpr_free(self->alpn_protocol_list);
self->session_cache.reset();
gpr_free(self);
}
}
static int client_handshaker_factory_npn_callback(
static int client_handshaker_factory_npn_callback(
SSL* /*ssl*/, unsigned char** out, unsigned char* outlen,
const unsigned char* in, unsigned int inlen, void* arg) {
tsi_ssl_client_handshaker_factory* factory =
@ -1729,28 +1712,27 @@ static tsi_result tsi_set_min_and_max_tls_versions(
return select_protocol_list(const_cast<const unsigned char**>(out), outlen,
factory->alpn_protocol_list,
factory->alpn_protocol_list_length, in, inlen);
}
}
/* --- tsi_ssl_server_handshaker_factory methods implementation. --- */
/* --- tsi_ssl_server_handshaker_factory methods implementation. --- */
tsi_result tsi_ssl_server_handshaker_factory_create_handshaker(
tsi_ssl_server_handshaker_factory * factory,
tsi_handshaker * *handshaker) {
tsi_result tsi_ssl_server_handshaker_factory_create_handshaker(
tsi_ssl_server_handshaker_factory* factory, tsi_handshaker** handshaker) {
if (factory->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(factory->ssl_contexts[0], 0, nullptr,
&factory->base, handshaker);
}
}
void tsi_ssl_server_handshaker_factory_unref(
tsi_ssl_server_handshaker_factory * factory) {
void tsi_ssl_server_handshaker_factory_unref(
tsi_ssl_server_handshaker_factory* factory) {
if (factory == nullptr) return;
tsi_ssl_handshaker_factory_unref(&factory->base);
}
}
static void tsi_ssl_server_handshaker_factory_destroy(
tsi_ssl_handshaker_factory * factory) {
static void tsi_ssl_server_handshaker_factory_destroy(
tsi_ssl_handshaker_factory* factory) {
if (factory == nullptr) return;
tsi_ssl_server_handshaker_factory* self =
reinterpret_cast<tsi_ssl_server_handshaker_factory*>(factory);
@ -1767,9 +1749,9 @@ static tsi_result tsi_set_min_and_max_tls_versions(
}
if (self->alpn_protocol_list != nullptr) gpr_free(self->alpn_protocol_list);
gpr_free(self);
}
}
static int does_entry_match_name(absl::string_view entry,
static int does_entry_match_name(absl::string_view entry,
absl::string_view name) {
if (entry.empty()) return 0;
@ -1808,10 +1790,11 @@ static tsi_result tsi_set_min_and_max_tls_versions(
name_subdomain.remove_suffix(1);
}
return !entry.empty() && absl::EqualsIgnoreCase(name_subdomain, entry);
}
}
static int ssl_server_handshaker_factory_servername_callback(
SSL * ssl, int* /*ap*/, void* arg) {
static int ssl_server_handshaker_factory_servername_callback(SSL* ssl,
int* /*ap*/,
void* arg) {
tsi_ssl_server_handshaker_factory* impl =
static_cast<tsi_ssl_server_handshaker_factory*>(arg);
size_t i = 0;
@ -1829,10 +1812,10 @@ static tsi_result tsi_set_min_and_max_tls_versions(
}
gpr_log(GPR_ERROR, "No match found for server name: %s.", servername);
return SSL_TLSEXT_ERR_NOACK;
}
}
#if TSI_OPENSSL_ALPN_SUPPORT
static int server_handshaker_factory_alpn_callback(
static int server_handshaker_factory_alpn_callback(
SSL* /*ssl*/, const unsigned char** out, unsigned char* outlen,
const unsigned char* in, unsigned int inlen, void* arg) {
tsi_ssl_server_handshaker_factory* factory =
@ -1840,28 +1823,27 @@ static tsi_result tsi_set_min_and_max_tls_versions(
return select_protocol_list(out, outlen, in, inlen,
factory->alpn_protocol_list,
factory->alpn_protocol_list_length);
}
}
#endif /* TSI_OPENSSL_ALPN_SUPPORT */
static int server_handshaker_factory_npn_advertised_callback(
SSL* /*ssl*/, const unsigned char** out, unsigned int* outlen,
void* arg) {
static int server_handshaker_factory_npn_advertised_callback(
SSL* /*ssl*/, const unsigned char** out, unsigned int* outlen, void* arg) {
tsi_ssl_server_handshaker_factory* factory =
static_cast<tsi_ssl_server_handshaker_factory*>(arg);
*out = factory->alpn_protocol_list;
GPR_ASSERT(factory->alpn_protocol_list_length <= UINT_MAX);
*outlen = static_cast<unsigned int>(factory->alpn_protocol_list_length);
return SSL_TLSEXT_ERR_OK;
}
}
/// This callback is called when new \a session is established and ready to
/// be cached. This session can be reused for new connections to similar
/// servers at later point of time.
/// It's intended to be used with SSL_CTX_sess_set_new_cb function.
///
/// It returns 1 if callback takes ownership over \a session and 0 otherwise.
static int server_handshaker_factory_new_session_callback(
SSL * ssl, SSL_SESSION * session) {
/// This callback is called when new \a session is established and ready to
/// be cached. This session can be reused for new connections to similar
/// servers at later point of time.
/// It's intended to be used with SSL_CTX_sess_set_new_cb function.
///
/// It returns 1 if callback takes ownership over \a session and 0 otherwise.
static int server_handshaker_factory_new_session_callback(
SSL* ssl, SSL_SESSION* session) {
SSL_CTX* ssl_context = SSL_get_SSL_CTX(ssl);
if (ssl_context == nullptr) {
return 0;
@ -1869,22 +1851,21 @@ static tsi_result tsi_set_min_and_max_tls_versions(
void* arg = SSL_CTX_get_ex_data(ssl_context, g_ssl_ctx_ex_factory_index);
tsi_ssl_client_handshaker_factory* factory =
static_cast<tsi_ssl_client_handshaker_factory*>(arg);
const char* server_name =
SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
const char* server_name = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
if (server_name == nullptr) {
return 0;
}
factory->session_cache->Put(server_name, tsi::SslSessionPtr(session));
// Return 1 to indicate transferred ownership over the given session.
return 1;
}
}
/* --- tsi_ssl_handshaker_factory constructors. --- */
/* --- tsi_ssl_handshaker_factory constructors. --- */
static tsi_ssl_handshaker_factory_vtable client_handshaker_factory_vtable = {
static tsi_ssl_handshaker_factory_vtable client_handshaker_factory_vtable = {
tsi_ssl_client_handshaker_factory_destroy};
tsi_result tsi_create_ssl_client_handshaker_factory(
tsi_result tsi_create_ssl_client_handshaker_factory(
const tsi_ssl_pem_key_cert_pair* pem_key_cert_pair,
const char* pem_root_certs, const char* cipher_suites,
const char** alpn_protocols, uint16_t num_alpn_protocols,
@ -1897,9 +1878,9 @@ static tsi_result tsi_set_min_and_max_tls_versions(
options.num_alpn_protocols = num_alpn_protocols;
return tsi_create_ssl_client_handshaker_factory_with_options(&options,
factory);
}
}
tsi_result tsi_create_ssl_client_handshaker_factory_with_options(
tsi_result tsi_create_ssl_client_handshaker_factory_with_options(
const tsi_ssl_client_handshaker_options* options,
tsi_ssl_client_handshaker_factory** factory) {
SSL_CTX* ssl_context = nullptr;
@ -1955,11 +1936,10 @@ static tsi_result tsi_set_min_and_max_tls_versions(
SSL_CTX_set_cert_store(ssl_context, options->root_store->store);
}
#endif
if (OPENSSL_VERSION_NUMBER < 0x10100000 ||
options->root_store == nullptr) {
if (OPENSSL_VERSION_NUMBER < 0x10100000 || options->root_store == nullptr) {
result = ssl_ctx_load_verification_certs(
ssl_context, options->pem_root_certs,
strlen(options->pem_root_certs), nullptr);
ssl_context, options->pem_root_certs, strlen(options->pem_root_certs),
nullptr);
if (result != TSI_OK) {
gpr_log(GPR_ERROR, "Cannot load server root certificates.");
break;
@ -2002,12 +1982,12 @@ static tsi_result tsi_set_min_and_max_tls_versions(
*factory = impl;
return TSI_OK;
}
}
static tsi_ssl_handshaker_factory_vtable server_handshaker_factory_vtable = {
static tsi_ssl_handshaker_factory_vtable server_handshaker_factory_vtable = {
tsi_ssl_server_handshaker_factory_destroy};
tsi_result tsi_create_ssl_server_handshaker_factory(
tsi_result tsi_create_ssl_server_handshaker_factory(
const tsi_ssl_pem_key_cert_pair* pem_key_cert_pairs,
size_t num_key_cert_pairs, const char* pem_client_root_certs,
int force_client_auth, const char* cipher_suites,
@ -2015,19 +1995,17 @@ static tsi_result tsi_set_min_and_max_tls_versions(
tsi_ssl_server_handshaker_factory** factory) {
return tsi_create_ssl_server_handshaker_factory_ex(
pem_key_cert_pairs, num_key_cert_pairs, pem_client_root_certs,
force_client_auth
? TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY
force_client_auth ? TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY
: TSI_DONT_REQUEST_CLIENT_CERTIFICATE,
cipher_suites, alpn_protocols, num_alpn_protocols, factory);
}
}
tsi_result tsi_create_ssl_server_handshaker_factory_ex(
tsi_result tsi_create_ssl_server_handshaker_factory_ex(
const tsi_ssl_pem_key_cert_pair* pem_key_cert_pairs,
size_t num_key_cert_pairs, const char* pem_client_root_certs,
tsi_client_certificate_request_type client_certificate_request,
const char* cipher_suites, const char** alpn_protocols,
uint16_t num_alpn_protocols,
tsi_ssl_server_handshaker_factory** factory) {
uint16_t num_alpn_protocols, tsi_ssl_server_handshaker_factory** factory) {
tsi_ssl_server_handshaker_options options;
options.pem_key_cert_pairs = pem_key_cert_pairs;
options.num_key_cert_pairs = num_key_cert_pairs;
@ -2038,9 +2016,9 @@ static tsi_result tsi_set_min_and_max_tls_versions(
options.num_alpn_protocols = num_alpn_protocols;
return tsi_create_ssl_server_handshaker_factory_with_options(&options,
factory);
}
}
tsi_result tsi_create_ssl_server_handshaker_factory_with_options(
tsi_result tsi_create_ssl_server_handshaker_factory_with_options(
const tsi_ssl_server_handshaker_options* options,
tsi_ssl_server_handshaker_factory** factory) {
tsi_ssl_server_handshaker_factory* impl = nullptr;
@ -2149,15 +2127,14 @@ static tsi_result tsi_set_min_and_max_tls_versions(
SSL_CTX_set_verify(impl->ssl_contexts[i], SSL_VERIFY_PEER, nullptr);
break;
case TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY:
SSL_CTX_set_verify(
impl->ssl_contexts[i],
SSL_CTX_set_verify(impl->ssl_contexts[i],
SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
NullVerifyCallback);
break;
case TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY:
SSL_CTX_set_verify(
impl->ssl_contexts[i],
SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
SSL_CTX_set_verify(impl->ssl_contexts[i],
SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
nullptr);
break;
}
/* TODO(jboeuf): Add revocation verification. */
@ -2173,8 +2150,7 @@ static tsi_result tsi_set_min_and_max_tls_versions(
SSL_CTX_set_tlsext_servername_arg(impl->ssl_contexts[i], impl);
#if TSI_OPENSSL_ALPN_SUPPORT
SSL_CTX_set_alpn_select_cb(impl->ssl_contexts[i],
server_handshaker_factory_alpn_callback,
impl);
server_handshaker_factory_alpn_callback, impl);
#endif /* TSI_OPENSSL_ALPN_SUPPORT */
SSL_CTX_set_next_protos_advertised_cb(
impl->ssl_contexts[i],
@ -2189,11 +2165,11 @@ static tsi_result tsi_set_min_and_max_tls_versions(
*factory = impl;
return TSI_OK;
}
}
/* --- tsi_ssl utils. --- */
/* --- tsi_ssl utils. --- */
int tsi_ssl_peer_matches_name(const tsi_peer* peer, absl::string_view name) {
int tsi_ssl_peer_matches_name(const tsi_peer* peer, absl::string_view name) {
size_t i = 0;
size_t san_count = 0;
const tsi_peer_property* cn_property = nullptr;
@ -2230,17 +2206,16 @@ static tsi_result tsi_set_min_and_max_tls_versions(
}
return 0; /* Not found. */
}
}
/* --- Testing support. --- */
const tsi_ssl_handshaker_factory_vtable*
tsi_ssl_handshaker_factory_swap_vtable(
tsi_ssl_handshaker_factory * factory,
tsi_ssl_handshaker_factory_vtable * new_vtable) {
/* --- Testing support. --- */
const tsi_ssl_handshaker_factory_vtable* tsi_ssl_handshaker_factory_swap_vtable(
tsi_ssl_handshaker_factory* factory,
tsi_ssl_handshaker_factory_vtable* new_vtable) {
GPR_ASSERT(factory != nullptr);
GPR_ASSERT(factory->vtable != nullptr);
const tsi_ssl_handshaker_factory_vtable* orig_vtable = factory->vtable;
factory->vtable = new_vtable;
return orig_vtable;
}
}

Loading…
Cancel
Save