From f26a925cb8fa4bdf707c28421ac90833c571b6c9 Mon Sep 17 00:00:00 2001 From: Andrey Ermolov Date: Sun, 20 Aug 2023 04:45:20 +0000 Subject: [PATCH 1/2] create vtable structure for local peer --- .../alts/handshaker/alts_tsi_handshaker.cc | 69 +++++++++++++++++++ src/core/tsi/fake_transport_security.cc | 17 +++++ src/core/tsi/local_transport_security.cc | 6 ++ src/core/tsi/ssl_transport_security.cc | 68 ++++++++++++++++++ src/core/tsi/transport_security.cc | 10 +++ src/core/tsi/transport_security.h | 1 + src/core/tsi/transport_security_interface.h | 6 ++ 7 files changed, 177 insertions(+) diff --git a/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc b/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc index 9b0ab25af660f..f85c07f68a555 100644 --- a/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +++ b/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc @@ -154,6 +154,74 @@ static tsi_result handshaker_result_extract_peer( return ok; } +static tsi_result handshaker_result_extract_local_peer( + const tsi_handshaker_result* self, tsi_peer* local_peer) { + if (self == nullptr || local_peer == nullptr) { + gpr_log(GPR_ERROR, "Invalid argument to handshaker_result_extract_peer()"); + return TSI_INVALID_ARGUMENT; + } + alts_tsi_handshaker_result* result = + reinterpret_cast( + const_cast(self)); + GPR_ASSERT(kTsiAltsNumOfPeerProperties == 5); + tsi_result ok = tsi_construct_peer(kTsiAltsNumOfPeerProperties, local_peer); + int index = 0; + if (ok != TSI_OK) { + gpr_log(GPR_ERROR, "Failed to construct tsi peer"); + return ok; + } + GPR_ASSERT(&local_peer->properties[index] != nullptr); + ok = tsi_construct_string_peer_property_from_cstring( + TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_ALTS_CERTIFICATE_TYPE, + &local_peer->properties[index]); + if (ok != TSI_OK) { + tsi_peer_destruct(local_peer); + gpr_log(GPR_ERROR, "Failed to set tsi peer property"); + return ok; + } + index++; + GPR_ASSERT(&local_peer->properties[index] != nullptr); + ok = tsi_construct_string_peer_property_from_cstring( + TSI_ALTS_SERVICE_ACCOUNT_PEER_PROPERTY, result->peer_identity, + &local_peer->properties[index]); + if (ok != TSI_OK) { + tsi_peer_destruct(local_peer); + gpr_log(GPR_ERROR, "Failed to set tsi peer property"); + } + index++; + GPR_ASSERT(&local_peer->properties[index] != nullptr); + ok = tsi_construct_string_peer_property( + TSI_ALTS_RPC_VERSIONS, + reinterpret_cast(GRPC_SLICE_START_PTR(result->rpc_versions)), + GRPC_SLICE_LENGTH(result->rpc_versions), &local_peer->properties[index]); + if (ok != TSI_OK) { + tsi_peer_destruct(local_peer); + gpr_log(GPR_ERROR, "Failed to set tsi peer property"); + } + index++; + GPR_ASSERT(&local_peer->properties[index] != nullptr); + ok = tsi_construct_string_peer_property( + TSI_ALTS_CONTEXT, + reinterpret_cast(GRPC_SLICE_START_PTR(result->serialized_context)), + GRPC_SLICE_LENGTH(result->serialized_context), &local_peer->properties[index]); + if (ok != TSI_OK) { + tsi_peer_destruct(local_peer); + gpr_log(GPR_ERROR, "Failed to set tsi peer property"); + } + index++; + GPR_ASSERT(&local_peer->properties[index] != nullptr); + ok = tsi_construct_string_peer_property_from_cstring( + TSI_SECURITY_LEVEL_PEER_PROPERTY, + tsi_security_level_to_string(TSI_PRIVACY_AND_INTEGRITY), + &local_peer->properties[index]); + if (ok != TSI_OK) { + tsi_peer_destruct(local_peer); + gpr_log(GPR_ERROR, "Failed to set tsi peer property"); + } + GPR_ASSERT(++index == kTsiAltsNumOfPeerProperties); + return ok; +} + static tsi_result handshaker_result_get_frame_protector_type( const tsi_handshaker_result* /*self*/, tsi_frame_protector_type* frame_protector_type) { @@ -257,6 +325,7 @@ static void handshaker_result_destroy(tsi_handshaker_result* self) { static const tsi_handshaker_result_vtable result_vtable = { handshaker_result_extract_peer, + handshaker_result_extract_local_peer, handshaker_result_get_frame_protector_type, handshaker_result_create_zero_copy_grpc_protector, handshaker_result_create_frame_protector, diff --git a/src/core/tsi/fake_transport_security.cc b/src/core/tsi/fake_transport_security.cc index b1371dcfc7503..14232803bb9f4 100644 --- a/src/core/tsi/fake_transport_security.cc +++ b/src/core/tsi/fake_transport_security.cc @@ -545,6 +545,22 @@ static tsi_result fake_handshaker_result_extract_peer( return result; } +static tsi_result fake_handshaker_result_extract_local_peer( + const tsi_handshaker_result* /*self*/, tsi_peer* local_peer) { + // Construct a tsi_peer with 1 property: certificate type, security_level. + tsi_result result = tsi_construct_peer(2, local_peer); + if (result != TSI_OK) return result; + result = tsi_construct_string_peer_property_from_cstring( + TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_FAKE_CERTIFICATE_TYPE, + &local_peer->properties[0]); + if (result != TSI_OK) tsi_peer_destruct(local_peer); + result = tsi_construct_string_peer_property_from_cstring( + TSI_SECURITY_LEVEL_PEER_PROPERTY, + tsi_security_level_to_string(TSI_SECURITY_NONE), &local_peer->properties[1]); + if (result != TSI_OK) tsi_peer_destruct(local_peer); + return result; +} + static tsi_result fake_handshaker_result_get_frame_protector_type( const tsi_handshaker_result* /*self*/, tsi_frame_protector_type* frame_protector_type) { @@ -587,6 +603,7 @@ static void fake_handshaker_result_destroy(tsi_handshaker_result* self) { static const tsi_handshaker_result_vtable handshaker_result_vtable = { fake_handshaker_result_extract_peer, + fake_handshaker_result_extract_local_peer, fake_handshaker_result_get_frame_protector_type, fake_handshaker_result_create_zero_copy_grpc_protector, fake_handshaker_result_create_frame_protector, diff --git a/src/core/tsi/local_transport_security.cc b/src/core/tsi/local_transport_security.cc index 6b3668c528285..0c748dac63845 100644 --- a/src/core/tsi/local_transport_security.cc +++ b/src/core/tsi/local_transport_security.cc @@ -58,6 +58,11 @@ tsi_result handshaker_result_extract_peer(const tsi_handshaker_result* /*self*/, return TSI_OK; } +tsi_result handshaker_result_extract_local_peer(const tsi_handshaker_result* /*self*/, + tsi_peer* /*peer*/) { + return TSI_OK; +} + tsi_result handshaker_result_get_frame_protector_type( const tsi_handshaker_result* /*self*/, tsi_frame_protector_type* frame_protector_type) { @@ -92,6 +97,7 @@ void handshaker_result_destroy(tsi_handshaker_result* self) { const tsi_handshaker_result_vtable result_vtable = { handshaker_result_extract_peer, + handshaker_result_extract_local_peer, handshaker_result_get_frame_protector_type, nullptr, // handshaker_result_create_zero_copy_grpc_protector nullptr, // handshaker_result_create_frame_protector diff --git a/src/core/tsi/ssl_transport_security.cc b/src/core/tsi/ssl_transport_security.cc index 10e99d6be1140..90a37c8575a64 100644 --- a/src/core/tsi/ssl_transport_security.cc +++ b/src/core/tsi/ssl_transport_security.cc @@ -22,6 +22,7 @@ #include #include +#include // TODO(jboeuf): refactor inet_ntop into a portability header. // Note: for whomever reads this and tries to refactor this, this @@ -1253,6 +1254,57 @@ static tsi_result ssl_handshaker_result_extract_peer( return result; } +static tsi_result ssl_handshaker_result_extract_local_peer( + const tsi_handshaker_result* self, tsi_peer* local_peer) { + tsi_result result = TSI_OK; + const unsigned char* alpn_selected = nullptr; + unsigned int alpn_selected_len; + const tsi_ssl_handshaker_result* impl = + reinterpret_cast(self); + X509 *local_cert = SSL_get_certificate(impl->ssl); + if (local_cert != nullptr) { + result = peer_from_x509(local_cert, 1, local_peer); + X509_free(local_cert); + if (result != TSI_OK) return result; + } +#if TSI_OPENSSL_ALPN_SUPPORT + SSL_get0_alpn_selected(impl->ssl, &alpn_selected, &alpn_selected_len); +#endif // TSI_OPENSSL_ALPN_SUPPORT + if (alpn_selected == nullptr) { + // Try npn. + SSL_get0_next_proto_negotiated(impl->ssl, &alpn_selected, + &alpn_selected_len); + } + + // 1 is for session reused property. + size_t new_property_count = local_peer->property_count + 3; + if (alpn_selected != nullptr) new_property_count++; + tsi_peer_property* new_properties = static_cast( + gpr_zalloc(sizeof(*new_properties) * new_property_count)); + for (size_t i = 0; i < local_peer->property_count; i++) { + new_properties[i] = local_peer->properties[i]; + } + if (local_peer->properties != nullptr) gpr_free(local_peer->properties); + local_peer->properties = new_properties; + if (alpn_selected != nullptr) { + result = tsi_construct_string_peer_property( + TSI_SSL_ALPN_SELECTED_PROTOCOL, + reinterpret_cast(alpn_selected), alpn_selected_len, + &local_peer->properties[local_peer->property_count]); + if (result != TSI_OK) return result; + local_peer->property_count++; + } + // Add security_level peer property. + result = tsi_construct_string_peer_property_from_cstring( + TSI_SECURITY_LEVEL_PEER_PROPERTY, + tsi_security_level_to_string(TSI_PRIVACY_AND_INTEGRITY), + &local_peer->properties[local_peer->property_count]); + if (result != TSI_OK) return result; + local_peer->property_count++; + + return result; +} + static tsi_result ssl_handshaker_result_get_frame_protector_type( const tsi_handshaker_result* /*self*/, tsi_frame_protector_type* frame_protector_type) { @@ -1326,6 +1378,7 @@ static void ssl_handshaker_result_destroy(tsi_handshaker_result* self) { static const tsi_handshaker_result_vtable handshaker_result_vtable = { ssl_handshaker_result_extract_peer, + ssl_handshaker_result_extract_local_peer, ssl_handshaker_result_get_frame_protector_type, nullptr, // create_zero_copy_grpc_protector ssl_handshaker_result_create_frame_protector, @@ -1392,6 +1445,16 @@ static tsi_result ssl_handshaker_get_result(tsi_ssl_handshaker* impl) { return impl->result; } +void print_cert_info(X509 *cert) { + BIO *bio = BIO_new_fp(stdout, BIO_NOCLOSE); + X509_NAME_print_ex(bio, X509_get_subject_name(cert), 0, XN_FLAG_ONELINE); + BIO_puts(bio, "\n"); + X509_NAME_print_ex(bio, X509_get_issuer_name(cert), 0, XN_FLAG_ONELINE); + BIO_puts(bio, "\n"); + + BIO_free(bio); +} + static tsi_result ssl_handshaker_do_handshake(tsi_ssl_handshaker* impl, std::string* error) { if (ssl_handshaker_get_result(impl) != TSI_HANDSHAKE_IN_PROGRESS) { @@ -1402,6 +1465,11 @@ static tsi_result ssl_handshaker_do_handshake(tsi_ssl_handshaker* impl, // Get ready to get some bytes from SSL. int ssl_result = SSL_do_handshake(impl->ssl); ssl_result = SSL_get_error(impl->ssl, ssl_result); + printf("***** Handshake successful p\n"); + X509 *server_cert = SSL_get_certificate(impl->ssl); + if (server_cert) { + X509_print_fp(stderr, server_cert); + } switch (ssl_result) { case SSL_ERROR_WANT_READ: if (BIO_pending(impl->network_io) == 0) { diff --git a/src/core/tsi/transport_security.cc b/src/core/tsi/transport_security.cc index f9b13ea7d3652..bb9cdf3a01932 100644 --- a/src/core/tsi/transport_security.cc +++ b/src/core/tsi/transport_security.cc @@ -263,6 +263,16 @@ tsi_result tsi_handshaker_result_extract_peer(const tsi_handshaker_result* self, return self->vtable->extract_peer(self, peer); } +tsi_result tsi_handshaker_result_extract_local_peer(const tsi_handshaker_result* self, + tsi_peer* local_peer) { + if (self == nullptr || self->vtable == nullptr || local_peer == nullptr) { + return TSI_INVALID_ARGUMENT; + } + memset(local_peer, 0, sizeof(tsi_peer)); + if (self->vtable->extract_local_peer == nullptr) return TSI_UNIMPLEMENTED; + return self->vtable->extract_local_peer(self, local_peer); +} + tsi_result tsi_handshaker_result_get_frame_protector_type( const tsi_handshaker_result* self, tsi_frame_protector_type* frame_protector_type) { diff --git a/src/core/tsi/transport_security.h b/src/core/tsi/transport_security.h index 2c88cb6eb8b63..eeb72335726b3 100644 --- a/src/core/tsi/transport_security.h +++ b/src/core/tsi/transport_security.h @@ -100,6 +100,7 @@ struct tsi_handshaker { // struct tsi_handshaker_result_vtable { tsi_result (*extract_peer)(const tsi_handshaker_result* self, tsi_peer* peer); + tsi_result (*extract_local_peer)(const tsi_handshaker_result* self, tsi_peer* local_peer); tsi_result (*get_frame_protector_type)( const tsi_handshaker_result* self, tsi_frame_protector_type* frame_protector_type); diff --git a/src/core/tsi/transport_security_interface.h b/src/core/tsi/transport_security_interface.h index 37cc94c712743..a251194bd19d6 100644 --- a/src/core/tsi/transport_security_interface.h +++ b/src/core/tsi/transport_security_interface.h @@ -258,6 +258,12 @@ typedef struct tsi_handshaker_result tsi_handshaker_result; tsi_result tsi_handshaker_result_extract_peer(const tsi_handshaker_result* self, tsi_peer* peer); +// This method extracts tsi local peer. It returns TSI_OK assuming there is no fatal +// error. +// The caller is responsible for destructing the local peer. +tsi_result tsi_handshaker_result_extract_local_peer(const tsi_handshaker_result* self, + tsi_peer* local_peer); + // This method indicates what type of frame protector is provided by the // TSI implementation. tsi_result tsi_handshaker_result_get_frame_protector_type( From 2b63879becd19f57a5c31abdf1ea2163427e0719 Mon Sep 17 00:00:00 2001 From: erm-g Date: Sun, 20 Aug 2023 05:57:26 +0000 Subject: [PATCH 2/2] Automated change: Fix sanity tests --- .../alts/handshaker/alts_tsi_handshaker.cc | 3 ++- src/core/tsi/fake_transport_security.cc | 3 ++- src/core/tsi/local_transport_security.cc | 4 ++-- src/core/tsi/ssl_transport_security.cc | 21 ++++++++++--------- src/core/tsi/transport_security.cc | 4 ++-- src/core/tsi/transport_security.h | 3 ++- src/core/tsi/transport_security_interface.h | 9 ++++---- 7 files changed, 25 insertions(+), 22 deletions(-) diff --git a/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc b/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc index f85c07f68a555..c0aa0224dfd85 100644 --- a/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +++ b/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc @@ -203,7 +203,8 @@ static tsi_result handshaker_result_extract_local_peer( ok = tsi_construct_string_peer_property( TSI_ALTS_CONTEXT, reinterpret_cast(GRPC_SLICE_START_PTR(result->serialized_context)), - GRPC_SLICE_LENGTH(result->serialized_context), &local_peer->properties[index]); + GRPC_SLICE_LENGTH(result->serialized_context), + &local_peer->properties[index]); if (ok != TSI_OK) { tsi_peer_destruct(local_peer); gpr_log(GPR_ERROR, "Failed to set tsi peer property"); diff --git a/src/core/tsi/fake_transport_security.cc b/src/core/tsi/fake_transport_security.cc index 14232803bb9f4..76df7607a42ff 100644 --- a/src/core/tsi/fake_transport_security.cc +++ b/src/core/tsi/fake_transport_security.cc @@ -556,7 +556,8 @@ static tsi_result fake_handshaker_result_extract_local_peer( if (result != TSI_OK) tsi_peer_destruct(local_peer); result = tsi_construct_string_peer_property_from_cstring( TSI_SECURITY_LEVEL_PEER_PROPERTY, - tsi_security_level_to_string(TSI_SECURITY_NONE), &local_peer->properties[1]); + tsi_security_level_to_string(TSI_SECURITY_NONE), + &local_peer->properties[1]); if (result != TSI_OK) tsi_peer_destruct(local_peer); return result; } diff --git a/src/core/tsi/local_transport_security.cc b/src/core/tsi/local_transport_security.cc index 0c748dac63845..c9c08313eddc9 100644 --- a/src/core/tsi/local_transport_security.cc +++ b/src/core/tsi/local_transport_security.cc @@ -58,8 +58,8 @@ tsi_result handshaker_result_extract_peer(const tsi_handshaker_result* /*self*/, return TSI_OK; } -tsi_result handshaker_result_extract_local_peer(const tsi_handshaker_result* /*self*/, - tsi_peer* /*peer*/) { +tsi_result handshaker_result_extract_local_peer( + const tsi_handshaker_result* /*self*/, tsi_peer* /*peer*/) { return TSI_OK; } diff --git a/src/core/tsi/ssl_transport_security.cc b/src/core/tsi/ssl_transport_security.cc index 96cf6010b088a..3d06aa863946b 100644 --- a/src/core/tsi/ssl_transport_security.cc +++ b/src/core/tsi/ssl_transport_security.cc @@ -22,6 +22,7 @@ #include #include + #include // TODO(jboeuf): refactor inet_ntop into a portability header. @@ -1262,7 +1263,7 @@ static tsi_result ssl_handshaker_result_extract_local_peer( unsigned int alpn_selected_len; const tsi_ssl_handshaker_result* impl = reinterpret_cast(self); - X509 *local_cert = SSL_get_certificate(impl->ssl); + X509* local_cert = SSL_get_certificate(impl->ssl); if (local_cert != nullptr) { result = peer_from_x509(local_cert, 1, local_peer); X509_free(local_cert); @@ -1446,14 +1447,14 @@ static tsi_result ssl_handshaker_get_result(tsi_ssl_handshaker* impl) { return impl->result; } -void print_cert_info(X509 *cert) { - BIO *bio = BIO_new_fp(stdout, BIO_NOCLOSE); - X509_NAME_print_ex(bio, X509_get_subject_name(cert), 0, XN_FLAG_ONELINE); - BIO_puts(bio, "\n"); - X509_NAME_print_ex(bio, X509_get_issuer_name(cert), 0, XN_FLAG_ONELINE); - BIO_puts(bio, "\n"); +void print_cert_info(X509* cert) { + BIO* bio = BIO_new_fp(stdout, BIO_NOCLOSE); + X509_NAME_print_ex(bio, X509_get_subject_name(cert), 0, XN_FLAG_ONELINE); + BIO_puts(bio, "\n"); + X509_NAME_print_ex(bio, X509_get_issuer_name(cert), 0, XN_FLAG_ONELINE); + BIO_puts(bio, "\n"); - BIO_free(bio); + BIO_free(bio); } static tsi_result ssl_handshaker_do_handshake(tsi_ssl_handshaker* impl, @@ -1467,9 +1468,9 @@ static tsi_result ssl_handshaker_do_handshake(tsi_ssl_handshaker* impl, int ssl_result = SSL_do_handshake(impl->ssl); ssl_result = SSL_get_error(impl->ssl, ssl_result); printf("***** Handshake successful p\n"); - X509 *server_cert = SSL_get_certificate(impl->ssl); + X509* server_cert = SSL_get_certificate(impl->ssl); if (server_cert) { - X509_print_fp(stderr, server_cert); + X509_print_fp(stderr, server_cert); } switch (ssl_result) { case SSL_ERROR_WANT_READ: diff --git a/src/core/tsi/transport_security.cc b/src/core/tsi/transport_security.cc index bb9cdf3a01932..ca94e32138d0b 100644 --- a/src/core/tsi/transport_security.cc +++ b/src/core/tsi/transport_security.cc @@ -263,8 +263,8 @@ tsi_result tsi_handshaker_result_extract_peer(const tsi_handshaker_result* self, return self->vtable->extract_peer(self, peer); } -tsi_result tsi_handshaker_result_extract_local_peer(const tsi_handshaker_result* self, - tsi_peer* local_peer) { +tsi_result tsi_handshaker_result_extract_local_peer( + const tsi_handshaker_result* self, tsi_peer* local_peer) { if (self == nullptr || self->vtable == nullptr || local_peer == nullptr) { return TSI_INVALID_ARGUMENT; } diff --git a/src/core/tsi/transport_security.h b/src/core/tsi/transport_security.h index eeb72335726b3..84175b557a9f3 100644 --- a/src/core/tsi/transport_security.h +++ b/src/core/tsi/transport_security.h @@ -100,7 +100,8 @@ struct tsi_handshaker { // struct tsi_handshaker_result_vtable { tsi_result (*extract_peer)(const tsi_handshaker_result* self, tsi_peer* peer); - tsi_result (*extract_local_peer)(const tsi_handshaker_result* self, tsi_peer* local_peer); + tsi_result (*extract_local_peer)(const tsi_handshaker_result* self, + tsi_peer* local_peer); tsi_result (*get_frame_protector_type)( const tsi_handshaker_result* self, tsi_frame_protector_type* frame_protector_type); diff --git a/src/core/tsi/transport_security_interface.h b/src/core/tsi/transport_security_interface.h index a251194bd19d6..5846cc9868726 100644 --- a/src/core/tsi/transport_security_interface.h +++ b/src/core/tsi/transport_security_interface.h @@ -258,11 +258,10 @@ typedef struct tsi_handshaker_result tsi_handshaker_result; tsi_result tsi_handshaker_result_extract_peer(const tsi_handshaker_result* self, tsi_peer* peer); -// This method extracts tsi local peer. It returns TSI_OK assuming there is no fatal -// error. -// The caller is responsible for destructing the local peer. -tsi_result tsi_handshaker_result_extract_local_peer(const tsi_handshaker_result* self, - tsi_peer* local_peer); +// This method extracts tsi local peer. It returns TSI_OK assuming there is no +// fatal error. The caller is responsible for destructing the local peer. +tsi_result tsi_handshaker_result_extract_local_peer( + const tsi_handshaker_result* self, tsi_peer* local_peer); // This method indicates what type of frame protector is provided by the // TSI implementation.