1 // 2 // 3 // Copyright 2017 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 #ifndef GRPC_TEST_CORE_TSI_TRANSPORT_SECURITY_TEST_LIB_H 20 #define GRPC_TEST_CORE_TSI_TRANSPORT_SECURITY_TEST_LIB_H 21 22 #include <grpc/support/sync.h> 23 #include <openssl/x509v3.h> 24 25 #include "src/core/tsi/transport_security_interface.h" 26 27 #define TSI_TEST_TINY_HANDSHAKE_BUFFER_SIZE 32 28 #define TSI_TEST_SMALL_HANDSHAKE_BUFFER_SIZE 128 29 #define TSI_TEST_SMALL_READ_BUFFER_ALLOCATED_SIZE 41 30 #define TSI_TEST_SMALL_PROTECTED_BUFFER_SIZE 37 31 #define TSI_TEST_SMALL_MESSAGE_BUFFER_ALLOCATED_SIZE 42 32 #define TSI_TEST_SMALL_CLIENT_MAX_OUTPUT_PROTECTED_FRAME_SIZE 39 33 #define TSI_TEST_SMALL_SERVER_MAX_OUTPUT_PROTECTED_FRAME_SIZE 43 34 #define TSI_TEST_DEFAULT_BUFFER_SIZE 4096 35 #define TSI_TEST_DEFAULT_PROTECTED_BUFFER_SIZE 16384 36 #define TSI_TEST_DEFAULT_CHANNEL_SIZE 32768 37 #define TSI_TEST_BIG_MESSAGE_SIZE 17000 38 #define TSI_TEST_SMALL_MESSAGE_SIZE 10 39 #define TSI_TEST_NUM_OF_ARGUMENTS 7 40 #define TSI_TEST_NUM_OF_COMBINATIONS 128 41 #define TSI_TEST_UNUSED_BYTES "HELLO GOOGLE" 42 43 // --- tsi_test_fixture object --- 44 // The tests for specific TSI implementations should create their own 45 // custom "subclass" of this fixture, which wraps all information 46 // that will be used to test correctness of TSI handshakes and frame 47 // protect/unprotect operations with respect to TSI implementations. 48 typedef struct tsi_test_fixture tsi_test_fixture; 49 50 // --- tsi_test_frame_protector_fixture object --- 51 // The object wraps all necessary information used to test correctness of TSI 52 // frame protector implementations. 53 typedef struct tsi_test_frame_protector_fixture 54 tsi_test_frame_protector_fixture; 55 56 // --- tsi_test_frame_protector_config object --- 57 // This object is used to configure different parameters of TSI frame protector 58 // APIs. 59 typedef struct tsi_test_frame_protector_config tsi_test_frame_protector_config; 60 61 // --- tsi_test_channel object --- 62 // This object represents simulated channels between the client and server 63 // from/to which they could read/write the exchanged information. 64 typedef struct tsi_test_channel tsi_test_channel; 65 66 // V-table for tsi_test_fixture operations that are implemented differently in 67 // different TSI implementations. 68 typedef struct tsi_test_fixture_vtable { 69 void (*setup_handshakers)(tsi_test_fixture* fixture); 70 void (*check_handshaker_peers)(tsi_test_fixture* fixture); 71 void (*destruct)(tsi_test_fixture* fixture); 72 } tsi_test_fixture_vtable; 73 74 struct tsi_test_fixture { 75 const tsi_test_fixture_vtable* vtable; 76 // client/server TSI handshaker used to perform TSI handshakes, and will get 77 // instantiated during the call to setup_handshakers. 78 tsi_handshaker* client_handshaker; 79 tsi_handshaker* server_handshaker; 80 // client/server TSI handshaker results used to store the result of TSI 81 // handshake. If the handshake fails, the result will store NULL upon 82 // finishing the handshake. 83 tsi_handshaker_result* client_result; 84 tsi_handshaker_result* server_result; 85 // size of buffer used to store data received from the peer. 86 size_t handshake_buffer_size; 87 // tsi_test_channel instance. 88 tsi_test_channel* channel; 89 // tsi_test_frame_protector_config instance 90 tsi_test_frame_protector_config* config; 91 // a flag indicating if client has finished TSI handshake first (i.e., before 92 // server). 93 // The flag should be referred if and only if TSI handshake finishes 94 // successfully. 95 bool has_client_finished_first; 96 // a flag indicating whether to test tsi_handshaker_result_get_unused_bytes() 97 // for TSI implementation. This field is true by default, and false 98 // for SSL TSI implementation due to grpc issue #12164 99 // (https://github.com/grpc/grpc/issues/12164). 100 // 101 bool test_unused_bytes; 102 // These objects will be used coordinate client/server handshakers with TSI 103 // thread to perform TSI handshakes in an asynchronous manner (for GTS TSI 104 // implementations). 105 // 106 gpr_cv cv; 107 gpr_mu mu; 108 bool notified; 109 }; 110 111 struct tsi_test_frame_protector_fixture { 112 // client/server TSI frame protectors whose ownership are transferred. 113 tsi_frame_protector* client_frame_protector; 114 tsi_frame_protector* server_frame_protector; 115 // tsi_test_channel instance. 116 tsi_test_channel* channel; 117 // tsi_test_frame_protector_config instance 118 tsi_test_frame_protector_config* config; 119 }; 120 121 struct tsi_test_channel { 122 // simulated channels between client and server. If the server (client) 123 // wants to send data to the client (server), he will write data to 124 // client_channel (server_channel), which will be read by client (server). 125 uint8_t* client_channel; 126 uint8_t* server_channel; 127 // size of data written to the client/server channel. 128 size_t bytes_written_to_client_channel; 129 size_t bytes_written_to_server_channel; 130 // size of data read from the client/server channel 131 size_t bytes_read_from_client_channel; 132 size_t bytes_read_from_server_channel; 133 }; 134 135 struct tsi_test_frame_protector_config { 136 // size of buffer used to store protected frames to be unprotected. 137 size_t read_buffer_allocated_size; 138 // size of buffer used to store bytes resulted from unprotect operations. 139 size_t message_buffer_allocated_size; 140 // size of buffer used to store frames resulted from protect operations. 141 size_t protected_buffer_size; 142 // size of client/server maximum frame size. 143 size_t client_max_output_protected_frame_size; 144 size_t server_max_output_protected_frame_size; 145 // pointer that points to client/server message to be protected. 146 uint8_t* client_message; 147 uint8_t* server_message; 148 // size of client/server message. 149 size_t client_message_size; 150 size_t server_message_size; 151 }; 152 153 // This method creates a tsi_test_frame_protector_config instance. Each 154 // parameter of this function is a boolean value indicating whether to set the 155 // corresponding parameter with a default value or not. If it's false, it will 156 // be set with a specific value which is usually much smaller than the default. 157 // Both values are defined with #define directive. 158 tsi_test_frame_protector_config* tsi_test_frame_protector_config_create( 159 bool use_default_read_buffer_allocated_size, 160 bool use_default_message_buffer_allocated_size, 161 bool use_default_protected_buffer_size, bool use_default_client_message, 162 bool use_default_server_message, 163 bool use_default_client_max_output_protected_frame_size, 164 bool use_default_server_max_output_protected_frame_size); 165 166 // This method sets different buffer and frame sizes of a 167 // tsi_test_frame_protector_config instance with user provided values. 168 void tsi_test_frame_protector_config_set_buffer_size( 169 tsi_test_frame_protector_config* config, size_t read_buffer_allocated_size, 170 size_t message_buffer_allocated_size, size_t protected_buffer_size, 171 size_t client_max_output_protected_frame_size, 172 size_t server_max_output_protected_frame_size); 173 174 // This method destroys a tsi_test_frame_protector_config instance. 175 void tsi_test_frame_protector_config_destroy( 176 tsi_test_frame_protector_config* config); 177 178 // This method initializes members of tsi_test_fixture instance. 179 // Note that the struct instance should be allocated before making 180 // this call. 181 void tsi_test_fixture_init(tsi_test_fixture* fixture); 182 183 // This method destroys a tsi_test_fixture instance. Note that the 184 // fixture instance must be dynamically allocated and will be freed by 185 // this function. 186 void tsi_test_fixture_destroy(tsi_test_fixture* fixture); 187 188 // This method creates a tsi_test_frame_protector_fixture instance. 189 tsi_test_frame_protector_fixture* tsi_test_frame_protector_fixture_create(); 190 191 // This method initializes members of tsi_test_frame_protector_fixture instance. 192 // Note that the struct instance should be allocated before making 193 // this call. 194 void tsi_test_frame_protector_fixture_init( 195 tsi_test_frame_protector_fixture* fixture, 196 tsi_frame_protector* client_frame_protector, 197 tsi_frame_protector* server_frame_protector); 198 199 // This method destroys a tsi_test_frame_protector_fixture instance. Note that 200 // the fixture instance must be dynamically allocated and will be freed by this 201 // function. 202 void tsi_test_frame_protector_fixture_destroy( 203 tsi_test_frame_protector_fixture* fixture); 204 205 // This method performs a protect operation on raw data and sends the result to 206 // peer. 207 void tsi_test_frame_protector_send_message_to_peer( 208 tsi_test_frame_protector_config* config, tsi_test_channel* channel, 209 tsi_frame_protector* protector, bool is_client); 210 211 // This method receives message from peer and unprotects it. 212 void tsi_test_frame_protector_receive_message_from_peer( 213 tsi_test_frame_protector_config* config, tsi_test_channel* channel, 214 tsi_frame_protector* protector, unsigned char* message, 215 size_t* bytes_received, bool is_client); 216 217 // This method performs a full TSI handshake between a client and a server. 218 // Note that the test library will implement the new TSI handshaker API to 219 // perform handshakes. 220 void tsi_test_do_handshake(tsi_test_fixture* fixture); 221 222 // This method performs a round trip test between the client and the server. 223 // That is, the client sends a protected message to a server who receives the 224 // message, and unprotects it. The same operation is triggered again with 225 // the client and server switching its role. 226 void tsi_test_do_round_trip(tsi_test_fixture* fixture); 227 228 // This method performs the above round trip test without doing handshakes. 229 void tsi_test_frame_protector_do_round_trip_no_handshake( 230 tsi_test_frame_protector_fixture* fixture); 231 232 struct SelfSignedCertificateOptions { 233 std::string common_name; 234 std::string organization; 235 std::string organizational_unit; 236 }; 237 238 // Returns a PEM-encoded self-signed certificate. 239 std::string GenerateSelfSignedCertificate( 240 const SelfSignedCertificateOptions& options); 241 242 // Returns the OpenSSL representation of a PEM cert. 243 X509* ReadPemCert(absl::string_view pem_cert); 244 245 // Returns the OpenSSL representation of a CRL. 246 X509_CRL* ReadCrl(absl::string_view crl_pem); 247 248 #endif // GRPC_TEST_CORE_TSI_TRANSPORT_SECURITY_TEST_LIB_H 249