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